Project import
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b1ee29e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,111 @@
+#
+#    Copyright (c) 2010-2011 Nest, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the make file for the Netscape Portable Runtime,
+#      (NSPR), providing a platform-neutral API for system level and
+#      libc like functions.
+#
+
+BuildConfigSpecialized	:= No
+BuildProductSpecialized	:= No
+
+include pre.mak
+
+PackageName		:= nspr
+
+PackageExtension	:= tar.gz
+PackageSeparator	:= -
+
+PackagePatchArgs	:= -p1
+
+PackageArchive		:= $(PackageName).$(PackageExtension)
+PackageSourceDir	:= $(PackageName)$(PackageSeparator)$(PackageVersion)
+
+PackageBuildMakefile	= $(call GenerateBuildPaths,Makefile)
+
+LicenseSourceFile	:= $(PackageSourceDir)/mozilla/nsprpub/pr/include/nspr.h
+
+CleanPaths		+= $(PackageLicenseFile)
+
+ifeq ($(BUILD_FEATURE_SIMULATOR), 1)
+	ENABLE_64BIT_NSPR = --enable-64bit
+endif
+
+all: $(PackageDefaultGoal)
+
+# Generate the package license contents.
+
+$(LicenseSourceFile): source
+
+$(PackageLicenseFile): $(LicenseSourceFile)
+	$(Verbose)$(SED) -n -e '/^\/\* \*\*\*\*\* BEGIN LICENSE BLOCK \*\*\*\*\*$$/,/\*\/$$/{;p;/\*\/$$/q;}' < $< > $@
+
+# Extract the source from the archive and apply patches, if any.
+
+$(PackageSourceDir): $(PackageArchive) $(PackagePatchPaths)
+	$(expand-and-patch-package)
+
+# Prepare the sources.
+
+.PHONY: source
+source: | $(PackageSourceDir)
+
+# Patch the sources, if necessary.
+
+.PHONY: patch
+patch: source
+
+# Generate the package build makefile.
+
+$(PackageBuildMakefile): | $(PackageSourceDir) $(BuildDirectory)
+	$(Verbose)cd $(BuildDirectory) && \
+	CC="$(CC)" CXX="$(CXX)" AR=$(AR) RANLIB=$(RANLIB) STRIP=$(STRIP) \
+	INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
+	$(CURDIR)/$(PackageSourceDir)/mozilla/nsprpub/configure \
+	--build=$(HostTuple) \
+	--target=$(TargetTuple) \
+	$(NsprPackageOptions) \
+	--prefix=/usr \
+	--sysconfdir=/etc \
+	--localstatedir=/var \
+	$(ENABLE_64BIT_NSPR) \
+	--disable-static
+
+# Configure the source for building.
+
+.PHONY: configure
+configure: source $(PackageBuildMakefile)
+
+# Build the source.
+#
+# We have to unset MAKEFLAGS since they confuse the package build otherwise.
+
+.PHONY: build
+build: configure
+	$(Verbose)unset MAKEFLAGS && \
+	$(MAKE) $(JOBSFLAG) -C $(BuildDirectory) all
+
+# Stage the build to a temporary installation area.
+#
+# We have to unset MAKEFLAGS since they confuse the package build otherwise.
+
+.PHONY: stage
+stage: build | $(ResultDirectory)
+	$(Verbose)unset MAKEFLAGS && \
+	$(MAKE) $(JOBSFLAG) -C $(BuildDirectory) DESTDIR=$(ResultDirectory) install
+
+clean:
+	$(Verbose)$(RM) $(RMFLAGS) -r $(PackageSourceDir)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory)
+
+include post.mak
diff --git a/nspr-4.8.6/mozilla/nsprpub/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/Makefile.in
new file mode 100644
index 0000000..c80d24a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/Makefile.in
@@ -0,0 +1,152 @@
+#! gmake
+
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+MOD_DEPTH	= .
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+MAKE := $(patsubst -j%,,$(MAKE)) -j1
+
+DIRS = config pr lib
+
+ifdef MOZILLA_CLIENT
+# Make nsinstall use absolute symlinks by default for Mozilla OSX builds
+# http://bugzilla.mozilla.org/show_bug.cgi?id=193164
+ifeq ($(OS_ARCH),Darwin)
+ifndef NSDISTMODE
+NSDISTMODE=absolute_symlink
+export NSDISTMODE
+endif
+endif
+endif
+
+DIST_GARBAGE = config.cache config.log config.status
+
+all:: config.status export
+
+include $(topsrcdir)/config/rules.mk
+
+config.status:: configure
+ifeq ($(OS_ARCH),WINNT)
+	sh $(srcdir)/configure --no-create --no-recursion
+else
+	./config.status --recheck && ./config.status
+endif
+
+#
+# The -ll option of zip converts CR LF to LF.
+#
+ifeq ($(OS_ARCH),WINNT)
+ZIP_ASCII_OPT = -ll
+endif
+
+# Delete config/autoconf.mk last because it is included by every makefile.
+distclean::
+	@echo "cd pr/tests; $(MAKE) $@"
+	@$(MAKE) -C pr/tests $@
+	rm -f config/autoconf.mk
+	rm -f `cat unallmakefiles` unallmakefiles
+
+release::
+	echo $(BUILD_NUMBER) > $(RELEASE_DIR)/$(BUILD_NUMBER)/version.df
+	@if test -f imports.df; then \
+	    echo "cp -f imports.df $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df"; \
+	    cp -f imports.df $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df; \
+	else \
+	    echo "echo > $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df"; \
+	    echo > $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df; \
+	fi
+	cd $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
+	rm -rf META-INF; mkdir META-INF; cd META-INF; \
+	echo "Manifest-Version: 1.0" > MANIFEST.MF; \
+	echo "" >> MANIFEST.MF; \
+	cd ..; rm -f mdbinary.jar; zip -r mdbinary.jar META-INF bin lib; \
+	rm -rf META-INF; \
+	cd include; \
+	rm -rf META-INF; mkdir META-INF; cd META-INF; \
+	echo "Manifest-Version: 1.0" > MANIFEST.MF; \
+	echo "" >> MANIFEST.MF; \
+	cd ..; rm -f mdheader.jar; zip $(ZIP_ASCII_OPT) -r mdheader.jar *; \
+	rm -rf META-INF
+ifeq ($(OS_ARCH),WINNT)
+	@if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); then \
+		rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+		echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)"; \
+		mkdir -p $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+	fi
+	@if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); then \
+		rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+		echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)"; \
+		mkdir -p $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+	fi
+else
+	@if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); then \
+		rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+		echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)"; \
+		$(NSINSTALL) -D $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+		chmod 775 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+	fi
+	@if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); then \
+		rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+		echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)"; \
+		$(NSINSTALL) -D $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+		chmod 775 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+	fi
+endif
+	cd $(RELEASE_DIR)/$(BUILD_NUMBER); \
+	cp -f version.df imports.df $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/version.df; \
+	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/imports.df; \
+	cd $(OBJDIR_NAME); \
+	cp -f mdbinary.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)/mdbinary.jar; \
+	cd include; \
+	cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)/mdheader.jar
+
+package:
+	@echo "cd pkg; $(MAKE) publish"
+	$(MAKE) -C pkg publish
+
+depend:
+	@echo "NSPR20 has no dependencies.  Skipped."
diff --git a/nspr-4.8.6/mozilla/nsprpub/admin/explode.pl b/nspr-4.8.6/mozilla/nsprpub/admin/explode.pl
new file mode 100644
index 0000000..881f21b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/admin/explode.pl
@@ -0,0 +1,75 @@
+#!/bin/perl
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# -----------------------------------------------------------------
+#
+# explode.pl -- Unpack .jar files into bin, lib, include directories
+#
+# syntax: perl explode.pl
+#
+# Description:
+# explode.pl unpacks the .jar files created by the NSPR build   
+# procedure. 
+#
+# Suggested use: After copying the platform directories to
+# /s/b/c/nspr20/<release>. CD to /s/b/c/nspr20/<release> and
+# run explode.pl. This will unpack the jar files into bin, lib,
+# include directories.
+#
+# -----------------------------------------------------------------
+
+@dirs = `ls -d *.OBJ*`;
+
+foreach $dir (@dirs) {
+    chop($dir);
+    if (-l $dir) {
+        print "Skipping symbolic link $dir\n";
+        next;
+    }
+    print "Unzipping $dir/mdbinary.jar\n";
+    system ("unzip", "-o", "$dir/mdbinary.jar",
+            "-d", "$dir");
+    system ("rm", "-rf", "$dir/META-INF");
+    mkdir "$dir/include", 0755;
+    print "Unzipping $dir/mdheader.jar\n";
+    system ("unzip", "-o", "-aa",
+            "$dir/mdheader.jar",
+            "-d", "$dir/include");
+    system ("rm", "-rf", "$dir/include/META-INF");
+}
+# --- end explode.pl ----------------------------------------------
diff --git a/nspr-4.8.6/mozilla/nsprpub/admin/makeTargetDirs.sh b/nspr-4.8.6/mozilla/nsprpub/admin/makeTargetDirs.sh
new file mode 100644
index 0000000..4250ce4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/admin/makeTargetDirs.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# -----------------------------------------------------------------
+# makeTargetDirs.sh -- Create target directories for building NSPR
+#
+# syntax: makeTargetDirs.sh
+#
+# Description:
+# makeTargetDirs.sh creates a set of directories intended for use
+# with NSPR's autoconf based build system.
+#     
+# The enumerated directories are the same as those built for NSPR
+# 4.1.1. Adjust as needed.
+#
+# -----------------------------------------------------------------
+
+mkdir  AIX4.3_64_DBG.OBJ
+mkdir  AIX4.3_64_OPT.OBJ
+mkdir  AIX4.3_DBG.OBJ
+mkdir  AIX4.3_OPT.OBJ
+mkdir  HP-UXB.11.00_64_DBG.OBJ
+mkdir  HP-UXB.11.00_64_OPT.OBJ
+mkdir  HP-UXB.11.00_DBG.OBJ
+mkdir  HP-UXB.11.00_OPT.OBJ
+mkdir  IRIX6.5_n32_PTH_DBG.OBJ
+mkdir  IRIX6.5_n32_PTH_OPT.OBJ
+mkdir  Linux2.2_x86_glibc_PTH_DBG.OBJ
+mkdir  Linux2.2_x86_glibc_PTH_OPT.OBJ
+mkdir  Linux2.4_x86_glibc_PTH_DBG.OBJ
+mkdir  Linux2.4_x86_glibc_PTH_OPT.OBJ
+mkdir  OSF1V4.0D_DBG.OBJ
+mkdir  OSF1V4.0D_OPT.OBJ
+mkdir  SunOS5.6_DBG.OBJ
+mkdir  SunOS5.6_OPT.OBJ
+mkdir  SunOS5.7_64_DBG.OBJ
+mkdir  SunOS5.7_64_OPT.OBJ
+mkdir  WIN954.0_DBG.OBJ
+mkdir  WIN954.0_DBG.OBJD
+mkdir  WIN954.0_OPT.OBJ
+mkdir  WINNT4.0_DBG.OBJ
+mkdir  WINNT4.0_DBG.OBJD
+mkdir  WINNT4.0_OPT.OBJ
+# --- end makeTargetDirs.sh ---------------------------------------
diff --git a/nspr-4.8.6/mozilla/nsprpub/admin/repackage.sh b/nspr-4.8.6/mozilla/nsprpub/admin/repackage.sh
new file mode 100755
index 0000000..4e85104
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/admin/repackage.sh
Binary files differ
diff --git a/nspr-4.8.6/mozilla/nsprpub/admin/symlinks.sh b/nspr-4.8.6/mozilla/nsprpub/admin/symlinks.sh
new file mode 100644
index 0000000..f90582e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/admin/symlinks.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# -----------------------------------------------------------------
+# symlinks.sh -- create links from NSPR builds
+#
+# syntax: symlinks.sh
+# 
+# Description:
+# symlinks.sh creates some symbolic links for NSPR build targets
+# that are not actually build, but for which there are NSPR
+# binaries suitable for running on the intended target. ... got
+# that?
+# 
+# Suggested use: After copying NSPR binaries to
+# /s/b/c/nspr20/<platform> run symlinks.sh to create the links
+# for all supported platforms.
+#
+# The symlinks in this script correspond to the NSPR 4.1.1
+# release. Adjust as necessary.
+#
+# -----------------------------------------------------------------
+
+ln -s SunOS5.6_DBG.OBJ SunOS5.7_DBG.OBJ
+ln -s SunOS5.6_OPT.OBJ SunOS5.7_OPT.OBJ
+
+ln -s SunOS5.6_DBG.OBJ SunOS5.8_DBG.OBJ
+ln -s SunOS5.6_OPT.OBJ SunOS5.8_OPT.OBJ
+
+ln -s SunOS5.7_64_DBG.OBJ SunOS5.8_64_DBG.OBJ
+ln -s SunOS5.7_64_OPT.OBJ SunOS5.8_64_OPT.OBJ
+
+ln -s OSF1V4.0D_DBG.OBJ OSF1V5.0_DBG.OBJ
+ln -s OSF1V4.0D_OPT.OBJ OSF1V5.0_OPT.OBJ
+
+ln -s WINNT4.0_DBG.OBJ WINNT5.0_DBG.OBJ
+ln -s WINNT4.0_DBG.OBJD WINNT5.0_DBG.OBJD
+ln -s WINNT4.0_OPT.OBJ WINNT5.0_OPT.OBJ
+# --- end symlinks.sh ---------------------------------------------
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/build/autoconf/config.guess b/nspr-4.8.6/mozilla/nsprpub/build/autoconf/config.guess
new file mode 100755
index 0000000..dfe628c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/build/autoconf/config.guess
@@ -0,0 +1,1471 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-10-13'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+#### MozillaHack 
+# Netscape's hacked uname
+    xx:WINNT:* | xx:WIN95:*)
+	echo i586-pc-msvc
+	exit ;;
+###  End MozillaHack
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/nspr-4.8.6/mozilla/nsprpub/build/autoconf/config.sub b/nspr-4.8.6/mozilla/nsprpub/build/autoconf/config.sub
new file mode 100755
index 0000000..7243829
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/build/autoconf/config.sub
@@ -0,0 +1,1702 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-12-04'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova* | wince-winmo*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+        -bluegene*)
+	        os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+        microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -winmo*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince-winmo*)
+		os=-wince-winmo
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/nspr-4.8.6/mozilla/nsprpub/build/autoconf/install-sh b/nspr-4.8.6/mozilla/nsprpub/build/autoconf/install-sh
new file mode 100755
index 0000000..0ff4b6a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/build/autoconf/install-sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:  no input file specified"
+	exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+	echo "install:  no destination specified"
+	exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+	dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/nspr-4.8.6/mozilla/nsprpub/build/cygwin-wrapper b/nspr-4.8.6/mozilla/nsprpub/build/cygwin-wrapper
new file mode 100755
index 0000000..679f0a1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/build/cygwin-wrapper
@@ -0,0 +1,75 @@
+#!/bin/sh
+#
+# Stupid wrapper to avoid win32 dospath/cygdrive issues
+# Try not to spawn programs from within this file. If the stuff in here looks royally 
+# confusing, see bug: http://bugzilla.mozilla.org/show_bug.cgi?id=206643
+# and look at the older versions of this file that are easier to read, but
+# do basically the same thing
+#
+
+prog=$1
+shift
+if test -z "$prog"; then
+    exit 0
+fi
+
+# If $CYGDRIVE_MOUNT was not set in configure, give $mountpoint the results of mount -p
+mountpoint=$CYGDRIVE_MOUNT
+if test -z "$mountpoint"; then
+    mountpoint=`mount -p`
+    if test -z "$mountpoint"; then
+       print "Cannot determine cygwin mount points. Exiting"
+       exit 1
+    fi
+fi
+
+# Delete everything but "/cygdrive" (or other mountpoint) from mount=`mount -p`
+mountpoint=${mountpoint#*/}
+mountpoint=/${mountpoint%%[!A-Za-z0-9_]*}
+mountpoint=${mountpoint%/}
+
+args=""
+up=""
+if test "${prog}" = "-up"; then
+    up=1
+    prog=${1}
+    shift
+fi
+
+process=1
+
+# Convert the mountpoint in parameters to Win32 filenames
+# For instance: /cygdrive/c/foo -> c:/foo
+for i in "${@}"
+do
+    if test "${i}" = "-wrap"; then
+        process=1
+    else
+        if test "${i}" = "-nowrap"; then
+            process=
+        else
+            if test -n "${process}"; then
+                if test -n "${up}"; then
+                    pathname=${i#-I[a-zA-Z]:/}
+                    if ! test "${pathname}" = "${i}"; then
+                        no_i=${i#-I}
+                        driveletter=${no_i%%:*}
+                        i=-I${mountpoint}/${driveletter}/${pathname}
+                    fi
+                else
+                    eval 'leader=${i%%'${mountpoint}'/[a-zA-Z]/*}'
+                    if ! test "${leader}" = "${i}"; then
+                        eval 'pathname=${i#'${leader}${mountpoint}'/[a-zA-Z]/}'
+                        eval 'no_mountpoint=${i#'${leader}${mountpoint}'/}'
+                        driveletter=${no_mountpoint%%/*}
+                        i=${leader}${driveletter}:/${pathname}
+                    fi
+                fi
+            fi
+
+            args="${args} ${i}"
+        fi
+    fi
+done
+
+exec $prog $args
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/config/Makefile.in
new file mode 100644
index 0000000..463deb2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/Makefile.in
@@ -0,0 +1,152 @@
+#! gmake
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+MOD_DEPTH	= ..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+# Indicate that this directory builds build tools.
+INTERNAL_TOOLS	= 1
+
+# For sanity's sake, we compile nsinstall without the wrapped system
+# headers, so that we can use it to set up the wrapped system headers.
+VISIBILITY_FLAGS =
+
+# autoconf.mk must be deleted last (from the top-level directory)
+# because it is included by every makefile.
+DIST_GARBAGE	= nsprincl.mk nsprincl.sh nspr-config
+
+RELEASE_BINS	= nspr-config
+
+include $(topsrcdir)/config/config.mk
+
+CSRCS	= now.c
+
+# This version hasn't been ported for us; the one in mozilla/config has
+ifneq ($(OS_ARCH),OS2)
+CSRCS  += nsinstall.c
+ 
+PLSRCS	= nfspwd.pl
+endif
+
+ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+# Temporary workaround to disable the generation of
+# library build time because now.c uses the 'long long'
+# data type that's not available on some platforms.
+ifeq (,$(filter-out NEC NEXTSTEP QNX SCOOS UNIXWARE,$(OS_ARCH)))
+DEFINES += -DOMIT_LIB_BUILD_TIME
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+    ifeq ($(basename $(OS_RELEASE)),6)
+        ifndef NS_USE_GCC
+            ifeq ($(USE_N32),1)
+                XLDOPTS += -n32 -Wl,-woff,85
+            else
+                ifeq ($(USE_64),1)
+                    XLDOPTS += -64
+                else
+                    XLDOPTS += -32
+                endif
+            endif
+        endif
+    endif
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+    ifeq ($(USE_64),1)
+        XLDOPTS += +DD64
+    endif
+endif
+
+ifeq ($(OS_ARCH), OS2)
+XCFLAGS = $(OS_CFLAGS)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+PROGS	= $(OBJDIR)/now$(PROG_SUFFIX)
+
+ifeq (,$(CROSS_COMPILE)$(filter-out OS2 WINNT,$(OS_ARCH)))
+TARGETS = $(PROGS)
+else
+ifeq (,$(filter-out SYMBIAN WINCE,$(OS_ARCH)))
+TARGETS = $(PROGS)
+else
+PROGS	+= $(OBJDIR)/nsinstall$(PROG_SUFFIX)
+TARGETS = $(PROGS) $(PLSRCS:.pl=)
+endif
+endif
+
+OUTOPTION = -o # end of the line
+ifeq (,$(filter-out WINNT WIN95 WINCE,$(OS_TARGET)))
+ifndef NS_USE_GCC
+OUTOPTION = -Fe
+endif
+endif
+
+# Redefine MAKE_OBJDIR for just this directory
+define MAKE_OBJDIR
+if test ! -d $(@D); then rm -rf $(@D); mkdir $(@D); else true; fi
+endef
+
+export:: $(TARGETS)
+	rm -f $(dist_bindir)/nspr-config
+
+ifdef WRAP_SYSTEM_INCLUDES
+export::
+	if test ! -d system_wrappers; then mkdir system_wrappers; fi
+	$(PERL) $(srcdir)/make-system-wrappers.pl system_wrappers < $(srcdir)/system-headers
+	$(INSTALL) system_wrappers $(dist_includedir)
+endif
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+	$(CC) $(XCFLAGS) $< $(LDFLAGS) $(XLDOPTS) $(OUTOPTION)$@
+
+install:: nspr.m4
+	$(NSINSTALL) -D $(DESTDIR)$(datadir)/aclocal
+	$(NSINSTALL) -t -m 0644 $< $(DESTDIR)$(datadir)/aclocal
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/autoconf.mk.in b/nspr-4.8.6/mozilla/nsprpub/config/autoconf.mk.in
new file mode 100644
index 0000000..3bb53b4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/autoconf.mk.in
@@ -0,0 +1,141 @@
+# -*- Mode: Makefile -*-
+
+INCLUDED_AUTOCONF_MK = 1
+USE_AUTOCONF	= 1
+@SHELL_OVERRIDE@
+MOZILLA_CLIENT	= @MOZILLA_CLIENT@
+
+prefix		= @prefix@
+exec_prefix	= @exec_prefix@
+bindir		= @bindir@
+includedir	= @includedir@
+libdir		= @libdir@
+datadir		= @datadir@
+
+dist_prefix	= @dist_prefix@
+dist_bindir	= @dist_bindir@
+dist_includedir = @dist_includedir@
+dist_libdir	= @dist_libdir@
+
+DIST		= $(dist_prefix)
+
+RELEASE_OBJDIR_NAME = @RELEASE_OBJDIR_NAME@
+OBJDIR_NAME	= @OBJDIR_NAME@
+OBJDIR		= @OBJDIR@
+OBJ_SUFFIX	= @OBJ_SUFFIX@
+LIB_SUFFIX	= @LIB_SUFFIX@
+DLL_SUFFIX	= @DLL_SUFFIX@
+ASM_SUFFIX	= @ASM_SUFFIX@
+MOD_NAME	= @NSPR_MODNAME@
+
+MOD_MAJOR_VERSION = @MOD_MAJOR_VERSION@
+MOD_MINOR_VERSION = @MOD_MINOR_VERSION@
+MOD_PATCH_VERSION = @MOD_PATCH_VERSION@
+
+LIBNSPR		= @LIBNSPR@
+LIBPLC		= @LIBPLC@
+
+CROSS_COMPILE	= @CROSS_COMPILE@
+MOZ_OPTIMIZE	= @MOZ_OPTIMIZE@
+MOZ_DEBUG	= @MOZ_DEBUG@
+MOZ_DEBUG_SYMBOLS = @MOZ_DEBUG_SYMBOLS@
+
+USE_CPLUS	= @USE_CPLUS@
+USE_IPV6	= @USE_IPV6@
+USE_N32		= @USE_N32@
+USE_64		= @USE_64@
+GC_LEAK_DETECTOR = @GC_LEAK_DETECTOR@
+ENABLE_STRIP	= @ENABLE_STRIP@
+
+USE_PTHREADS	= @USE_PTHREADS@
+USE_BTHREADS	= @USE_BTHREADS@
+PTHREADS_USER	= @USE_USER_PTHREADS@
+CLASSIC_NSPR	= @USE_NSPR_THREADS@
+
+AS		= @AS@
+ASFLAGS		= @ASFLAGS@
+CC		= @CC@
+CCC		= @CXX@
+NS_USE_GCC	= @GNU_CC@
+GCC_USE_GNU_LD	= @GCC_USE_GNU_LD@
+MSC_VER		= @MSC_VER@
+AR		= @AR@
+AR_FLAGS	= @AR_FLAGS@
+LD		= @LD@
+RANLIB		= @RANLIB@
+PERL		= @PERL@
+RC		= @RC@
+RCFLAGS		= @RCFLAGS@
+STRIP		= @STRIP@
+NSINSTALL	= @NSINSTALL@
+FILTER		= @FILTER@
+IMPLIB		= @IMPLIB@
+CYGWIN_WRAPPER	= @CYGWIN_WRAPPER@
+MT		= @MT@
+
+OS_CPPFLAGS	= @CPPFLAGS@
+OS_CFLAGS	= $(OS_CPPFLAGS) @CFLAGS@ $(DSO_CFLAGS)
+OS_CXXFLAGS	= $(OS_CPPFLAGS) @CXXFLAGS@ $(DSO_CFLAGS)
+OS_LIBS         = @OS_LIBS@
+OS_LDFLAGS	= @LDFLAGS@
+OS_DLLFLAGS	= @OS_DLLFLAGS@
+DLLFLAGS	= @DLLFLAGS@
+EXEFLAGS  = @EXEFLAGS@
+OPTIMIZER	= @OPTIMIZER@
+
+PROFILE_GEN_CFLAGS  = @PROFILE_GEN_CFLAGS@
+PROFILE_GEN_LDFLAGS = @PROFILE_GEN_LDFLAGS@
+PROFILE_USE_CFLAGS  = @PROFILE_USE_CFLAGS@
+PROFILE_USE_LDFLAGS = @PROFILE_USE_LDFLAGS@
+
+MKSHLIB		= @MKSHLIB@
+WRAP_MALLOC_LIB = @WRAP_MALLOC_LIB@
+WRAP_MALLOC_CFLAGS = @WRAP_MALLOC_CFLAGS@
+DSO_CFLAGS	= @DSO_CFLAGS@
+DSO_LDOPTS	= @DSO_LDOPTS@
+
+RESOLVE_LINK_SYMBOLS = @RESOLVE_LINK_SYMBOLS@
+
+HOST_CC		= @HOST_CC@
+HOST_CFLAGS	= @HOST_CFLAGS@
+HOST_LDFLAGS	= @HOST_LDFLAGS@
+
+DEFINES		= @DEFINES@ @DEFS@
+
+MDCPUCFG_H	= @MDCPUCFG_H@
+PR_MD_CSRCS	= @PR_MD_CSRCS@
+PR_MD_ASFILES	= @PR_MD_ASFILES@
+PR_MD_ARCH_DIR	= @PR_MD_ARCH_DIR@
+CPU_ARCH	= @CPU_ARCH@
+
+OS_TARGET	= @OS_TARGET@
+OS_ARCH		= @OS_ARCH@
+OS_RELEASE	= @OS_RELEASE@
+OS_TEST		= @OS_TEST@
+
+NOSUCHFILE	= @NOSUCHFILE@
+AIX_LINK_OPTS	= @AIX_LINK_OPTS@
+MOZ_OBJFORMAT	= @MOZ_OBJFORMAT@
+ULTRASPARC_LIBRARY = @ULTRASPARC_LIBRARY@
+
+OBJECT_MODE	= @OBJECT_MODE@
+ifdef OBJECT_MODE
+export OBJECT_MODE
+endif
+
+VISIBILITY_FLAGS = @VISIBILITY_FLAGS@
+WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCLUDES@
+
+MACOSX_DEPLOYMENT_TARGET = @MACOSX_DEPLOYMENT_TARGET@
+ifdef MACOSX_DEPLOYMENT_TARGET
+export MACOSX_DEPLOYMENT_TARGET
+endif
+
+MACOS_SDK_DIR	= @MACOS_SDK_DIR@
+
+SYMBIAN_SDK_DIR = @SYMBIAN_SDK_DIR@
+
+NEXT_ROOT	= @NEXT_ROOT@
+ifdef NEXT_ROOT
+export NEXT_ROOT
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/config.mk b/nspr-4.8.6/mozilla/nsprpub/config/config.mk
new file mode 100644
index 0000000..f47d8fe
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/config.mk
@@ -0,0 +1,175 @@
+#! gmake
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# Configuration information for building in the NSPR source module
+
+# Define an include-at-most-once-flag
+NSPR_CONFIG_MK	= 1
+
+#
+# The variable definitions in this file are inputs to NSPR's
+# build system.  This file, if present, is included at the
+# beginning of config.mk.
+#
+# For example:
+#
+# MOZ_OPTIMIZE=1
+# USE_PTHREADS=1
+# NS_USE_GCC=
+#
+ifndef topsrcdir
+topsrcdir=$(MOD_DEPTH)
+endif
+
+ifndef srcdir
+srcdir=.
+endif
+
+NFSPWD		= $(MOD_DEPTH)/config/nfspwd
+
+CFLAGS		= $(VISIBILITY_FLAGS) $(CC_ONLY_FLAGS) $(OPTIMIZER)\
+		  $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS)
+CCCFLAGS	= $(VISIBILITY_FLAGS) $(CCC_ONLY_FLAGS) $(OPTIMIZER)\
+		  $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS)
+# For purify
+NOMD_CFLAGS	= $(CC_ONLY_FLAGS) $(OPTIMIZER) $(NOMD_OS_CFLAGS)\
+		  $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS)
+NOMD_CCFLAGS	= $(CCC_ONLY_FLAGS) $(OPTIMIZER) $(NOMD_OS_CFLAGS)\
+		  $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS)
+
+LDFLAGS		= $(OS_LDFLAGS)
+
+# Enable profile-guided optimization
+ifdef MOZ_PROFILE_GENERATE
+CFLAGS += $(PROFILE_GEN_CFLAGS)
+LDFLAGS += $(PROFILE_GEN_LDFLAGS)
+endif # MOZ_PROFILE_GENERATE
+
+ifdef MOZ_PROFILE_USE
+CFLAGS += $(PROFILE_USE_CFLAGS)
+LDFLAGS += $(PROFILE_USE_LDFLAGS)
+endif # MOZ_PROFILE_USE
+
+define MAKE_OBJDIR
+if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi
+endef
+
+LINK_DLL	= $(LD) $(OS_DLLFLAGS) $(DLLFLAGS)
+
+ifeq ($(OS_ARCH),Darwin)
+PWD := $(shell pwd)
+endif
+
+ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2, $(OS_ARCH)))
+INSTALL		= $(NSINSTALL)
+else
+ifeq ($(NSDISTMODE),copy)
+# copy files, but preserve source mtime
+INSTALL		= $(NSINSTALL) -t
+else
+ifeq ($(NSDISTMODE),absolute_symlink)
+# install using absolute symbolic links
+ifeq ($(OS_ARCH),Darwin)
+INSTALL		= $(NSINSTALL) -L $(PWD)
+else
+INSTALL		= $(NSINSTALL) -L `$(NFSPWD)`
+endif
+else
+# install using relative symbolic links
+INSTALL		= $(NSINSTALL) -R
+endif
+endif
+endif # (WINNT || OS2) && !CROSS_COMPILE
+
+DEPENDENCIES	= $(OBJDIR)/.md
+
+ifdef BUILD_DEBUG_GC
+DEFINES		+= -DDEBUG_GC
+endif
+
+GARBAGE		+= $(DEPENDENCIES) core $(wildcard core.[0-9]*)
+
+DIST_GARBAGE += Makefile
+
+####################################################################
+#
+# The NSPR-specific configuration
+#
+####################################################################
+
+DEFINES += -DFORCE_PR_LOG
+
+ifeq ($(_PR_NO_CLOCK_TIMER),1)
+DEFINES += -D_PR_NO_CLOCK_TIMER
+endif
+
+ifeq ($(USE_PTHREADS), 1)
+DEFINES += -D_PR_PTHREADS -UHAVE_CVAR_BUILT_ON_SEM
+endif
+
+ifeq ($(PTHREADS_USER), 1)
+DEFINES += -DPTHREADS_USER -UHAVE_CVAR_BUILT_ON_SEM
+endif
+
+ifeq ($(USE_IPV6),1)
+DEFINES += -D_PR_INET6
+endif
+
+ifeq ($(MOZ_UNICODE),1)
+DEFINES += -DMOZ_UNICODE
+endif
+
+####################################################################
+#
+# Configuration for the release process
+#
+####################################################################
+
+MDIST = /m/dist
+ifeq ($(OS_ARCH),WINNT)
+MDIST = //helium/dist
+MDIST_DOS = $(subst /,\\,$(MDIST))
+endif
+
+# RELEASE_DIR is ns/dist/<module name>
+
+RELEASE_DIR = $(MOD_DEPTH)/dist/release/$(MOD_NAME)
+
+RELEASE_INCLUDE_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/include
+RELEASE_BIN_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/bin
+RELEASE_LIB_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/lib
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/gcc_hidden.h b/nspr-4.8.6/mozilla/nsprpub/config/gcc_hidden.h
new file mode 100644
index 0000000..58140c1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/gcc_hidden.h
@@ -0,0 +1,2 @@
+/* Begin all files as hidden visibility */
+#pragma GCC visibility push(hidden)
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/libc_r.h b/nspr-4.8.6/mozilla/nsprpub/config/libc_r.h
new file mode 100644
index 0000000..0f66d12
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/libc_r.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* libc_r.h  --  macros, defines, etc. to make using reentrant libc calls */
+/*               a bit easier.  This was initially done for AIX pthreads, */
+/*               but should be usable for anyone...                       */
+
+/* Most of these use locally defined space instead of static library space. */
+/* Because of this, we use the _INIT_R to declare/allocate space (stack),   */
+/* and the plain routines to actually do it..._WARNING_: avoid allocating   */
+/* memory wherever possible.  Memory allocation is fairly expensive, at     */
+/* least on AIX...use arrays instead (which allocate from the stack.)       */
+/* I know the names are a bit strange, but I wanted to be fairly certain    */
+/* that we didn't have any namespace corruption...in general, the inits are */
+/* R_<name>_INIT_R(), and the actual calls are R_<name>_R().                */
+
+#ifndef _LIBC_R_H
+#define _LIBC_R_H
+
+/************/
+/*  strtok  */
+/************/
+#define R_STRTOK_INIT_R() \
+    char *r_strtok_r=NULL
+
+#define R_STRTOK_R(return,source,delim) \     
+    return=strtok_r(source,delim,&r_strtok_r)
+
+#define R_STRTOK_NORET_R(source,delim) \
+    strtok_r(source,delim,&r_strtok_r)
+
+/**************/
+/*  strerror  */
+/**************/
+#define R_MAX_STRERROR_LEN_R 8192     /* Straight from limits.h */
+
+#define R_STRERROR_INIT_R() \
+    char r_strerror_r[R_MAX_STRERROR_LEN_R]
+
+#define R_STRERROR_R(val) \
+    strerror_r(val,r_strerror_r,R_MAX_STRERROR_LEN_R)
+
+/*****************/
+/*  time things  */
+/*****************/
+#define R_ASCTIME_INIT_R() \
+    char r_asctime_r[26]
+
+#define R_ASCTIME_R(val) \
+    asctime_r(val,r_asctime_r)
+
+#define R_CTIME_INIT_R() \
+    char r_ctime_r[26]
+
+#define R_CTIME_R(val) \
+    ctime_r(val,r_ctime_r)
+
+#define R_GMTIME_INIT_R() \
+    struct tm r_gmtime_r
+
+#define R_GMTIME_R(time) \
+    gmtime_r(time,&r_gmtime_r)
+
+#define R_LOCALTIME_INIT_R() \
+   struct tm r_localtime_r
+
+#define R_LOCALTIME_R(val) \
+   localtime_r(val,&r_localtime_r)
+    
+/***********/
+/*  crypt  */
+/***********/
+#include <crypt.h>
+#define R_CRYPT_INIT_R() \
+    CRYPTD r_cryptd_r; \
+    bzero(&r_cryptd_r,sizeof(CRYPTD)) 
+
+#define R_CRYPT_R(pass,salt) \
+    crypt_r(pass,salt,&r_cryptd_r)
+
+/**************/
+/*  pw stuff  */
+/**************/
+#define R_MAX_PW_LEN_R 1024
+/* The following must be after the last declaration, but */
+/* before the first bit of code...                       */
+#define R_GETPWNAM_INIT_R(pw_ptr) \
+    struct passwd r_getpwnam_pw_r; \
+    char r_getpwnam_line_r[R_MAX_PW_LEN_R]; \
+    pw_ptr = &r_getpwnam_pw_r
+
+#define R_GETPWNAM_R(name) \
+    getpwnam_r(name,&r_getpwnam_pw_r,r_getpwnam_line_r,R_MAX_PW_LEN_R)
+
+/*******************/
+/*  gethost stuff  */
+/*******************/
+#define R_GETHOSTBYADDR_INIT_R() \
+    struct hostent r_gethostbyaddr_r; \
+    struct hostent_data r_gethostbyaddr_data_r
+
+#define R_GETHOSTBYADDR_R(addr,len,type,xptr_ent) \
+    bzero(&r_gethostbyaddr_r,sizeof(struct hostent)); \
+    bzero(&r_gethostbyaddr_data_r,sizeof(struct hostent_data)); \
+    xptr_ent = &r_gethostbyaddr_r; \
+    if (gethostbyaddr_r(addr,len,type, \
+       &r_gethostbyaddr_r,&r_gethostbyaddr_data_r) == -1) { \
+           xptr_ent = NULL; \
+    }
+
+#define R_GETHOSTBYNAME_INIT_R() \
+    struct hostent r_gethostbyname_r; \
+    struct hostent_data r_gethostbyname_data_r
+
+#define R_GETHOSTBYNAME_R(name,xptr_ent) \
+    bzero(&r_gethostbyname_r,sizeof(struct hostent)); \
+    bzero(&r_gethostbyname_data_r,sizeof(struct hostent_data)); \
+    xptr_ent = &r_gethostbyname_r; \
+    if (gethostbyname_r(name, \
+       &r_gethostbyname_r,&r_gethostbyname_data_r) == -1) { \
+          xptr_ent = NULL; \
+    }
+
+#endif /* _LIBC_R_H */
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/make-system-wrappers.pl b/nspr-4.8.6/mozilla/nsprpub/config/make-system-wrappers.pl
new file mode 100644
index 0000000..31c9af4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/make-system-wrappers.pl
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# IBM Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2004
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Brian Ryner <bryner@brianryner.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+$output_dir = shift;
+
+while (<STDIN>) {
+    chomp;
+    if (-e "$output_dir/$_") {
+	next;
+    }
+
+    if (/(.*)\/[^\/*]/) {
+	mkdir "$output_dir/$1";
+    }
+
+    open OUT, ">$output_dir/$_";
+    print OUT "#pragma GCC system_header\n";  # suppress include_next warning
+    print OUT "#pragma GCC visibility push(default)\n";
+    print OUT "#include_next \<$_\>\n";
+    print OUT "#pragma GCC visibility pop\n";
+    close OUT;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/nfspwd.pl b/nspr-4.8.6/mozilla/nsprpub/config/nfspwd.pl
new file mode 100644
index 0000000..947b822
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/nfspwd.pl
@@ -0,0 +1,50 @@
+#! perl
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+require "fastcwd.pl";
+
+$_ = &fastcwd;
+if (m@^/[uh]/@o || s@^/tmp_mnt/@/@o) {
+    print("$_\n");
+} elsif ((($user, $rest) = m@^/usr/people/(\w+)/(.*)@o)
+      && readlink("/u/$user") eq "/usr/people/$user") {
+    print("/u/$user/$rest\n");
+} else {
+    chop($host = `hostname`);
+    print("/h/$host$_\n");
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/now.c b/nspr-4.8.6/mozilla/nsprpub/config/now.c
new file mode 100644
index 0000000..3af5f44
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/now.c
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+#include <sys/time.h>
+#elif defined(_WIN32)
+#include <windows.h>
+#else
+#error "Architecture not supported"
+#endif
+
+
+int main(int argc, char **argv)
+{
+#if defined(OMIT_LIB_BUILD_TIME)
+    /*
+     * Some platforms don't have any 64-bit integer type
+     * such as 'long long'.  Because we can't use NSPR's
+     * PR_snprintf in this program, it is difficult to
+     * print a static initializer for PRInt64 (a struct).
+     * So we print nothing.  The makefiles that build the
+     * shared libraries will detect the empty output string
+     * of this program and omit the library build time
+     * in PRVersionDescription.
+     */
+#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+    long long now;
+    struct timeval tv;
+#ifdef HAVE_SVID_GETTOD
+    gettimeofday(&tv);
+#else
+    gettimeofday(&tv, NULL);
+#endif
+    now = ((1000000LL) * tv.tv_sec) + (long long)tv.tv_usec;
+#if defined(OSF1)
+    fprintf(stdout, "%ld", now);
+#elif defined(BEOS) && defined(__POWERPC__)
+    fprintf(stdout, "%Ld", now);  /* Metroworks on BeOS PPC */
+#else
+    fprintf(stdout, "%lld", now);
+#endif
+
+#elif defined(_WIN32)
+    __int64 now;
+    FILETIME ft;
+    GetSystemTimeAsFileTime(&ft);
+    CopyMemory(&now, &ft, sizeof(now));
+    /*
+     * 116444736000000000 is the number of 100-nanosecond intervals
+     * between Jan. 1, 1601 and Jan. 1, 1970.
+     */
+#ifdef __GNUC__
+    now = (now - 116444736000000000LL) / 10LL;
+    fprintf(stdout, "%lld", now);
+#else
+    now = (now - 116444736000000000i64) / 10i64;
+    fprintf(stdout, "%I64d", now);
+#endif
+
+#else
+#error "Architecture not supported"
+#endif
+
+    return 0;
+}  /* main */
+
+/* now.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/nsinstall.c b/nspr-4.8.6/mozilla/nsprpub/config/nsinstall.c
new file mode 100644
index 0000000..f18e116
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/nsinstall.c
@@ -0,0 +1,586 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Netscape portable install command.
+**
+** Brendan Eich, 7/20/95
+*/
+#include <stdio.h>  /* OSF/1 requires this before grp.h, so put it first */
+#include <assert.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <utime.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdarg.h>
+#ifdef USE_REENTRANT_LIBC
+#include "libc_r.h"
+#endif /* USE_REENTRANT_LIBC */
+
+#include "pathsub.h"
+
+#define HAVE_FCHMOD
+
+#if defined(BEOS)
+#undef HAVE_FCHMOD
+#endif
+
+/*
+ * Does getcwd() take NULL as the first argument and malloc
+ * the result buffer?
+ */
+#if !defined(DARWIN) && !defined(NEXTSTEP)
+#define GETCWD_CAN_MALLOC
+#endif
+
+#ifdef NEXTSTEP
+#include <bsd/libc.h>
+
+/*
+** balazs.pataki@sztaki.hu: The getcwd is broken in NEXTSTEP (returns 0),
+** when called on a mounted fs. Did anyone notice this? Here's an ugly
+** workaround ...
+*/
+#define getcwd(b,s)   my_getcwd(b,s)
+
+static char *
+my_getcwd (char *buf, size_t size)
+{
+    FILE *pwd = popen("pwd", "r");
+    char *result = fgets(buf, size, pwd);
+
+    if (result) {
+        buf[strlen(buf)-1] = '\0';
+    }
+    pclose (pwd);
+    return buf;
+}
+#endif /* NEXTSTEP */
+
+#if defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) 
+#include <getopt.h>
+#endif
+
+#if defined(SCO) || defined(UNIXWARE) || defined(SNI) || defined(NCR) || defined(NEC) || defined(NEXTSTEP)
+#if !defined(S_ISLNK) && defined(S_IFLNK)
+#define S_ISLNK(a)	(((a) & S_IFMT) == S_IFLNK)
+#endif
+#endif
+
+#if defined(SNI)
+extern int fchmod(int fildes, mode_t mode);
+#endif
+
+#ifdef QNX
+#define d_ino d_stat.st_ino
+#endif
+
+static void
+usage(void)
+{
+    fprintf(stderr,
+	"usage: %s [-C cwd] [-L linkprefix] [-m mode] [-o owner] [-g group]\n"
+	"       %*s [-DdltR] file [file ...] directory\n",
+	program, (int)strlen(program), "");
+    exit(2);
+}
+
+static int
+mkdirs(char *path, mode_t mode)
+{
+    char *cp;
+    struct stat sb;
+    int res;
+    
+    while (*path == '/' && path[1] == '/')
+	path++;
+    for (cp = strrchr(path, '/'); cp && cp != path && cp[-1] == '/'; cp--)
+	;
+    if (cp && cp != path) {
+	*cp = '\0';
+	if ((stat(path, &sb) < 0 || !S_ISDIR(sb.st_mode)) &&
+	    mkdirs(path, mode) < 0) {
+	    return -1;
+	}
+	*cp = '/';
+    }
+    res = mkdir(path, mode);
+    if ((res != 0) && (errno == EEXIST))
+	return 0;
+     else
+	return res;
+}
+
+static uid_t
+touid(char *owner)
+{
+    struct passwd *pw;
+    uid_t uid;
+    char *cp;
+
+    pw = getpwnam(owner);
+    if (pw)
+	return pw->pw_uid;
+    uid = strtol(owner, &cp, 0);
+    if (uid == 0 && cp == owner)
+	fail("cannot find uid for %s", owner);
+    return uid;
+}
+
+static gid_t
+togid(char *group)
+{
+    struct group *gr;
+    gid_t gid;
+    char *cp;
+
+    gr = getgrnam(group);
+    if (gr)
+	return gr->gr_gid;
+    gid = strtol(group, &cp, 0);
+    if (gid == 0 && cp == group)
+	fail("cannot find gid for %s", group);
+    return gid;
+}
+
+int
+main(int argc, char **argv)
+{
+    int onlydir, dodir, dolink, dorelsymlink, dotimes, opt, len, lplen, tdlen, bnlen, exists, fromfd, tofd, cc, wc;
+    mode_t mode = 0755;
+    char *linkprefix, *owner, *group, *cp, *cwd, *todir, *toname, *name, *base, *linkname, *bp, buf[BUFSIZ];
+    uid_t uid;
+    gid_t gid;
+    struct stat sb, tosb;
+    struct utimbuf utb;
+
+    program = argv[0];
+    cwd = linkname = linkprefix = owner = group = 0;
+    onlydir = dodir = dolink = dorelsymlink = dotimes = lplen = 0;
+
+    while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) {
+	switch (opt) {
+	  case 'C':
+	    cwd = optarg;
+	    break;
+	  case 'D':
+	    onlydir = 1;
+	    break;
+	  case 'd':
+	    dodir = 1;
+	    break;
+	  case 'l':
+	    dolink = 1;
+	    break;
+	  case 'L':
+	    linkprefix = optarg;
+	    lplen = strlen(linkprefix);
+	    dolink = 1;
+	    break;
+	  case 'R':
+	    dolink = dorelsymlink = 1;
+	    break;
+	  case 'm':
+	    mode = strtoul(optarg, &cp, 8);
+	    if (mode == 0 && cp == optarg)
+		usage();
+	    break;
+	  case 'o':
+	    owner = optarg;
+	    break;
+	  case 'g':
+	    group = optarg;
+	    break;
+	  case 't':
+	    dotimes = 1;
+	    break;
+	  default:
+	    usage();
+	}
+    }
+
+    argc -= optind;
+    argv += optind;
+    if (argc < 2 - onlydir)
+	usage();
+
+    todir = argv[argc-1];
+    if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) &&
+	mkdirs(todir, 0777) < 0) {
+	fail("cannot make directory %s", todir);
+    }
+    if (onlydir)
+	return 0;
+
+    if (!cwd) {
+#ifdef GETCWD_CAN_MALLOC
+	cwd = getcwd(0, PATH_MAX);
+#else
+	cwd = malloc(PATH_MAX + 1);
+	cwd = getcwd(cwd, PATH_MAX);
+#endif
+    }
+    xchdir(todir);
+#ifdef GETCWD_CAN_MALLOC
+    todir = getcwd(0, PATH_MAX);
+#else
+    todir = malloc(PATH_MAX + 1);
+    todir = getcwd(todir, PATH_MAX);
+#endif
+    tdlen = strlen(todir);
+    xchdir(cwd);
+    tdlen = strlen(todir);
+
+    uid = owner ? touid(owner) : -1;
+    gid = group ? togid(group) : -1;
+
+    while (--argc > 0) {
+	name = *argv++;
+	len = strlen(name);
+	base = xbasename(name);
+	bnlen = strlen(base);
+	toname = (char*)xmalloc(tdlen + 1 + bnlen + 1);
+	sprintf(toname, "%s/%s", todir, base);
+	exists = (lstat(toname, &tosb) == 0);
+
+	if (dodir) {
+	    /* -d means create a directory, always */
+	    if (exists && !S_ISDIR(tosb.st_mode)) {
+		(void) unlink(toname);
+		exists = 0;
+	    }
+	    if (!exists && mkdir(toname, mode) < 0)
+		fail("cannot make directory %s", toname);
+	    if ((owner || group) && chown(toname, uid, gid) < 0)
+		fail("cannot change owner of %s", toname);
+	} else if (dolink) {
+	    if (*name == '/') {
+		/* source is absolute pathname, link to it directly */
+		linkname = 0;
+	    } else {
+		if (linkprefix) {
+		    /* -L implies -l and prefixes names with a $cwd arg. */
+		    len += lplen + 1;
+		    linkname = (char*)xmalloc(len + 1);
+		    sprintf(linkname, "%s/%s", linkprefix, name);
+		} else if (dorelsymlink) {
+		    /* Symlink the relative path from todir to source name. */
+		    linkname = (char*)xmalloc(PATH_MAX);
+
+		    if (*todir == '/') {
+			/* todir is absolute: skip over common prefix. */
+			lplen = relatepaths(todir, cwd, linkname);
+			strcpy(linkname + lplen, name);
+		    } else {
+			/* todir is named by a relative path: reverse it. */
+			reversepath(todir, name, len, linkname);
+			xchdir(cwd);
+		    }
+
+		    len = strlen(linkname);
+		}
+		name = linkname;
+	    }
+
+	    /* Check for a pre-existing symlink with identical content. */
+	    if (exists &&
+		(!S_ISLNK(tosb.st_mode) ||
+		 readlink(toname, buf, sizeof buf) != len ||
+		 strncmp(buf, name, len) != 0)) {
+		(void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
+		exists = 0;
+	    }
+	    if (!exists && symlink(name, toname) < 0)
+		fail("cannot make symbolic link %s", toname);
+#ifdef HAVE_LCHOWN
+	    if ((owner || group) && lchown(toname, uid, gid) < 0)
+		fail("cannot change owner of %s", toname);
+#endif
+
+	    if (linkname) {
+		free(linkname);
+		linkname = 0;
+	    }
+	} else {
+	    /* Copy from name to toname, which might be the same file. */
+	    fromfd = open(name, O_RDONLY);
+	    if (fromfd < 0 || fstat(fromfd, &sb) < 0)
+		fail("cannot access %s", name);
+	    if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0))
+		(void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
+	    tofd = open(toname, O_CREAT | O_WRONLY, 0666);
+	    if (tofd < 0)
+		fail("cannot create %s", toname);
+
+	    bp = buf;
+	    while ((cc = read(fromfd, bp, sizeof buf)) > 0) {
+		while ((wc = write(tofd, bp, cc)) > 0) {
+		    if ((cc -= wc) == 0)
+			break;
+		    bp += wc;
+		}
+		if (wc < 0)
+		    fail("cannot write to %s", toname);
+	    }
+	    if (cc < 0)
+		fail("cannot read from %s", name);
+
+	    if (ftruncate(tofd, sb.st_size) < 0)
+		fail("cannot truncate %s", toname);
+	    if (dotimes) {
+		utb.actime = sb.st_atime;
+		utb.modtime = sb.st_mtime;
+		if (utime(toname, &utb) < 0)
+		    fail("cannot set times of %s", toname);
+	    }
+#ifdef HAVE_FCHMOD
+	    if (fchmod(tofd, mode) < 0)
+#else
+	    if (chmod(toname, mode) < 0)
+#endif
+		fail("cannot change mode of %s", toname);
+	    if ((owner || group) && fchown(tofd, uid, gid) < 0)
+		fail("cannot change owner of %s", toname);
+
+	    /* Must check for delayed (NFS) write errors on close. */
+	    if (close(tofd) < 0)
+		fail("cannot write to %s", toname);
+	    close(fromfd);
+	}
+
+	free(toname);
+    }
+
+    free(cwd);
+    free(todir);
+    return 0;
+}
+
+/*
+** Pathname subroutines.
+**
+** Brendan Eich, 8/29/95
+*/
+
+char *program;
+
+void
+fail(char *format, ...)
+{
+    int error;
+    va_list ap;
+
+#ifdef USE_REENTRANT_LIBC
+    R_STRERROR_INIT_R();
+#endif
+
+    error = errno;
+    fprintf(stderr, "%s: ", program);
+    va_start(ap, format);
+    vfprintf(stderr, format, ap);
+    va_end(ap);
+    if (error)
+
+#ifdef USE_REENTRANT_LIBC
+    R_STRERROR_R(errno);
+	fprintf(stderr, ": %s", r_strerror_r);
+#else
+	fprintf(stderr, ": %s", strerror(errno));
+#endif
+
+    putc('\n', stderr);
+    exit(1);
+}
+
+char *
+getcomponent(char *path, char *name)
+{
+    if (*path == '\0')
+	return 0;
+    if (*path == '/') {
+	*name++ = '/';
+    } else {
+	do {
+	    *name++ = *path++;
+	} while (*path != '/' && *path != '\0');
+    }
+    *name = '\0';
+    while (*path == '/')
+	path++;
+    return path;
+}
+
+#ifdef UNIXWARE_READDIR_BUFFER_TOO_SMALL
+/* Sigh.  The static buffer in Unixware's readdir is too small. */
+struct dirent * readdir(DIR *d)
+{
+        static struct dirent *buf = NULL;
+#define MAX_PATH_LEN 1024
+
+
+        if(buf == NULL)
+                buf = (struct dirent *) malloc(sizeof(struct dirent) + MAX_PATH_LEN)
+;
+        return(readdir_r(d, buf));
+}
+#endif
+
+char *
+ino2name(ino_t ino, char *dir)
+{
+    DIR *dp;
+    struct dirent *ep;
+    char *name;
+
+    dp = opendir("..");
+    if (!dp)
+	fail("cannot read parent directory");
+    for (;;) {
+	if (!(ep = readdir(dp)))
+	    fail("cannot find current directory");
+	if (ep->d_ino == ino)
+	    break;
+    }
+    name = xstrdup(ep->d_name);
+    closedir(dp);
+    return name;
+}
+
+void *
+xmalloc(size_t size)
+{
+    void *p = malloc(size);
+    if (!p)
+	fail("cannot allocate %u bytes", size);
+    return p;
+}
+
+char *
+xstrdup(char *s)
+{
+    return strcpy((char*)xmalloc(strlen(s) + 1), s);
+}
+
+char *
+xbasename(char *path)
+{
+    char *cp;
+
+    while ((cp = strrchr(path, '/')) && cp[1] == '\0')
+	*cp = '\0';
+    if (!cp) return path;
+    return cp + 1;
+}
+
+void
+xchdir(char *dir)
+{
+    if (chdir(dir) < 0)
+	fail("cannot change directory to %s", dir);
+}
+
+int
+relatepaths(char *from, char *to, char *outpath)
+{
+    char *cp, *cp2;
+    int len;
+    char buf[NAME_MAX];
+
+    assert(*from == '/' && *to == '/');
+    for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++)
+	if (*cp == '\0')
+	    break;
+    while (cp[-1] != '/')
+	cp--, cp2--;
+    if (cp - 1 == to) {
+	/* closest common ancestor is /, so use full pathname */
+	len = strlen(strcpy(outpath, to));
+	if (outpath[len] != '/') {
+	    outpath[len++] = '/';
+	    outpath[len] = '\0';
+	}
+    } else {
+	len = 0;
+	while ((cp2 = getcomponent(cp2, buf)) != 0) {
+	    strcpy(outpath + len, "../");
+	    len += 3;
+	}
+	while ((cp = getcomponent(cp, buf)) != 0) {
+	    sprintf(outpath + len, "%s/", buf);
+	    len += strlen(outpath + len);
+	}
+    }
+    return len;
+}
+
+void
+reversepath(char *inpath, char *name, int len, char *outpath)
+{
+    char *cp, *cp2;
+    char buf[NAME_MAX];
+    struct stat sb;
+
+    cp = strcpy(outpath + PATH_MAX - (len + 1), name);
+    cp2 = inpath;
+    while ((cp2 = getcomponent(cp2, buf)) != 0) {
+	if (strcmp(buf, ".") == 0)
+	    continue;
+	if (strcmp(buf, "..") == 0) {
+	    if (stat(".", &sb) < 0)
+		fail("cannot stat current directory");
+	    name = ino2name(sb.st_ino, "..");
+	    len = strlen(name);
+	    cp -= len + 1;
+	    strcpy(cp, name);
+	    cp[len] = '/';
+	    free(name);
+	    xchdir("..");
+	} else {
+	    cp -= 3;
+	    strncpy(cp, "../", 3);
+	    xchdir(buf);
+	}
+    }
+    strcpy(outpath, cp);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/nspr-config.in b/nspr-4.8.6/mozilla/nsprpub/config/nspr-config.in
new file mode 100755
index 0000000..a7d2b4f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/nspr-config.in
@@ -0,0 +1,143 @@
+#!/bin/sh
+
+prefix=@prefix@
+
+major_version=@MOD_MAJOR_VERSION@
+minor_version=@MOD_MINOR_VERSION@
+patch_version=@MOD_PATCH_VERSION@
+
+usage()
+{
+	cat <<EOF
+Usage: nspr-config [OPTIONS] [LIBRARIES]
+Options:
+	[--prefix[=DIR]]
+	[--exec-prefix[=DIR]]
+	[--includedir[=DIR]]
+	[--libdir[=DIR]]
+	[--version]
+	[--libs]
+	[--cflags]
+Libraries:
+	nspr
+	plc
+	plds
+EOF
+	exit $1
+}
+
+if test $# -eq 0; then
+	usage 1 1>&2
+fi
+
+lib_nspr=yes
+lib_plc=yes
+lib_plds=yes
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      ;;
+    --prefix)
+      echo_prefix=yes
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      ;;
+    --exec-prefix)
+      echo_exec_prefix=yes
+      ;;
+    --includedir=*)
+      includedir=$optarg
+      ;;
+    --includedir)
+      echo_includedir=yes
+      ;;
+    --libdir=*)
+      libdir=$optarg
+      ;;
+    --libdir)
+      echo_libdir=yes
+      ;;
+    --version)
+      echo ${major_version}.${minor_version}.${patch_version}
+      ;;
+    --cflags)
+      echo_cflags=yes
+      ;;
+    --libs)
+      echo_libs=yes
+      ;;
+    nspr)
+      lib_nspr=yes
+      ;;
+    plc)
+      lib_plc=yes
+      ;;
+    plds)
+      lib_plds=yes
+      ;;
+    *)
+      usage 1 1>&2
+      ;;
+  esac
+  shift
+done
+
+# Set variables that may be dependent upon other variables
+if test -z "$exec_prefix"; then
+    exec_prefix=@exec_prefix@
+fi
+if test -z "$includedir"; then
+    includedir=@includedir@
+fi
+if test -z "$libdir"; then
+    libdir=@libdir@
+fi
+
+if test "$echo_prefix" = "yes"; then
+    echo $prefix
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+    echo $exec_prefix
+fi
+
+if test "$echo_includedir" = "yes"; then
+    echo $includedir
+fi
+
+if test "$echo_libdir" = "yes"; then
+    echo $libdir
+fi
+
+if test "$echo_cflags" = "yes"; then
+    echo -I$includedir
+fi
+
+if test "$echo_libs" = "yes"; then
+      libdirs=-L$libdir
+      if test -n "$lib_plds"; then
+	libdirs="$libdirs -lplds${major_version}"
+      fi
+      if test -n "$lib_plc"; then
+	libdirs="$libdirs -lplc${major_version}"
+      fi
+      if test -n "$lib_nspr"; then
+	libdirs="$libdirs -lnspr${major_version}"
+      fi
+      os_ldflags="@LDFLAGS@"
+      for i in $os_ldflags ; do
+	if echo $i | grep \^-L >/dev/null; then
+	  libdirs="$libdirs $i"
+        fi
+      done
+      echo $libdirs @OS_LIBS@
+fi      
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/nspr.m4 b/nspr-4.8.6/mozilla/nsprpub/config/nspr.m4
new file mode 100644
index 0000000..d21df69
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/nspr.m4
@@ -0,0 +1,82 @@
+# -*- tab-width: 4; -*-
+# Configure paths for NSPR
+# Public domain - Chris Seawood <cls@seawood.org> 2001-04-05
+# Based upon gtk.m4 (also PD) by Owen Taylor
+
+dnl AM_PATH_NSPR([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for NSPR, and define NSPR_CFLAGS and NSPR_LIBS
+AC_DEFUN([AM_PATH_NSPR],
+[dnl
+
+AC_ARG_WITH(nspr-prefix,
+	[  --with-nspr-prefix=PFX  Prefix where NSPR is installed],
+	nspr_config_prefix="$withval",
+	nspr_config_prefix="")
+
+AC_ARG_WITH(nspr-exec-prefix,
+	[  --with-nspr-exec-prefix=PFX
+                          Exec prefix where NSPR is installed],
+	nspr_config_exec_prefix="$withval",
+	nspr_config_exec_prefix="")
+
+	if test -n "$nspr_config_exec_prefix"; then
+		nspr_config_args="$nspr_config_args --exec-prefix=$nspr_config_exec_prefix"
+		if test -z "$NSPR_CONFIG"; then
+			NSPR_CONFIG=$nspr_config_exec_prefix/bin/nspr-config
+		fi
+	fi
+	if test -n "$nspr_config_prefix"; then
+		nspr_config_args="$nspr_config_args --prefix=$nspr_config_prefix"
+		if test -z "$NSPR_CONFIG"; then
+			NSPR_CONFIG=$nspr_config_prefix/bin/nspr-config
+		fi
+	fi
+
+	unset ac_cv_path_NSPR_CONFIG
+	AC_PATH_PROG(NSPR_CONFIG, nspr-config, no)
+	min_nspr_version=ifelse([$1], ,4.0.0,$1)
+	AC_MSG_CHECKING(for NSPR - version >= $min_nspr_version)
+
+	no_nspr=""
+	if test "$NSPR_CONFIG" = "no"; then
+		no_nspr="yes"
+	else
+		NSPR_CFLAGS=`$NSPR_CONFIG $nspr_config_args --cflags`
+		NSPR_LIBS=`$NSPR_CONFIG $nspr_config_args --libs`
+
+		nspr_config_major_version=`$NSPR_CONFIG $nspr_config_args --version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+		nspr_config_minor_version=`$NSPR_CONFIG $nspr_config_args --version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+		nspr_config_micro_version=`$NSPR_CONFIG $nspr_config_args --version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+		min_nspr_major_version=`echo $min_nspr_version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+		min_nspr_minor_version=`echo $min_nspr_version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+		min_nspr_micro_version=`echo $min_nspr_version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+		if test "$nspr_config_major_version" -ne "$min_nspr_major_version"; then
+			no_nspr="yes"
+		elif test "$nspr_config_major_version" -eq "$min_nspr_major_version" &&
+		     test "$nspr_config_minor_version" -lt "$min_nspr_minor_version"; then
+			no_nspr="yes"
+		elif test "$nspr_config_major_version" -eq "$min_nspr_major_version" &&
+		     test "$nspr_config_minor_version" -eq "$min_nspr_minor_version" &&
+		     test "$nspr_config_micro_version" -lt "$min_nspr_micro_version"; then
+			no_nspr="yes"
+		fi
+	fi
+
+	if test -z "$no_nspr"; then
+		AC_MSG_RESULT(yes)
+		ifelse([$2], , :, [$2])     
+	else
+		AC_MSG_RESULT(no)
+	fi
+
+
+	AC_SUBST(NSPR_CFLAGS)
+	AC_SUBST(NSPR_LIBS)
+
+])
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/nsprincl.mk.in b/nspr-4.8.6/mozilla/nsprpub/config/nsprincl.mk.in
new file mode 100644
index 0000000..d56cc02
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/nsprincl.mk.in
@@ -0,0 +1,5 @@
+# Include in Makefiles to define NSPR variables
+
+NSPR_VERSION    = @NSPR_VERSION@
+NSPR_LIB        = -lnspr@NSPR_VERSION@
+NSPR_EXTRA_LIBS = @EXTRA_LIBS@
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/nsprincl.sh.in b/nspr-4.8.6/mozilla/nsprpub/config/nsprincl.sh.in
new file mode 100644
index 0000000..be4e145
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/nsprincl.sh.in
@@ -0,0 +1,5 @@
+# Include in shell scripts to define NSPR variables
+
+NSPR_VERSION=@NSPR_VERSION@
+NSPR_LIB=-lnspr$NSPR_VERSION
+NSPR_EXTRA_LIBS="@EXTRA_LIBS@"
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/pathsub.h b/nspr-4.8.6/mozilla/nsprpub/config/pathsub.h
new file mode 100644
index 0000000..bf3fca3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/pathsub.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef pathsub_h___
+#define pathsub_h___
+/*
+** Pathname subroutines.
+**
+** Brendan Eich, 8/29/95
+*/
+#include <limits.h>
+#include <sys/types.h>
+
+#if SUNOS4
+#include "../pr/include/md/sunos4.h"
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+/*
+ * Just prevent stupidity
+ */
+#undef NAME_MAX
+#define NAME_MAX 256
+
+extern char *program;
+
+extern void fail(char *format, ...);
+extern char *getcomponent(char *path, char *name);
+extern char *ino2name(ino_t ino, char *dir);
+extern void *xmalloc(size_t size);
+extern char *xstrdup(char *s);
+extern char *xbasename(char *path);
+extern void xchdir(char *dir);
+
+/* Relate absolute pathnames from and to returning the result in outpath. */
+extern int relatepaths(char *from, char *to, char *outpath);
+
+/* XXX changes current working directory -- caveat emptor */
+extern void reversepath(char *inpath, char *name, int len, char *outpath);
+
+#endif /* pathsub_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/prdepend.h b/nspr-4.8.6/mozilla/nsprpub/config/prdepend.h
new file mode 100644
index 0000000..55444c4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/prdepend.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * 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."
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/rules.mk b/nspr-4.8.6/mozilla/nsprpub/config/rules.mk
new file mode 100644
index 0000000..794b1ae
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/rules.mk
@@ -0,0 +1,482 @@
+#! gmake
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+################################################################################
+# We used to have a 4 pass build process.  Now we do everything in one pass.
+#
+# export - Create generated headers and stubs. Publish public headers to
+#          dist/<arch>/include.
+#          Create libraries. Publish libraries to dist/<arch>/lib.
+#          Create programs. 
+#
+# libs - obsolete.  Now a synonym of "export".
+#
+# all - the default makefile target.  Now a synonym of "export".
+#
+# install - Install headers, libraries, and programs on the system.
+#
+# Parameters to this makefile (set these before including):
+#
+# a)
+#	TARGETS	-- the target to create 
+#			(defaults to $LIBRARY $PROGRAM)
+# b)
+#	DIRS	-- subdirectories for make to recurse on
+#			(the 'all' rule builds $TARGETS $DIRS)
+# c)
+#	CSRCS   -- .c files to compile
+#			(used to define $OBJS)
+# d)
+#	PROGRAM	-- the target program name to create from $OBJS
+#			($OBJDIR automatically prepended to it)
+# e)
+#	LIBRARY	-- the target library name to create from $OBJS
+#			($OBJDIR automatically prepended to it)
+#
+################################################################################
+
+ifndef topsrcdir
+topsrcdir=$(MOD_DEPTH)
+endif
+
+ifndef srcdir
+srcdir=.
+endif
+
+ifndef NSPR_CONFIG_MK
+include $(topsrcdir)/config/config.mk
+endif
+
+ifdef USE_AUTOCONF
+ifdef CROSS_COMPILE
+ifdef INTERNAL_TOOLS
+CC=$(HOST_CC)
+CCC=$(HOST_CXX)
+CFLAGS=$(HOST_CFLAGS)
+CXXFLAGS=$(HOST_CXXFLAGS)
+LDFLAGS=$(HOST_LDFLAGS)
+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
+#
+# The names of these libraries can be generated by simply specifying
+# LIBRARY_NAME and LIBRARY_VERSION.
+#
+
+ifdef LIBRARY_NAME
+ifeq (,$(filter-out WINNT WINCE OS2,$(OS_ARCH)))
+
+#
+# Win95 and OS/2 require library names conforming to the 8.3 rule.
+# other platforms do not.
+#
+ifeq (,$(filter-out WIN95 WINCE WINMO OS2,$(OS_TARGET)))
+LIBRARY		= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX)
+SHARED_LIBRARY	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+IMPORT_LIBRARY	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
+SHARED_LIB_PDB	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).pdb
+else
+LIBRARY		= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX)
+SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+IMPORT_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
+SHARED_LIB_PDB	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).pdb
+endif
+
+else
+
+LIBRARY		= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
+ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1)
+SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_shr.a
+else
+ifdef MKSHLIB
+SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+endif
+endif
+
+endif
+endif
+
+ifndef TARGETS
+ifeq (,$(filter-out WINNT WINCE OS2,$(OS_ARCH)))
+TARGETS		= $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY)
+ifdef MOZ_DEBUG_SYMBOLS
+ifdef MSC_VER
+ifneq (,$(filter-out 1100 1200,$(MSC_VER)))
+TARGETS		+= $(SHARED_LIB_PDB)
+endif
+endif
+endif
+else
+TARGETS		= $(LIBRARY) $(SHARED_LIBRARY)
+endif
+endif
+
+#
+# OBJS is the list of object files.  It can be constructed by
+# specifying CSRCS (list of C source files) and ASFILES (list
+# of assembly language source files).
+#
+
+ifndef OBJS
+OBJS		= $(addprefix $(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \
+		  $(addprefix $(OBJDIR)/,$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
+endif
+
+ALL_TRASH		= $(TARGETS) $(OBJS) $(RES) $(filter-out . .., $(OBJDIR)) LOGS TAGS $(GARBAGE) \
+			  $(NOSUCHFILE) \
+			  so_locations
+
+ifndef RELEASE_LIBS_DEST
+RELEASE_LIBS_DEST	= $(RELEASE_LIB_DIR)
+endif
+
+define MAKE_IN_DIR
+	$(MAKE) -C $(dir) $@
+
+endef # do not remove the blank line!
+
+ifdef DIRS
+LOOP_OVER_DIRS = $(foreach dir,$(DIRS),$(MAKE_IN_DIR))
+endif
+
+################################################################################
+
+all:: export
+
+export::
+	+$(LOOP_OVER_DIRS)
+
+libs:: export
+
+clean::
+	rm -rf $(OBJS) $(RES) so_locations $(NOSUCHFILE) $(GARBAGE)
+	+$(LOOP_OVER_DIRS)
+
+clobber::
+	rm -rf $(OBJS) $(RES) $(TARGETS) $(filter-out . ..,$(OBJDIR)) $(GARBAGE) so_locations $(NOSUCHFILE)
+	+$(LOOP_OVER_DIRS)
+
+realclean clobber_all::
+	rm -rf $(wildcard *.OBJ *.OBJD) dist $(ALL_TRASH)
+	+$(LOOP_OVER_DIRS)
+
+distclean::
+	rm -rf $(wildcard *.OBJ *.OBJD) dist $(ALL_TRASH) $(DIST_GARBAGE)
+	+$(LOOP_OVER_DIRS)
+
+install:: $(RELEASE_BINS) $(RELEASE_HEADERS) $(RELEASE_LIBS)
+ifdef RELEASE_BINS
+	$(NSINSTALL) -t -m 0755 $(RELEASE_BINS) $(DESTDIR)$(bindir)
+endif
+ifdef RELEASE_HEADERS
+	$(NSINSTALL) -t -m 0644 $(RELEASE_HEADERS) $(DESTDIR)$(includedir)/$(include_subdir)
+endif
+ifdef RELEASE_LIBS
+	$(NSINSTALL) -t -m 0755 $(RELEASE_LIBS) $(DESTDIR)$(libdir)/$(lib_subdir)
+endif
+	+$(LOOP_OVER_DIRS)
+
+release:: export
+ifdef RELEASE_BINS
+	@echo "Copying executable programs and scripts to release directory"
+	@if test -z "$(BUILD_NUMBER)"; then \
+		echo "BUILD_NUMBER must be defined"; \
+		false; \
+	else \
+		true; \
+	fi
+	@if test ! -d $(RELEASE_BIN_DIR); then \
+		rm -rf $(RELEASE_BIN_DIR); \
+		$(NSINSTALL) -D $(RELEASE_BIN_DIR);\
+	else \
+		true; \
+	fi
+	cp $(RELEASE_BINS) $(RELEASE_BIN_DIR)
+endif
+ifdef RELEASE_LIBS
+	@echo "Copying libraries to release directory"
+	@if test -z "$(BUILD_NUMBER)"; then \
+		echo "BUILD_NUMBER must be defined"; \
+		false; \
+	else \
+		true; \
+	fi
+	@if test ! -d $(RELEASE_LIBS_DEST); then \
+		rm -rf $(RELEASE_LIBS_DEST); \
+		$(NSINSTALL) -D $(RELEASE_LIBS_DEST);\
+	else \
+		true; \
+	fi
+	cp $(RELEASE_LIBS) $(RELEASE_LIBS_DEST)
+endif
+ifdef RELEASE_HEADERS
+	@echo "Copying header files to release directory"
+	@if test -z "$(BUILD_NUMBER)"; then \
+		echo "BUILD_NUMBER must be defined"; \
+		false; \
+	else \
+		true; \
+	fi
+	@if test ! -d $(RELEASE_HEADERS_DEST); then \
+		rm -rf $(RELEASE_HEADERS_DEST); \
+		$(NSINSTALL) -D $(RELEASE_HEADERS_DEST);\
+	else \
+		true; \
+	fi
+	cp $(RELEASE_HEADERS) $(RELEASE_HEADERS_DEST)
+endif
+	+$(LOOP_OVER_DIRS)
+
+alltags:
+	rm -f TAGS tags
+	find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs etags -a
+	find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs ctags -a
+
+$(NFSPWD):
+	cd $(@D); $(MAKE) $(@F)
+
+$(PROGRAM): $(OBJS)
+	@$(MAKE_OBJDIR)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CC) $(OBJS) -Fe$@ -link $(LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS)
+ifdef MT
+	@if test -f $@.manifest; then \
+		$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
+		rm -f $@.manifest; \
+	fi
+endif	# MSVC with manifest tool
+else	# WINNT && !GCC
+	$(CC) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS)
+endif	# WINNT && !GCC
+ifdef ENABLE_STRIP
+	$(STRIP) $@
+endif
+
+$(LIBRARY): $(OBJS)
+	@$(MAKE_OBJDIR)
+	rm -f $@
+	$(AR) $(AR_FLAGS) $(OBJS) $(AR_EXTRA_ARGS)
+	$(RANLIB) $@
+
+ifeq ($(OS_TARGET), OS2)
+$(IMPORT_LIBRARY): $(MAPFILE)
+	rm -f $@
+	$(IMPLIB) $@ $(MAPFILE)
+else
+ifeq (,$(filter-out WIN95 WINCE WINMO,$(OS_TARGET)))
+$(IMPORT_LIBRARY): $(SHARED_LIBRARY)
+endif
+endif
+
+$(SHARED_LIBRARY): $(OBJS) $(RES) $(MAPFILE)
+	@$(MAKE_OBJDIR)
+	rm -f $@
+ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1)
+	echo "#!" > $(OBJDIR)/lib$(LIBRARY_NAME)_syms
+	nm -B -C -g $(OBJS) \
+		| awk '/ [T,D] / {print $$3}' \
+		| sed -e 's/^\.//' \
+		| sort -u >> $(OBJDIR)/lib$(LIBRARY_NAME)_syms
+	$(LD) $(XCFLAGS) -o $@ $(OBJS) -bE:$(OBJDIR)/lib$(LIBRARY_NAME)_syms \
+		-bM:SRE -bnoentry $(OS_LIBS) $(EXTRA_LIBS)
+else	# AIX 4.1
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(LINK_DLL) -MAP $(DLLBASE) $(DLL_LIBS) $(EXTRA_LIBS) $(OBJS) $(RES)
+ifdef MT
+	@if test -f $@.manifest; then \
+		$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;2; \
+		rm -f $@.manifest; \
+	fi
+endif	# MSVC with manifest tool
+else	# WINNT && !GCC
+	$(MKSHLIB) $(OBJS) $(RES) $(LDFLAGS) $(EXTRA_LIBS)
+endif	# WINNT && !GCC
+endif	# AIX 4.1
+ifdef ENABLE_STRIP
+	$(STRIP) $@
+endif
+
+ifeq ($(OS_ARCH),WINNT)
+$(RES): $(RESNAME)
+	@$(MAKE_OBJDIR)
+# The resource compiler does not understand the -U option.
+ifdef NS_USE_GCC
+	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) -o $@ $<
+else
+	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES) -Fo$@ $<
+endif # GCC
+	@echo $(RES) finished
+endif
+
+$(MAPFILE): $(LIBRARY_NAME).def
+	@$(MAKE_OBJDIR)
+ifeq ($(OS_ARCH),SunOS)
+	grep -v ';-' $< | \
+	sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
+endif
+ifeq ($(OS_ARCH),OS2)
+	echo LIBRARY $(LIBRARY_NAME)$(LIBRARY_VERSION) INITINSTANCE TERMINSTANCE > $@
+	echo PROTMODE >> $@
+	echo CODE    LOADONCALL MOVEABLE DISCARDABLE >> $@
+	echo DATA    PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@
+	echo EXPORTS >> $@
+	grep -v ';+' $< | grep -v ';-' | \
+	sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,\([\t ]*\),\1_,' | \
+	awk 'BEGIN {ord=1;} { print($$0 " @" ord " RESIDENTNAME"); ord++;}'	>> $@
+	$(ADD_TO_DEF_FILE)
+endif
+
+#
+# Translate source filenames to absolute paths. This is required for
+# debuggers under Windows and OS/2 to find source files automatically.
+#
+
+ifeq (,$(filter-out AIX OS2,$(OS_ARCH)))
+NEED_ABSOLUTE_PATH = 1
+endif
+
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+NEED_ABSOLUTE_PATH = 1
+endif
+
+ifdef NEED_ABSOLUTE_PATH
+# The quotes allow absolute paths to contain spaces.
+pr_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))"
+endif
+
+$(OBJDIR)/%.$(OBJ_SUFFIX): %.cpp
+	@$(MAKE_OBJDIR)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CCC) -Fo$@ -c $(CCCFLAGS) $(call pr_abspath,$<)
+else
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINCE)
+	$(CCC) -Fo$@ -c $(CCCFLAGS) $<
+else
+ifdef NEED_ABSOLUTE_PATH
+	$(CCC) -o $@ -c $(CCCFLAGS) $(call pr_abspath,$<)
+else
+	$(CCC) -o $@ -c $(CCCFLAGS) $<
+endif
+endif
+endif
+
+WCCFLAGS1 = $(subst /,\\,$(CFLAGS))
+WCCFLAGS2 = $(subst -I,-i=,$(WCCFLAGS1))
+WCCFLAGS3 = $(subst -D,-d,$(WCCFLAGS2))
+$(OBJDIR)/%.$(OBJ_SUFFIX): %.c
+	@$(MAKE_OBJDIR)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CC) -Fo$@ -c $(CFLAGS) $(call pr_abspath,$<)
+else
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINCE)
+	$(CC) -Fo$@ -c $(CFLAGS) $<
+else
+ifdef NEED_ABSOLUTE_PATH
+	$(CC) -o $@ -c $(CFLAGS) $(call pr_abspath,$<)
+else
+	$(CC) -o $@ -c $(CFLAGS) $<
+endif
+endif
+endif
+
+
+$(OBJDIR)/%.$(OBJ_SUFFIX): %.s
+	@$(MAKE_OBJDIR)
+	$(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.
+#
+.SUFFIXES:
+.SUFFIXES: .a .$(OBJ_SUFFIX) .c .cpp .s .h .i .pl
+
+#
+# Fake targets.  Always run these rules, even if a file/directory with that
+# name already exists.
+#
+.PHONY: all alltags clean export install libs realclean release
+
+#
+# List the target pattern of an implicit rule as a dependency of the
+# special target .PRECIOUS to preserve intermediate files made by
+# implicit rules whose target patterns match that file's name.
+# (See GNU Make documentation, Edition 0.51, May 1996, Sec. 10.4,
+# p. 107.)
+#
+.PRECIOUS: $(OBJDIR)/%.$(OBJ_SUFFIX)
diff --git a/nspr-4.8.6/mozilla/nsprpub/config/system-headers b/nspr-4.8.6/mozilla/nsprpub/config/system-headers
new file mode 100644
index 0000000..cf0f114
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/config/system-headers
@@ -0,0 +1,172 @@
+Aliases.h
+arpa/inet.h
+assert.h
+bsd/libc.h
+bsd/syscall.h
+bstring.h
+builtin.h
+c_asm.h
+cf.h
+CFBundle.h
+CFData.h
+CFDictionary.h
+CFString.h
+CFURL.h
+CodeFragments.h
+commdlg.h
+crt_externs.h
+crypt.h
+ctype.h
+descrip.h
+Devices.h
+direct.h
+dirent.h
+dlfcn.h
+dl.h
+DriverServices.h
+dvidef.h
+errno.h
+Errors.h
+Events.h
+fcntl.h
+fibdef.h
+files.h
+Files.h
+float.h
+Folders.h
+Gestalt.h
+getopt.h
+grp.h
+ia64/sys/inline.h
+ifaddrs.h
+image.h
+ints.h
+iodef.h
+io.h
+iostream.h
+kernel/OS.h
+lib$routines.h
+limits.h
+loader.h
+locale.h
+LowMem.h
+MacErrors.h
+machine/builtins.h
+machine/clock.h
+machine/endian.h
+machine/inline.h
+mach/mach_init.h
+mach/mach_host.h
+mach-o/dyld.h
+MacTypes.h
+Math64.h
+math.h
+mbstring.h
+memory.h
+MixedMode.h
+model.h
+mswsock.h
+Multiprocessing.h
+mutex.h
+netdb.h
+net/if.h
+netinet/in.h
+netinet/in_systm.h
+netinet/tcp.h
+OpenTptInternet.h
+OpenTransport.h
+os2.h
+OS.h
+osreldate.h
+OSUtils.h
+poll.h
+PPCToolbox.h
+Processes.h
+process.h
+pthread.h
+pwd.h
+QDOffscreen.h
+Resources.h
+rld_interface.h
+rpc/types.h
+semaphore.h
+setjmp.h
+share.h
+signal.h
+ssdef.h
+starlet.h
+stat.h
+stdarg.h
+stddef.h
+stdio.h
+stdlib.h
+string.h
+stropts.h
+stsdef.h
+support/SupportDefs.h
+support/TLS.h
+synch.h
+sys/atomic_op.h
+syscall.h
+sys/cfgodm.h
+sys/file.h
+sys/filio.h
+sys/immu.h
+sys/ioctl.h
+sys/ipc.h
+sys/ldr.h
+sys/locking.h
+sys/lwp.h
+sys/mman.h
+sys/mpctl.h
+sys/param.h
+sys/pda.h
+sys/poll.h
+sys/prctl.h
+sys/priv.h
+sys/procfs.h
+sys/pstat.h
+sys/regset.h
+sys/resource.h
+sys/sched.h
+sys/select.h
+sys/sem.h
+sys/sendfile.h
+sys/shm.h
+sys/socket.h
+sys/stack.h
+sys/stat.h
+sys/statvfs.h
+sys/syscall.h
+sys/sysctl.h
+sys/sysmp.h
+sys/syssgi.h
+sys/systeminfo.h
+sys/timeb.h
+sys/time.h
+sys/times.h
+sys/types.h
+sys/ucontext.h
+sys/uio.h
+sys/utsname.h
+sys/wait.h
+task.h
+TextUtils.h
+thread.h
+time.h
+Timer.h
+types.h
+Types.h
+ucontext.h
+ucx$inetdef.h
+ulocks.h
+unistd.h
+unix.h
+unixlib.h
+utime.h
+wchar.h
+winbase.h
+win/compobj.h
+windef.h
+windows.h
+winsock.h
diff --git a/nspr-4.8.6/mozilla/nsprpub/configure b/nspr-4.8.6/mozilla/nsprpub/configure
new file mode 100755
index 0000000..35bb8bf
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/configure
@@ -0,0 +1,6686 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --with-android-ndk=DIR
+                      location where the Android NDK can be found"
+ac_help="$ac_help
+  --with-android-toolchain=DIR
+                            location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0"
+ac_help="$ac_help
+  --with-android-platform=DIR
+                           location of platform dir, default NDK/build/platforms/android-5/arch-arm"
+ac_help="$ac_help
+  --with-dist-prefix=DIST_PREFIX
+                          place build files in DIST_PREFIX [dist]"
+ac_help="$ac_help
+  --with-dist-bindir=DIR  build execuatables in DIR [DIST_PREFIX/bin]"
+ac_help="$ac_help
+  --with-dist-includedir=DIR
+                          build include files in DIR [DIST_PREFIX/include/nspr]"
+ac_help="$ac_help
+  --with-dist-libdir=DIR  build library files in DIR [DIST_PREFIX/lib]"
+ac_help="$ac_help
+  --with-mozilla          Compile NSPR with Mozilla support"
+ac_help="$ac_help
+  --enable-optimize[=OPT] Enable code optimizations (ie. -O2) "
+ac_help="$ac_help
+  --enable-debug[=DBG]    Enable debugging (using compiler flags DBG)"
+ac_help="$ac_help
+  --enable-debug-symbols[=DBG]    Enable debugging symbols
+                                       (using compiler flags DBG)"
+ac_help="$ac_help
+  --enable-win32-target=\$t
+                          Specify win32 flavor. (WIN95 or WINNT)"
+ac_help="$ac_help
+  --enable-symbian-target=\$t
+                          Specify symbian flavor. (WINSCW or GCCE)"
+ac_help="$ac_help
+  --enable-debug-rtl      Use the MSVC debug runtime library"
+ac_help="$ac_help
+  --enable-n32            Enable n32 ABI support (IRIX only)"
+ac_help="$ac_help
+  --enable-64bit          Enable 64-bit support (on certain platforms)"
+ac_help="$ac_help
+  --enable-mdupdate       Enable use of certain compilers' mdupdate feature"
+ac_help="$ac_help
+  --enable-cplus          Enable some c++ api routines"
+ac_help="$ac_help
+  --with-arm-kuser        Use kuser helpers (Linux/ARM only)
+                          (Requires kernel 2.6.13 or later)"
+ac_help="$ac_help
+  --with-macos-sdk=dir    Location of platform SDK to use (Mac OS X only)"
+ac_help="$ac_help
+  --enable-macos-target=VER
+                          Set the minimum MacOS version needed at runtime
+                          [10.2 for ppc, 10.4 for x86]"
+ac_help="$ac_help
+  --disable-os2-high-mem  Disable high-memory support on OS/2"
+ac_help="$ac_help
+  --enable-thumb2              Enable Thumb2 instruction set"
+ac_help="$ac_help
+  --with-symbian-sdk=SYMBIAN_SDK_DIR
+                          The path to the Symbian SDK"
+ac_help="$ac_help
+  --enable-strip          Enable stripping of shared libs and programs"
+ac_help="$ac_help
+  --with-pthreads         Use system pthreads library as thread subsystem"
+ac_help="$ac_help
+  --enable-user-pthreads  Build using userland pthreads"
+ac_help="$ac_help
+  --enable-nspr-threads   Build using classic nspr threads"
+ac_help="$ac_help
+  --with-bthreads         Use system bthreads library as thread subsystem
+                          (BeOS only)"
+ac_help="$ac_help
+  --enable-ipv6           Compile ipv6 support"
+ac_help="$ac_help
+  --enable-boehm          Enable the Boehm Garbage Collector"
+ac_help="$ac_help
+  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)"
+ac_help="$ac_help
+  --with-wrap-malloc=SHAREDLIB  Location of malloc wrapper library"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=config/libc_r.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in ${srcdir}/build/autoconf $srcdir/${srcdir}/build/autoconf; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in ${srcdir}/build/autoconf $srcdir/${srcdir}/build/autoconf" 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+#    configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+#    same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+#    as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:652: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:673: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+  case $nonopt in
+  NONE) target_alias=$host_alias ;;
+  *) target_alias=$nonopt ;;
+  esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:691: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+
+MOD_MAJOR_VERSION=4
+MOD_MINOR_VERSION=8
+MOD_PATCH_VERSION=6
+NSPR_MODNAME=nspr20
+_HAVE_PTHREADS=
+USE_PTHREADS=
+USE_USER_PTHREADS=
+USE_NSPR_THREADS=
+USE_N32=
+USE_64=
+USE_CPLUS=
+USE_IPV6=
+USE_MDUPDATE=
+_MACOSX_DEPLOYMENT_TARGET=
+_OPTIMIZE_FLAGS=-O
+_DEBUG_FLAGS=-g
+MOZ_DEBUG=1
+MOZ_OPTIMIZE=
+OBJDIR='$(OBJDIR_NAME)'
+OBJDIR_NAME=.
+OBJDIR_SUFFIX=OBJ
+NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall'
+NOSUCHFILE=/no-such-file
+LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)'
+LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)'
+CYGWIN_WRAPPER=
+MACOS_SDK_DIR=
+NEXT_ROOT=
+MT=
+MOZ_OS2_HIGH_MEMORY=1
+MOZ_THUMB2=
+PROFILE_GEN_CFLAGS=
+PROFILE_GEN_LDFLAGS=
+PROFILE_USE_CFLAGS=
+PROFILE_USE_LDFLAGS=
+
+RESOLVE_LINK_SYMBOLS=
+
+CFLAGS="${CFLAGS=}"
+CXXFLAGS="${CXXFLAGS=}"
+LDFLAGS="${LDFLAGS=}"
+DLLFLAGS="${DLLFLAGS=}"
+HOST_CFLAGS="${HOST_CFLAGS=}"
+HOST_LDFLAGS="${HOST_LDFLAGS=}"
+
+case "$target" in
+*-cygwin*|*-mingw*)
+    # Check to see if we are really running in a msvc environemnt
+    _WIN32_MSVC=
+    for ac_prog in cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:768: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CC" && break
+done
+
+    if test "$CC" = "cl"; then
+        echo 'main() { return 0; }' > dummy.c
+        ${CC} -o dummy dummy.c >/dev/null 2>&1
+        if test $? = 0; then
+            _WIN32_MSVC=1
+            CXX=$CC
+        else
+            echo "configure: warning: $(CC) test failed.  Using normal feature tests" 1>&2
+        fi
+        rm -f dummy dummy.o dummy.obj dummy.exe dummy.c
+    fi
+    ;;
+*-msvc*)
+    _WIN32_MSVC=1
+    ;;
+*-mks*)
+    _WIN32_MSVC=1
+    ;;
+esac
+
+if test -n "$_WIN32_MSVC"; then
+    SKIP_PATH_CHECKS=1
+    SKIP_COMPILER_CHECKS=1
+    SKIP_LIBRARY_CHECKS=1
+fi
+
+
+# Check whether --with-android-ndk or --without-android-ndk was given.
+if test "${with_android_ndk+set}" = set; then
+  withval="$with_android_ndk"
+  android_ndk=$withval
+fi
+
+
+# Check whether --with-android-toolchain or --without-android-toolchain was given.
+if test "${with_android_toolchain+set}" = set; then
+  withval="$with_android_toolchain"
+  android_toolchain=$withval
+fi
+
+
+# Check whether --with-android-platform or --without-android-platform was given.
+if test "${with_android_platform+set}" = set; then
+  withval="$with_android_platform"
+  android_platform=$withval
+fi
+
+
+if test "$target" = "arm-android-eabi" ; then
+    if test -z "$android_ndk" ; then
+       { echo "configure: error: You must specify --with-android-ndk=/path/to/ndk when targeting Android." 1>&2; exit 1; }
+    fi
+
+    if test -z "$android_toolchain" ; then
+       android_toolchain="$android_ndk"/build/prebuilt/`uname -s | tr "[:upper:]" "[:lower:]"`-x86/arm-eabi-4.4.0
+    fi
+
+    if test -z "$android_platform" ; then
+       android_platform="$android_ndk"/build/platforms/android-5/arch-arm
+    fi
+
+        AS="$android_toolchain"/bin/arm-eabi-as
+    CC="$android_toolchain"/bin/arm-eabi-gcc
+    CXX="$android_toolchain"/bin/arm-eabi-g++
+    CPP="$android_toolchain"/bin/arm-eabi-cpp
+    LD="$android_toolchain"/bin/arm-eabi-ld
+    AR="$android_toolchain"/bin/arm-eabi-ar
+    RANLIB="$android_toolchain"/bin/arm-eabi-ranlib
+    STRIP="$android_toolchain"/bin/arm-eabi-strip
+
+    CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS"
+    CFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions $CFLAGS"
+    CXXFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fpic -fno-short-enums -fno-exceptions $CXXFLAGS"
+    LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform $LDFLAGS"
+
+        if test -z "$HOST_CPPFLAGS" ; then
+        HOST_CPPFLAGS=" "
+    fi
+    if test -z "$HOST_CFLAGS" ; then
+        HOST_CFLAGS=" "
+    fi
+    if test -z "$HOST_CXXFLAGS" ; then
+        HOST_CXXFLAGS=" "
+    fi
+    if test -z "$HOST_LDFLAGS" ; then
+        HOST_LDFLAGS=" "
+    fi
+
+    cat >> confdefs.h <<\EOF
+#define ANDROID 1
+EOF
+
+fi
+
+dist_prefix='${MOD_DEPTH}/dist'
+dist_bindir='${dist_prefix}/bin'
+dist_includedir='${dist_prefix}/include/nspr'
+dist_libdir='${dist_prefix}/lib'
+if test "${includedir}" = '${prefix}/include'; then
+    includedir='${prefix}/include/nspr'
+fi
+
+# Check whether --with-dist-prefix or --without-dist-prefix was given.
+if test "${with_dist_prefix+set}" = set; then
+  withval="$with_dist_prefix"
+  dist_prefix=$withval
+fi
+
+
+# Check whether --with-dist-bindir or --without-dist-bindir was given.
+if test "${with_dist_bindir+set}" = set; then
+  withval="$with_dist_bindir"
+  dist_bindir=$withval
+fi
+
+
+# Check whether --with-dist-includedir or --without-dist-includedir was given.
+if test "${with_dist_includedir+set}" = set; then
+  withval="$with_dist_includedir"
+  dist_includedir=$withval
+fi
+
+
+# Check whether --with-dist-libdir or --without-dist-libdir was given.
+if test "${with_dist_libdir+set}" = set; then
+  withval="$with_dist_libdir"
+  dist_libdir=$withval
+fi
+
+
+
+
+
+
+
+# Check whether --with-mozilla or --without-mozilla was given.
+if test "${with_mozilla+set}" = set; then
+  withval="$with_mozilla"
+     if test "$withval" = "yes"; then
+            cat >> confdefs.h <<\EOF
+#define MOZILLA_CLIENT 1
+EOF
+
+            MOZILLA_CLIENT=1
+	    else
+	        MOZILLA_CLIENT=
+	    fi
+else
+  	if test -n "$MOZILLA_CLIENT"; then
+	        cat >> confdefs.h <<\EOF
+#define MOZILLA_CLIENT 1
+EOF
+
+	    fi
+fi
+
+
+# Check whether --enable-optimize or --disable-optimize was given.
+if test "${enable_optimize+set}" = set; then
+  enableval="$enable_optimize"
+   if test "$enableval" != "no"; then
+          MOZ_OPTIMIZE=1
+          if test -n "$enableval" -a "$enableval" != "yes"; then
+            _OPTIMIZE_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+            _SAVE_OPTIMIZE_FLAGS=$_OPTIMIZE_FLAGS
+          fi
+      else
+          MOZ_OPTIMIZE=
+      fi 
+fi
+
+
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+  enableval="$enable_debug"
+   if test "$enableval" != "no"; then
+          MOZ_DEBUG=1
+          MOZ_DEBUG_SYMBOLS=1
+          if test -n "$enableval" -a "$enableval" != "yes"; then
+              _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+              _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS
+          fi
+      else
+          MOZ_DEBUG=
+      fi 
+else
+  MOZ_DEBUG_SYMBOLS=1
+fi
+
+
+# Check whether --enable-debug-symbols or --disable-debug-symbols was given.
+if test "${enable_debug_symbols+set}" = set; then
+  enableval="$enable_debug_symbols"
+   if test "$enableval" != "no"; then
+          MOZ_DEBUG_SYMBOLS=1
+          if test -n "$enableval" -a "$enableval" != "yes"; then
+              if test -z "$_SAVE_DEBUG_FLAGS"; then
+                  _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+                  _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS
+              else
+                  { echo "configure: error: --enable-debug-symbols flags cannot be used with --enable-debug flags" 1>&2; exit 1; }
+              fi
+          fi
+      else
+          MOZ_DEBUG_SYMBOLS=
+      fi 
+fi
+
+
+# Check whether --enable-win32-target or --disable-win32-target was given.
+if test "${enable_win32_target+set}" = set; then
+  enableval="$enable_win32_target"
+  OS_TARGET=`echo $enableval | tr a-z A-Z`
+fi
+
+
+# Check whether --enable-symbian-target or --disable-symbian-target was given.
+if test "${enable_symbian_target+set}" = set; then
+  enableval="$enable_symbian_target"
+  OS_TARGET=`echo $enableval | tr a-z A-Z`
+fi
+
+
+# Check whether --enable-debug-rtl or --disable-debug-rtl was given.
+if test "${enable_debug_rtl+set}" = set; then
+  enableval="$enable_debug_rtl"
+   if test "$enableval" = "yes"; then
+	    USE_DEBUG_RTL=1
+      fi 
+fi
+
+
+# Check whether --enable-n32 or --disable-n32 was given.
+if test "${enable_n32+set}" = set; then
+  enableval="$enable_n32"
+   if test "$enableval" = "yes"; then
+	USE_N32=1
+      else if test "$enableval" = "no"; then
+	USE_N32=
+      fi
+    fi 
+fi
+
+
+# Check whether --enable-64bit or --disable-64bit was given.
+if test "${enable_64bit+set}" = set; then
+  enableval="$enable_64bit"
+   if test "$enableval" = "yes"; then
+	    USE_64=1
+      fi 
+fi
+
+
+# Check whether --enable-mdupdate or --disable-mdupdate was given.
+if test "${enable_mdupdate+set}" = set; then
+  enableval="$enable_mdupdate"
+   if test "$enableval" = "yes"; then
+	    USE_MDUPDATE=1
+      fi 
+fi
+
+
+# Check whether --enable-cplus or --disable-cplus was given.
+if test "${enable_cplus+set}" = set; then
+  enableval="$enable_cplus"
+   if test "$enableval" = "yes"; then
+	    USE_CPLUS=1
+      fi
+fi
+ 
+
+# Check whether --with-arm-kuser or --without-arm-kuser was given.
+if test "${with_arm_kuser+set}" = set; then
+  withval="$with_arm_kuser"
+   if test "$withval" = "yes"; then
+	    cat >> confdefs.h <<\EOF
+#define _PR_ARM_KUSER 1
+EOF
+
+      fi 
+fi
+
+
+# Check whether --with-macos-sdk or --without-macos-sdk was given.
+if test "${with_macos_sdk+set}" = set; then
+  withval="$with_macos_sdk"
+  MACOS_SDK_DIR=$withval
+fi
+
+
+# Check whether --enable-macos-target or --disable-macos-target was given.
+if test "${enable_macos_target+set}" = set; then
+  enableval="$enable_macos_target"
+  _MACOSX_DEPLOYMENT_TARGET=$enableval
+fi
+
+
+case "$target" in
+
+*-aix*)
+    case "${target_os}" in
+    aix3.2*)
+        USE_NSPR_THREADS=1
+        ;;
+    *)
+        USE_PTHREADS=1
+        ;;
+    esac
+    ;;
+
+esac
+
+if test -z "$CC"; then
+    case "$target" in
+
+    *-aix*)
+        if test -z "$USE_NSPR_THREADS"; then
+            CC=xlc_r
+        else
+            CC=xlc
+        fi
+    ;;
+
+    *-hpux*)
+        CC=cc
+    ;;
+
+    *-irix*)
+        CC=cc
+    ;;
+
+    *-osf*)
+        CC=cc
+    ;;
+
+    *-solaris*)
+        CC=cc
+    ;;
+
+    esac
+fi
+
+if test -z "$CXX"; then
+    case "$target" in
+
+    *-aix*)
+        if test -z "$USE_NSPR_THREADS"; then
+            CXX=xlC_r
+        else
+            CXX=xlC
+        fi
+    ;;
+
+    *-hpux*)
+        case "${target_os}" in
+        hpux10.30)
+            CXX=aCC
+            ;;
+        hpux11.*)
+            CXX=aCC
+            ;;
+        *)
+            CXX=CC
+            ;;
+        esac
+    ;;
+
+    *-irix*)
+        CXX=CC
+    ;;
+
+    *-osf*)
+        CXX=cxx
+    ;;
+
+    *-solaris*)
+        CXX=CC
+    ;;
+
+    esac
+fi
+
+if test -z "$SKIP_PATH_CHECKS"; then
+    # Extract the first word of "$WHOAMI whoami", so it can be a program name with args.
+set dummy $WHOAMI whoami; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1183: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_WHOAMI'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$WHOAMI" in
+  /*)
+  ac_cv_path_WHOAMI="$WHOAMI" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_WHOAMI="$WHOAMI" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_WHOAMI="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_WHOAMI" && ac_cv_path_WHOAMI="echo not_whoami"
+  ;;
+esac
+fi
+WHOAMI="$ac_cv_path_WHOAMI"
+if test -n "$WHOAMI"; then
+  echo "$ac_t""$WHOAMI" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+if test -n "$MOZ_DEBUG"; then
+    cat >> confdefs.h <<\EOF
+#define DEBUG 1
+EOF
+
+    DEFINES="$DEFINES -UNDEBUG"
+
+    case "${target_os}" in
+    beos*)
+        DEFINES="$DEFINES -DDEBUG_${USER}"
+        ;;
+    msvc*|mks*|cygwin*|mingw*|wince*|winmo*|os2*)
+        DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`"
+        ;;
+    *) 
+        DEFINES="$DEFINES -DDEBUG_`$WHOAMI`"
+        ;;
+    esac
+else
+    cat >> confdefs.h <<\EOF
+#define NDEBUG 1
+EOF
+
+    DEFINES="$DEFINES -UDEBUG"
+fi
+
+if test -z "$SKIP_COMPILER_CHECKS"; then
+if test "$target" != "$host"; then
+    echo "cross compiling from $host to $target"
+    cross_compiling=yes
+
+    _SAVE_CC="$CC"
+    _SAVE_CFLAGS="$CFLAGS"
+    _SAVE_LDFLAGS="$LDFLAGS"
+
+    echo $ac_n "checking for $host compiler""... $ac_c" 1>&6
+echo "configure:1254: checking for $host compiler" >&5
+    for ac_prog in $HOST_CC gcc cc /usr/ucb/cc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1260: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_HOST_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$HOST_CC"; then
+  ac_cv_prog_HOST_CC="$HOST_CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_HOST_CC="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+HOST_CC="$ac_cv_prog_HOST_CC"
+if test -n "$HOST_CC"; then
+  echo "$ac_t""$HOST_CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$HOST_CC" && break
+done
+test -n "$HOST_CC" || HOST_CC=""""
+
+    if test -z "$HOST_CC"; then
+        { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+    fi
+    echo "$ac_t""$HOST_CC" 1>&6
+    if test -z "$HOST_CFLAGS"; then
+        HOST_CFLAGS="$CFLAGS"
+    fi
+    if test -z "$HOST_LDFLAGS"; then
+        HOST_LDFLAGS="$LDFLAGS"
+    fi
+
+    CC="$HOST_CC"
+    CFLAGS="$HOST_CFLAGS"
+    LDFLAGS="$HOST_LDFLAGS"
+
+    echo $ac_n "checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1306: checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works" >&5
+    cat > conftest.$ac_ext <<EOF
+#line 1308 "configure"
+#include "confdefs.h"
+
+int main() {
+return(0);
+; return 0; }
+EOF
+if { (eval echo configure:1315: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_prog_host_cc_works=1 echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  { echo "configure: error: installation or configuration problem: $host compiler $HOST_CC cannot create executables." 1>&2; exit 1; } 
+fi
+rm -f conftest*
+
+    CC=$_SAVE_CC
+    CFLAGS=$_SAVE_CFLAGS
+    LDFLAGS=$_SAVE_LDFLAGS
+
+    case "$build:$target" in 
+      powerpc-apple-darwin8*:i?86-apple-darwin*)
+                                                _SAVE_CFLAGS=$CFLAGS 
+        _SAVE_CXXFLAGS=$CXXLAGS
+        CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CFLAGS"
+        CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS"
+        ;;        
+    esac            
+
+    for ac_prog in $CC "${target_alias}-gcc" "${target}-gcc"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1344: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CC" && break
+done
+test -n "$CC" || CC="echo"
+
+    unset ac_cv_prog_CC
+    # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1378: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1408: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1459: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1491: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1502 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1507: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1533: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1538: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1547: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1566: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+    if test -n "$USE_CPLUS"; then
+        for ac_prog in $CXX "${target_alias}-g++" "${target}-g++"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1603: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="echo"
+
+        unset ac_cv_prog_CXX
+        for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1639: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1671: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1682 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:1687: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1713: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:1718: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1727: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:1746: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+
+    fi
+
+    case "$build:$target" in
+      powerpc-apple-darwin8*:i?86-apple-darwin*)
+                                CFLAGS=$_SAVE_CFLAGS
+        CXXFLAGS=$_SAVE_CXXFLAGS
+        ;;
+    esac
+
+    for ac_prog in $RANLIB "${target_alias}-ranlib" "${target}-ranlib"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1791: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$RANLIB" && break
+done
+test -n "$RANLIB" || RANLIB="echo"
+
+    for ac_prog in $AR "${target_alias}-ar" "${target}-ar"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1826: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AR="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+  echo "$ac_t""$AR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AR" && break
+done
+test -n "$AR" || AR="echo"
+
+    for ac_prog in $AS "${target_alias}-as" "${target}-as"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1861: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AS"; then
+  ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AS="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+  echo "$ac_t""$AS" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AS" && break
+done
+test -n "$AS" || AS="echo"
+
+    for ac_prog in $LD "${target_alias}-ld" "${target}-ld"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1896: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$LD"; then
+  ac_cv_prog_LD="$LD" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_LD="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+LD="$ac_cv_prog_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LD" && break
+done
+test -n "$LD" || LD="echo"
+
+    for ac_prog in $STRIP "${target_alias}-strip" "${target}-strip"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1931: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_STRIP="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+  echo "$ac_t""$STRIP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$STRIP" && break
+done
+test -n "$STRIP" || STRIP="echo"
+
+    for ac_prog in $WINDRES "${target_alias}-windres" "${target}-windres"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1966: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$WINDRES"; then
+  ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_WINDRES="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+WINDRES="$ac_cv_prog_WINDRES"
+if test -n "$WINDRES"; then
+  echo "$ac_t""$WINDRES" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$WINDRES" && break
+done
+test -n "$WINDRES" || WINDRES="echo"
+
+
+else
+    # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2001: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2031: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2082: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2114: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2125 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:2130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2156: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:2161: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2170: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:2189: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+    if test -n "$USE_CPLUS"; then
+        if test "$CC" = "cl" -a -z "$CXX"; then
+            CXX=$CC
+        else        
+            for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2229: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2261: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2272 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:2277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2303: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:2308: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:2317: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:2336: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+
+        fi
+    fi
+    echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2370: 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 2385 "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:2391: \"$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 2402 "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:2408: \"$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 2419 "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:2425: \"$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=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+    # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2452: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    for ac_prog in as
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2484: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_AS'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$AS" in
+  /*)
+  ac_cv_path_AS="$AS" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_AS="$AS" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_AS="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+AS="$ac_cv_path_AS"
+if test -n "$AS"; then
+  echo "$ac_t""$AS" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AS" && break
+done
+test -n "$AS" || AS="$CC"
+
+    for ac_prog in ar
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2525: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$AR" in
+  /*)
+  ac_cv_path_AR="$AR" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_AR="$AR" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_AR="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+AR="$ac_cv_path_AR"
+if test -n "$AR"; then
+  echo "$ac_t""$AR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AR" && break
+done
+test -n "$AR" || AR="echo not_ar"
+
+    for ac_prog in ld link
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2566: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$LD" in
+  /*)
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_LD="$LD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_LD="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LD" && break
+done
+test -n "$LD" || LD="echo not_ld"
+
+    for ac_prog in strip
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2607: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_STRIP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$STRIP" in
+  /*)
+  ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_STRIP="$STRIP" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_STRIP="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+STRIP="$ac_cv_path_STRIP"
+if test -n "$STRIP"; then
+  echo "$ac_t""$STRIP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$STRIP" && break
+done
+test -n "$STRIP" || STRIP="echo not_strip"
+
+    for ac_prog in windres
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2648: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_WINDRES'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$WINDRES" in
+  /*)
+  ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_WINDRES="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+WINDRES="$ac_cv_path_WINDRES"
+if test -n "$WINDRES"; then
+  echo "$ac_t""$WINDRES" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$WINDRES" && break
+done
+test -n "$WINDRES" || WINDRES="echo not_windres"
+
+    if test -z "$HOST_CC"; then
+        HOST_CC="$CC"
+    fi
+    if test -z "$HOST_CFLAGS"; then
+        HOST_CFLAGS="$CFLAGS"
+    fi
+fi
+
+if test "$GCC" = "yes"; then
+    GNU_CC=1
+fi
+if test "$GXX" = "yes"; then
+    GNU_CXX=1
+fi
+if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then
+    GNU_AS=1
+fi
+rm -f a.out
+
+case "$build:$target" in
+    i?86-apple-darwin*:powerpc-apple-darwin*)
+                                cross_compiling=yes
+        ;;
+esac
+
+if test "$cross_compiling"  = "yes"; then
+    CROSS_COMPILE=1
+else
+    CROSS_COMPILE=
+fi
+
+echo $ac_n "checking for gcc -pipe support""... $ac_c" 1>&6
+echo "configure:2716: checking for gcc -pipe support" >&5
+if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then
+    echo '#include <stdio.h>' > dummy-hello.c
+    echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c
+    ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5
+    cat dummy-hello.s | ${AS} -o dummy-hello.S - 2>&5
+    if test $? = 0; then
+        _res_as_stdin="yes"
+    else
+        _res_as_stdin="no"
+    fi
+    if test "$_res_as_stdin" = "yes"; then
+        _SAVE_CFLAGS=$CFLAGS
+        CFLAGS="$CFLAGS -pipe"
+        cat > conftest.$ac_ext <<EOF
+#line 2731 "configure"
+#include "confdefs.h"
+ #include <stdio.h> 
+int main() {
+printf("Hello World\n");
+; return 0; }
+EOF
+if { (eval echo configure:2738: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  _res_gcc_pipe="yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  _res_gcc_pipe="no" 
+fi
+rm -f conftest*
+        CFLAGS=$_SAVE_CFLAGS
+    fi
+    if test "$_res_as_stdin" = "yes" && test "$_res_gcc_pipe" = "yes"; then
+        _res="yes";
+        CFLAGS="$CFLAGS -pipe"
+        CXXFLAGS="$CXXFLAGS -pipe"
+    else
+        _res="no"
+    fi
+    rm -f dummy-hello.c dummy-hello.s dummy-hello.S dummy-hello a.out
+    echo "$ac_t""$_res" 1>&6
+else
+    echo "$ac_t""no" 1>&6
+fi
+
+
+_SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction"
+
+echo $ac_n "checking whether C compiler supports -fprofile-generate""... $ac_c" 1>&6
+echo "configure:2768: checking whether C compiler supports -fprofile-generate" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2770 "configure"
+#include "confdefs.h"
+
+int main() {
+return 0;
+; return 0; }
+EOF
+if { (eval echo configure:2777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+   PROFILE_GEN_CFLAGS="-fprofile-generate"
+                 result="yes" 
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  result="no"
+fi
+rm -f conftest*
+echo "$ac_t""$result" 1>&6
+
+if test $result = "yes"; then
+   PROFILE_GEN_LDFLAGS="-fprofile-generate"
+   PROFILE_USE_CFLAGS="-fprofile-use -fprofile-correction -Wcoverage-mismatch -freorder-blocks-and-partition"
+   PROFILE_USE_LDFLAGS="-fprofile-use"
+fi
+
+CFLAGS="$_SAVE_CFLAGS"
+
+if test "$GNU_CC"; then
+    echo $ac_n "checking for visibility(hidden) attribute""... $ac_c" 1>&6
+echo "configure:2800: checking for visibility(hidden) attribute" >&5
+if eval "test \"`echo '$''{'ac_cv_visibility_hidden'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+        int foo __attribute__ ((visibility ("hidden"))) = 1;
+EOF
+        ac_cv_visibility_hidden=no
+        if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+            if grep '\.hidden.*foo' conftest.s >/dev/null; then
+                ac_cv_visibility_hidden=yes
+            fi
+        fi
+        rm -f conftest.cs
+        
+fi
+
+echo "$ac_t""$ac_cv_visibility_hidden" 1>&6
+    if test "$ac_cv_visibility_hidden" = "yes"; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_VISIBILITY_HIDDEN_ATTRIBUTE 1
+EOF
+
+        echo $ac_n "checking for visibility pragma support""... $ac_c" 1>&6
+echo "configure:2824: checking for visibility pragma support" >&5
+if eval "test \"`echo '$''{'ac_cv_visibility_pragma'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#pragma GCC visibility push(hidden)
+            int foo_hidden = 1;
+#pragma GCC visibility push(default)
+            int foo_default = 1;
+EOF
+            ac_cv_visibility_pragma=no
+            if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+                if grep '\.hidden.*foo_hidden' conftest.s >/dev/null; then
+                    if ! grep '\.hidden.*foo_default' conftest.s > /dev/null; then
+                        ac_cv_visibility_pragma=yes
+                    fi
+                fi
+            fi
+            rm -f conftest.cs
+            
+fi
+
+echo "$ac_t""$ac_cv_visibility_pragma" 1>&6
+        if test "$ac_cv_visibility_pragma" = "yes"; then
+            cat >> confdefs.h <<\EOF
+#define HAVE_VISIBILITY_PRAGMA 1
+EOF
+
+            # To work around a build problem on Linux x86-64 (Bugzilla bug
+            # 293438), we use the -fvisibility=hidden flag.  This flag is less
+            # optimal than #pragma GCC visibility push(hidden) because the flag
+            # assumes that symbols defined outside the current source file have
+            # the default visibility.  This has the advantage that we don't need
+            # to wrap system header files, but has the disadvantage that calls
+            # to hidden symbols defined in other source files cannot be
+            # optimized by the compiler.  The -fvisibility=hidden flag does
+            # hide and export symbols correctly.
+            #VISIBILITY_FLAGS='-I$(dist_includedir)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
+            #WRAP_SYSTEM_INCLUDES=1
+            VISIBILITY_FLAGS="-fvisibility=hidden"
+            WRAP_SYSTEM_INCLUDES=
+        fi
+    fi
+fi # GNU_CC
+
+fi # SKIP_COMPILER_CHECKS
+
+if test -z "$SKIP_PATH_CHECKS"; then
+    for ac_prog in perl5 perl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2877: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$PERL" in
+  /*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_PERL="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+PERL="$ac_cv_path_PERL"
+if test -n "$PERL"; then
+  echo "$ac_t""$PERL" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PERL" && break
+done
+test -n "$PERL" || PERL="echo not_perl"
+
+elif test -z "$PERL"; then
+    PERL=perl
+fi
+
+OBJ_SUFFIX=o
+LIB_SUFFIX=a
+DLL_SUFFIX=so
+ASM_SUFFIX=s
+MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@'
+PR_MD_ASFILES=
+PR_MD_CSRCS=
+PR_MD_ARCH_DIR=unix
+AR_FLAGS='cr $@'
+AS='$(CC)'
+ASFLAGS='$(CFLAGS)'
+
+if test -n "$CROSS_COMPILE"; then
+    OS_ARCH=`echo $target_os | sed -e 's|/|_|g'`
+    OS_RELEASE=
+    OS_TEST="${target_cpu}"
+    case "${target_os}" in
+        linux*)       OS_ARCH=Linux ;;
+        solaris*)     OS_ARCH=SunOS OS_RELEASE=5 ;;
+        mingw*)       OS_ARCH=WINNT ;;
+        wince*)       OS_ARCH=WINCE ;;
+        winmo*)       OS_ARCH=WINCE ;;
+        darwin*)      OS_ARCH=Darwin ;;
+        riscos*)      OS_ARCH=RISCOS ;;
+    esac
+else
+    OS_ARCH=`uname -s | sed -e 's|/|_|g'`
+    OS_RELEASE=`uname -r`
+    OS_TEST=`uname -m`
+fi
+
+if test "$OS_ARCH" = "IRIX64"; then
+    OS_ARCH=IRIX
+fi
+
+if test "$OS_ARCH" = "AIX"; then
+    OS_RELEASE=`uname -v`.`uname -r`
+fi
+
+if test "$OS_ARCH" = "FreeBSD"; then
+    OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'`
+fi
+
+if test "$OS_ARCH" = "Linux"; then
+    OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'`
+    OS_RELEASE=`echo $OS_RELEASE | awk -F\. '{ print $1 "." $2 }'`
+fi
+
+#######################################################################
+# Master "Core Components" macros for getting the OS target           #
+#######################################################################
+
+#
+# Note: OS_TARGET should be specified on the command line for gmake.
+# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built.
+# The difference between the Win95 target and the WinNT target is that
+# the WinNT target uses Windows NT specific features not available
+# in Windows 95. The Win95 target will run on Windows NT, but (supposedly)
+# at lesser performance (the Win95 target uses threads; the WinNT target
+# uses fibers).
+#
+# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no
+# cross-compilation.
+#
+
+#
+# The following hack allows one to build on a WIN95 machine (as if
+# s/he were cross-compiling on a WINNT host for a WIN95 target).
+# It also accomodates for MKS's uname.exe.  If you never intend
+# to do development on a WIN95 machine, you don't need this hack.
+#
+case "$OS_ARCH" in
+WIN95)
+    OS_ARCH=WINNT
+    OS_TARGET=WIN95
+    ;;
+Windows_95)
+    OS_ARCH=Windows_NT
+    OS_TARGET=WIN95
+    ;;
+Windows_98)
+    OS_ARCH=Windows_NT
+    OS_TARGET=WIN95
+    ;;
+CYGWIN_9*|CYGWIN_ME*)
+    OS_ARCH='CYGWIN_NT-4.0'
+    OS_TARGET=WIN95
+    ;;
+OS_2)
+    OS_ARCH=OS2
+    OS_TARGET=OS2
+    ;;
+esac
+
+#
+# On WIN32, we also define the variable CPU_ARCH.
+#
+
+case "$OS_ARCH" in
+WINNT)
+    CPU_ARCH=`uname -p`
+    if test "$CPU_ARCH" = "I386"; then
+        CPU_ARCH=x86
+    fi
+    ;;
+Windows_NT)
+#
+# If uname -s returns "Windows_NT", we assume that we are using
+# the uname.exe in MKS toolkit.
+#
+# The -r option of MKS uname only returns the major version number.
+# So we need to use its -v option to get the minor version number.
+# Moreover, it doesn't have the -p option, so we need to use uname -m.
+#
+    OS_ARCH=WINNT
+    OS_MINOR_RELEASE=`uname -v`
+    if test "$OS_MINOR_RELEASE" = "00"; then
+        OS_MINOR_RELEASE=0
+    fi
+    OS_RELEASE="${OS_RELEASE}.${OS_MINOR_RELEASE}"
+    CPU_ARCH=`uname -m`
+    #
+    # MKS's uname -m returns "586" on a Pentium machine.
+    #
+    if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    fi
+    ;;
+CYGWIN_NT*|MINGW*_NT*)
+#
+# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using
+# the uname.exe in the Cygwin tools.
+# If uname -s returns MINGW32_NT-5.1, we assume that we are using
+# the uname.exe in the MSYS tools.
+#
+    OS_RELEASE=`expr $OS_ARCH : '.*NT-\(.*\)'`
+    OS_ARCH=WINNT
+    CPU_ARCH=`uname -m`
+    #
+    # Cygwin's uname -m returns "i686" on a Pentium Pro machine.
+    #
+    if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    fi
+    ;;
+esac
+
+if test -n "$MOZILLA_CLIENT" && test "$OS_ARCH" = "WINNT"; then
+    OS_TARGET=WIN95
+    if test -n "$MOZ_DEBUG"; then
+        USE_DEBUG_RTL=1
+    fi
+fi
+if test -z "$OS_TARGET"; then
+    OS_TARGET=$OS_ARCH
+fi
+if test "$OS_TARGET" = "WIN95"; then
+    OS_RELEASE="4.0"
+fi
+OS_CONFIG="${OS_TARGET}${OS_RELEASE}"
+
+# Check whether --enable-os2-high-mem or --disable-os2-high-mem was given.
+if test "${enable_os2_high_mem+set}" = set; then
+  enableval="$enable_os2_high_mem"
+   if test "$enableval" = "no"; then
+        MOZ_OS2_HIGH_MEMORY=
+      else
+        MOZ_OS2_HIGH_MEMORY=1
+      fi 
+fi
+
+
+# Check whether --enable-thumb2 or --disable-thumb2 was given.
+if test "${enable_thumb2+set}" = set; then
+  enableval="$enable_thumb2"
+   if test "$enableval" = "yes"; then
+     MOZ_THUMB2=1,
+   fi 
+fi
+
+
+if test -n "$MOZ_THUMB2"; then
+  case "$target_cpu" in
+    arm*)
+      if test "$GNU_CC"; then
+        CFLAGS="$CFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
+        CXXFLAGS="$CXXFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
+        ASFLAGS="$ASFLAGS -march=armv7-a -mthumb"
+      else
+        { echo "configure: error: --enable-thumb2 is not supported for non-GNU toolchains" 1>&2; exit 1; }
+      fi
+    ;;
+    *)
+      { echo "configure: error: --enable-thumb2 is not supported for non-ARM CPU architectures" 1>&2; exit 1; }
+    ;;
+  esac
+fi
+
+case "$host" in
+*-mingw*)
+    NSINSTALL=nsinstall
+    ;;
+*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*)
+    NSINSTALL='$(CYGWIN_WRAPPER) nsinstall'
+    if test `echo "${PATH}" | grep -c \;` = 0; then
+        CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper'
+    fi
+    ;;
+*-beos*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE"
+    ;;
+*os2*)
+    ;;
+*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX"
+    ;;
+esac
+
+case "$target" in
+
+*-aix*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define AIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib'
+    ac_safe=`echo "sys/atomic_op.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/atomic_op.h""... $ac_c" 1>&6
+echo "configure:3153: checking for sys/atomic_op.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3158 "configure"
+#include "confdefs.h"
+#include <sys/atomic_op.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3163: \"$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
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define AIX_HAVE_ATOMIC_OP_H 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    case "${target_os}" in
+    aix3.2*)
+        cat >> confdefs.h <<\EOF
+#define AIX_RENAME_SELECT 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        AIX_LINK_OPTS='-bnso -berok'
+        PR_MD_ASFILES=os_AIX.s
+        ;;
+    aix4.1*)
+        cat >> confdefs.h <<\EOF
+#define AIX_TIMERS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define AIX4_1 1
+EOF
+
+        MKSHLIB=
+        DSO_LDOPTS=
+        AIX_LINK_OPTS='-bnso -berok'
+        LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)_shr'
+        LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)_shr'
+        ;;
+    aix4.2*)
+        cat >> confdefs.h <<\EOF
+#define AIX_TIMERS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    aix4.3*)
+        cat >> confdefs.h <<\EOF
+#define AIX_TIMERS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define AIX4_3_PLUS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+        USE_IPV6=1
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    *)
+        cat >> confdefs.h <<\EOF
+#define AIX_TIMERS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define AIX4_3_PLUS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+        USE_IPV6=1
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    esac
+    CFLAGS="$CFLAGS -qro -qroconst"
+    AIX_WRAP='$(DIST)/lib/aixwrap.o'
+    AIX_TMP='./_aix_tmp.o'
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_aix64.cfg
+        OBJECT_MODE=64
+    else
+        MDCPUCFG_H=_aix32.cfg
+    fi
+    PR_MD_CSRCS=aix.c
+    RESOLVE_LINK_SYMBOLS=1
+    ;;
+        
+*-beos*)
+    cat >> confdefs.h <<\EOF
+#define XP_BEOS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define BeOS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define BEOS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+    DSO_LDOPTS=-nostart
+    MDCPUCFG_H=_beos.cfg
+    USE_BTHREADS=1
+    PR_MD_ARCH_DIR=beos
+    RESOLVE_LINK_SYMBOLS=1
+    case "${target_cpu}" in
+    i*86)
+        _OPTIMIZE_FLAGS=-O2
+        _DEBUG_FLAGS='-gdwarf-2 -O0'
+        MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@'
+        echo $ac_n "checking for gethostbyaddr in -lbind""... $ac_c" 1>&6
+echo "configure:3320: checking for gethostbyaddr in -lbind" >&5
+ac_lib_var=`echo bind'_'gethostbyaddr | 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="-lbind  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3328 "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 gethostbyaddr();
+
+int main() {
+gethostbyaddr()
+; return 0; }
+EOF
+if { (eval echo configure:3339: \"$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
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  OS_LIBS="$OS_LIBS -lbind -lsocket"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+        ;;
+    powerpc)
+        CC=mwcc
+        CCC=mwcc
+        LD=mwld
+        DSO_LDOPTS='-xms -export pragma -init _init_routine_ -term _term_routine_ -lroot -lnet /boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o /boot/develop/lib/ppc/start_dyn.o'
+        _OPTIMIZE_FLAGS=-O2    
+        _DEBUG_FLAGS='-g -O0'
+        ;;
+    esac
+    ;;
+
+*-bsdi*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define BSDI 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NEED_BSDREGEX 1
+EOF
+
+
+    CFLAGS="$CFLAGS -Wall -Wno-format"
+    CXXFLAGS="$CXXFLAGS -Wall -Wno-format"
+
+    if echo "$OS_TEST" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    elif echo "$OS_TEST" | grep -c sparc >/dev/null; then 
+        CPU_ARCH=sparc
+    fi
+
+    MDCPUCFG_H=_bsdi.cfg
+    PR_MD_CSRCS=bsdi.c
+
+    DSO_LDOPTS=-r
+
+    case "$target_os" in
+    bsdi1.1*)
+        cat >> confdefs.h <<\EOF
+#define _PR_BSDI_JMPBUF_IS_ARRAY 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ONLY_ST_ATIME 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+        MKSHLIB=
+        DSO_CFLAGS=
+        DSO_LDOPTS=
+        ;;
+
+    bsdi2.1*)
+        cat >> confdefs.h <<\EOF
+#define _PR_TIMESPEC_HAS_TS_SEC 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_BSDI_JMPBUF_IS_ARRAY 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_DLL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define USE_DLFCN 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIMESPEC 1
+EOF
+
+        PR_MD_ASFILES=os_BSD_OS_386_2.s
+        ;;
+
+    bsdi4.* | bsdi5.*)
+        cat >> confdefs.h <<\EOF
+#define _PR_SELECT_CONST_TIMEVAL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_BSDI_JMPBUF_IS_STRUCT 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_DLL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define USE_DLFCN 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIMESPEC 1
+EOF
+
+        MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)'
+        DSO_CFLAGS=-fPIC
+        DSO_LDOPTS='-shared -Wl,-soname,$(@:$(OBJDIR)/%.so=%.so)'
+        STRIP="$STRIP -d"
+        case "$target_os" in
+        bsdi4.2* | bsdi4.3* | bsdi5.*)
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETPROTO_R 1
+EOF
+
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETPROTO_R_POINTER 1
+EOF
+
+            ;;
+        esac
+        ;;
+    *)
+        cat >> confdefs.h <<\EOF
+#define _PR_SELECT_CONST_TIMEVAL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_BSDI_JMPBUF_IS_STRUCT 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_DLL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define USE_DLFCN 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIMESPEC 1
+EOF
+
+        ;;
+    esac
+
+    ;;
+
+*-darwin*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define DARWIN 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+    AS='$(CC) -x assembler-with-cpp'
+    CFLAGS="$CFLAGS -Wall -fno-common"
+    case "${target_cpu}" in
+        i*86*)
+            if test -n "$USE_64"; then
+                CPU_ARCH=x86_64
+                CC="$CC -arch x86_64"
+            else        
+                CPU_ARCH=i386
+            fi
+            ;;
+        *)
+            CPU_ARCH=ppc
+            ;;
+    esac
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names'
+    _OPTIMIZE_FLAGS=-O2
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    STRIP="$STRIP -x -S"
+    DLL_SUFFIX=dylib
+    USE_PTHREADS=1
+    MDCPUCFG_H=_darwin.cfg
+    PR_MD_CSRCS=darwin.c
+    PR_MD_ASFILES=os_Darwin.s
+
+    # Add Mac OS X support for loading CFM & CFBundle plugins
+    if test -f "${MACOS_SDK_DIR}/System/Library/Frameworks/Carbon.framework/Carbon"; then
+        cat >> confdefs.h <<\EOF
+#define XP_MACOSX 1
+EOF
+
+        OS_TARGET=MacOSX
+
+        if test -n "$_MACOSX_DEPLOYMENT_TARGET" ; then
+                        export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET
+        elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then
+                                                case "${target_cpu}" in
+                powerpc*)
+                                        export MACOSX_DEPLOYMENT_TARGET=10.2
+                    ;;
+                i*86*)
+                                        export MACOSX_DEPLOYMENT_TARGET=10.4
+                    ;;
+            esac
+        fi
+
+                        
+        if test "$MACOS_SDK_DIR"; then
+            
+            if test ! -d "$MACOS_SDK_DIR"; then
+                { echo "configure: error: SDK not found.  When using --with-macos-sdk, you must
+specify a valid SDK.  SDKs are installed when the optional cross-development
+tools are selected during the Xcode/Developer Tools installation." 1>&2; exit 1; }
+            fi
+
+            
+            CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'`
+            GCC_VERSION_FULL=`echo $CC_VERSION | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'`
+            GCC_VERSION=`echo $GCC_VERSION_FULL | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'`
+            
+            GCC_VERSION_MAJOR=`echo $GCC_VERSION_FULL | $PERL -pe 's/(^\d*).*/$1/;'`
+            if test "$GCC_VERSION_MAJOR" -lt "4" ; then
+                SDK_C_FRAMEWORK="-F${MACOS_SDK_DIR}/System/Library/Frameworks"
+                if test -d "${MACOS_SDK_DIR}/Library/Frameworks" ; then
+                    SDK_C_FRAMEWORK="$SDK_C_FRAMEWORK -F${MACOS_SDK_DIR}/Library/Frameworks"
+                fi
+
+                SDK_C_INCLUDE="-isystem ${MACOS_SDK_DIR}/usr/include/gcc/darwin/${GCC_VERSION} -isystem ${MACOS_SDK_DIR}/usr/include ${SDK_C_FRAMEWORK}"
+
+                CFLAGS="$CFLAGS -nostdinc ${SDK_C_INCLUDE}"
+
+                                CPP="$CPP -nostdinc ${SDK_C_INCLUDE}"
+
+                
+                HOST_DARWIN_MAJOR=`echo "$build_os" | sed -E -e 's/^darwin([0-9]+).*$/\1/'`
+                
+                if test "$HOST_DARWIN_MAJOR" -lt 9 ; then
+                                                                                                                        MACOS_SDK_LIBS="-L${MACOS_SDK_DIR}/usr/lib/gcc/darwin -L${MACOS_SDK_DIR}/usr/lib/gcc/darwin/${GCC_VERSION_FULL} -L${MACOS_SDK_DIR}/usr/lib ${SDK_C_FRAMEWORK}"
+                else
+                                                                                                                                                                                                        MACOS_SDK_LIBS="-Wl,-syslibroot,${MACOS_SDK_DIR}"
+                fi
+
+                LDFLAGS="${MACOS_SDK_LIBS} $LDFLAGS"
+                export NEXT_ROOT=$MACOS_SDK_DIR
+
+                if test -n "$CROSS_COMPILE" ; then
+                                                                                HOST_CC="NEXT_ROOT= $HOST_CC"
+                    HOST_CXX="NEXT_ROOT= $HOST_CXX"
+                fi
+            else
+                                                CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}"
+
+                                CPP="$CPP -isysroot ${MACOS_SDK_DIR}"
+
+                                                                                if test "$GCC_VERSION_FULL" != "4.0.0" ; then
+                                                            LDFLAGS="$LDFLAGS -isysroot ${MACOS_SDK_DIR}"
+                else
+                                                            LDFLAGS="$LDFLAGS -Wl,-syslibroot,${MACOS_SDK_DIR}"
+                fi
+            fi
+        fi
+    fi
+    ;;
+
+*-dgux*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define DGUX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _DGUX_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _POSIX4A_DRAFT6_SOURCE 1
+EOF
+
+    DSO_LDOPTS=-G
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS=
+    MDCPUCFG_H=_dgux.cfg
+    PR_MD_CSRCS=dgux.c
+    ;;
+
+*-freebsd*)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define FREEBSD 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+    CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall"
+    MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf`
+    if test "$MOZ_OBJFORMAT" = "elf"; then
+        DLL_SUFFIX=so
+    else
+        DLL_SUFFIX=so.1.0
+    fi
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    MDCPUCFG_H=_freebsd.cfg
+    PR_MD_CSRCS=freebsd.c
+    ;;
+
+*-hpux*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HPUX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _HPUX_SOURCE 1
+EOF
+
+    # OSF1 and HPUX report the POLLHUP event for a socket when the
+    # shutdown(SHUT_WR) operation is called for the remote end, even though
+    # the socket is still writeable. Use select(), instead of poll(), to
+    # workaround this problem.
+    cat >> confdefs.h <<\EOF
+#define _PR_POLL_WITH_SELECT 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _USE_BIG_FDS 1
+EOF
+
+    DSO_LDOPTS='-b +h $(notdir $@)'
+    PR_MD_CSRCS=hpux.c
+    if test "$OS_TEST" = "ia64"; then
+        DLL_SUFFIX=so
+        DSO_LDOPTS="$DSO_LDOPTS +b '\$\$ORIGIN'"
+        CPU_ARCH_TAG=_$OS_TEST 
+        if test -z "$USE_64"; then
+            COMPILER_TAG=_32
+        fi
+        PR_MD_ASFILES=os_HPUX_ia64.s
+    else
+        cat >> confdefs.h <<\EOF
+#define hppa 1
+EOF
+
+        DLL_SUFFIX=sl
+        PR_MD_ASFILES=os_HPUX.s
+    fi
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_hpux64.cfg
+    else
+        MDCPUCFG_H=_hpux32.cfg
+    fi
+    if test -z "$GNU_CC"; then
+        CC="$CC -Ae"
+        CXX="$CXX -ext"
+        DSO_CFLAGS=+Z
+    else
+        DSO_CFLAGS=-fPIC
+        ASFLAGS="$ASFLAGS -x assembler-with-cpp"
+    fi
+
+    if test -n "$MOZILLA_CLIENT"; then
+        DEFAULT_IMPL_STRATEGY=_EMU
+    fi
+
+    if echo "$OS_RELEASE" | grep ^A.09 >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX9 1
+EOF
+
+        DEFAULT_IMPL_STRATEGY=_EMU
+    	USE_NSPR_THREADS=1
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(A.09|B.10)' >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_INT_LOCALTIME_R 1
+EOF
+
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.30|B.11)' >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+    fi
+
+    # HP-UX 11i v2 (B.11.23) or higher
+    
+    case "$OS_RELEASE" in
+    [C-Z]*|B.[2-9]*|B.1[2-9]*|B.11.[3-9]*|B.11.2[3-9]*)
+        USE_IPV6=1
+        ;;
+    esac
+    
+
+    if test "$OS_RELEASE" = "B.10.01"; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        DEFAULT_IMPL_STRATEGY=_EMU
+    fi
+
+    if test "$OS_RELEASE" = "B.10.10"; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX10_10 1
+EOF
+
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$OS_RELEASE" = "B.10.20"; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX10_20 1
+EOF
+
+        if test -z "$GNU_CC"; then
+            CFLAGS="$CFLAGS +DAportable +DS1.1"
+            CXXFLAGS="$CXXFLAGS +DAportable +DS1.1"
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$OS_RELEASE" = "B.10.30"; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX10_30 1
+EOF
+
+        if test -z "$GNU_CC"; then
+            CFLAGS="$CFLAGS +DAportable +DS1.1"
+            CXXFLAGS="$CXXFLAGS +DAportable +DS1.1"
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if echo "$OS_RELEASE" | grep ^B.11 >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX11 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _LARGEFILE64_SOURCE 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+        if test -z "$GNU_CC"; then
+            if test -z "$USE_64"; then
+                if test "$OS_TEST" = "ia64"; then
+                    CFLAGS="$CFLAGS +DD32"
+                    CXXFLAGS="$CXXFLAGS +DD32"
+                else
+                    CFLAGS="$CFLAGS +DAportable +DS2.0"
+                    CXXFLAGS="$CXXFLAGS +DAportable +DS2.0"
+                fi
+            else
+                if test "$OS_TEST" = "ia64"; then
+                    CFLAGS="$CFLAGS +DD64"
+                    CXXFLAGS="$CXXFLAGS +DD64"
+                else
+                    CFLAGS="$CFLAGS +DA2.0W +DS2.0"
+                    CXXFLAGS="$CXXFLAGS +DA2.0W +DS2.0"
+                fi
+            fi
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$DEFAULT_IMPL_STRATEGY" = "_EMU"; then
+        USE_NSPR_THREADS=1
+        USE_PTHREADS=
+        USE_USER_PTHREADS=
+    elif test "$DEFAULT_IMPL_STRATEGY" = "_PTH"; then
+        USE_PTHREADS=1
+        if test "$USE_NSPR_THREADS"; then
+            USE_PTHREADS=
+        fi
+        if test "$USE_USER_PTHREADS"; then
+            USE_PTHREADS=
+        fi
+    fi
+    ;;
+
+*-irix*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define IRIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _SGI_MP_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+    PR_MD_CSRCS=irix.c
+    PR_MD_ASFILES=os_Irix.s
+    MKSHLIB='$(LD) $(DSO_LDOPTS) -rdata_shared -shared -soname $(notdir $@) -o $@'
+    STRIP="$STRIP -f"
+    RESOLVE_LINK_SYMBOLS=1
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_irix64.cfg
+    else
+        MDCPUCFG_H=_irix32.cfg
+    fi
+    case "${target_os}" in
+    irix6*)
+        cat >> confdefs.h <<\EOF
+#define IRIX6 1
+EOF
+
+        USE_PTHREADS=1
+        USE_N32=1
+        COMPILER_TAG=_n32
+        IMPL_STRATEGY=_PTH
+        ;;
+    irix5*)
+        cat >> confdefs.h <<\EOF
+#define IRIX5 1
+EOF
+
+        USE_NSPR_THREADS=1
+        ;;
+    *)
+        USE_PTHREADS=1
+        USE_N32=1
+        ;;
+    esac
+    if test "$GNU_CC"; then
+                                                        	    AS='$(CC) -Wp,-P -x assembler-with-cpp -D_ASM -mips2 $(INCLUDES)'
+	    CFLAGS="$CFLAGS -Wall -Wno-format"
+	    _OPTIMIZE_FLAGS="-O6"
+    else
+	    if test -n "$USE_N32"; then
+		AS='as -D_ASM $(INCLUDES) -n32'
+	    else
+		AS='as -D_ASM $(INCLUDES)'
+	    fi
+	    CFLAGS="$CFLAGS -fullwarn -xansi"
+	    if test "$USE_N32"; then
+	        _OPTIMIZE_FLAGS="-O -OPT:Olimit=4000"
+	    else
+	        _OPTIMIZE_FLAGS="-O -Olimit 4000"
+	    fi
+	    if test "$USE_MDUPDATE"; then
+                CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+	    fi
+	    case "${target}" in
+	    *-irix6.*)
+	        CFLAGS="$CFLAGS -multigot"
+	        DSO_LDOPTS="-no_unresolved"
+	        if test "$USE_N32"; then
+		        CFLAGS="$CFLAGS -n32 -woff 1209"
+		        DSO_LDOPTS="$DSO_LDOPTS -n32"
+	        else
+		        if test "$USE_64"; then
+		            CFLAGS="$CFLAGS -64"
+		        else
+		            CFLAGS="$CFLAGS -32"
+		        fi
+	        fi
+	        ;;
+	    *)
+	        CFLAGS="$CFLAGS -xgot"
+	        ;;
+	    esac
+    fi
+    if test "${target_os}" = "irix5.3"; then
+	    cat >> confdefs.h <<\EOF
+#define IRIX5_3 1
+EOF
+
+    fi
+    case "${target_os}" in
+	irix6.5)
+	    if test -z "$GNU_CC"; then
+		    CFLAGS="$CFLAGS -mips3"
+	    fi
+	    cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETPROTO_R 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETPROTO_R_POINTER 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _PR_HAVE_SGI_PRDA_PROCMASK 1
+EOF
+
+	    ;;
+	irix5*)
+	    ;;
+	*)
+	    cat >> confdefs.h <<\EOF
+#define _PR_HAVE_SGI_PRDA_PROCMASK 1
+EOF
+
+	    ;;
+	esac
+    ;;
+
+arm-android-eabi)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+        IMPL_STRATEGY=_PTH
+    fi
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _GNU_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define LINUX 1
+EOF
+
+    CFLAGS="$CFLAGS -Wall"
+    CXXFLAGS="$CXXFLAGS -Wall"
+    MDCPUCFG_H=_linux.cfg
+    PR_MD_CSRCS=linux.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) $(WRAP_MALLOC_LIB) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS="-g -fno-inline"  # most people on linux use gcc/gdb, and that
+                                   # combo is not yet good at debugging inlined
+                                   # functions (even when using DWARF2 as the
+                                   # debugging format)
+    COMPILER_TAG=_glibc
+    CPU_ARCH=arm
+    CPU_ARCH_TAG=_arm
+    OS_TARGET=Android
+    ;;
+
+*-linux*|*-gnu*|*-k*bsd*-gnu)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+        IMPL_STRATEGY=_PTH
+    fi
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _GNU_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+    case "${target_os}" in
+    linux*)
+        cat >> confdefs.h <<\EOF
+#define LINUX 1
+EOF
+
+        ;;
+    esac
+    CFLAGS="$CFLAGS -Wall"
+    CXXFLAGS="$CXXFLAGS -Wall"
+    MDCPUCFG_H=_linux.cfg
+    PR_MD_CSRCS=linux.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) $(WRAP_MALLOC_LIB) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS="-g -fno-inline"  # most people on linux use gcc/gdb, and that
+                                   # combo is not yet good at debugging inlined
+                                   # functions (even when using DWARF2 as the
+                                   # debugging format)
+    COMPILER_TAG=_glibc
+    if echo "$OS_TEST" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    else
+        CPU_ARCH=$OS_TEST
+    fi
+    CPU_ARCH_TAG=_${CPU_ARCH}
+    case "${target_cpu}" in
+    alpha)
+        cat >> confdefs.h <<\EOF
+#define _ALPHA_ 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define __alpha 1
+EOF
+
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+        ;;
+    i*86)
+        cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+        PR_MD_ASFILES=os_Linux_x86.s
+        ;;
+    ia64)
+        PR_MD_ASFILES=os_Linux_ia64.s
+        ;;
+    x86_64)
+        if test -n "$USE_64"; then
+            PR_MD_ASFILES=os_Linux_x86_64.s
+        else
+            cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+            PR_MD_ASFILES=os_Linux_x86.s
+            CC="$CC -m32"
+            CXX="$CXX -m32"
+        fi
+        ;;
+    ppc|powerpc)
+        PR_MD_ASFILES=os_Linux_ppc.s
+        ;;
+    powerpc64)
+        if test -n "$USE_64"; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        else
+            PR_MD_ASFILES=os_Linux_ppc.s
+        fi
+        ;;
+    m68k)
+        CFLAGS="$CFLAGS -m68020-60"
+        CXXFLAGS="$CXXFLAGS -m68020-60"
+        ;;
+    esac    
+    ;;
+
+*-mingw*|*-cygwin*|*-msvc*|*-mks*)
+    cat >> confdefs.h <<\EOF
+#define XP_PC 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define WIN32 1
+EOF
+
+    PR_MD_ARCH_DIR=windows
+    RESOLVE_LINK_SYMBOLS=1
+
+    if test -n "$GNU_CC"; then
+        CC="$CC -mno-cygwin"
+        CXX="$CXX -mno-cygwin"
+        DLL_SUFFIX=dll
+        MKSHLIB='$(CC) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(IMPORT_LIBRARY) $(DLLBASE) -o $(subst $(OBJDIR)/,,$(SHARED_LIBRARY))'
+        RC=$WINDRES
+        # Use temp file for windres (bug 213281)
+        RCFLAGS='-O coff --use-temp-file'
+    else
+        CC=cl
+        CXX=cl
+        LD=link
+        AR='lib -NOLOGO -OUT:"$@"'
+        AR_FLAGS=
+        RANLIB='echo not_ranlib'
+        STRIP='echo not_strip'
+        RC=rc.exe
+        GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb'
+        OBJ_SUFFIX=obj
+        LIB_SUFFIX=lib
+        DLL_SUFFIX=dll
+
+        # Determine compiler version
+        
+        _MSVC_VER_FILTER='s|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p'
+        
+        CC_VERSION=`"${CC}" -v 2>&1 | sed -ne "$_MSVC_VER_FILTER"`
+        _CC_MAJOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $1 }'`
+        _CC_MINOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $2 }'`
+        _CC_RELEASE=`echo ${CC_VERSION} | awk -F\. '{ print $3 }'`
+        _CC_BUILD=`echo ${CC_VERSION} | awk -F\. '{ print $4 }'`
+        MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION}
+
+        if test "$_CC_MAJOR_VERSION" -eq "14"; then
+                                            if test $_CC_RELEASE -gt 50727; then
+              _USE_DYNAMICBASE=1
+           elif test $_CC_BUILD -ge 762; then
+              _USE_DYNAMICBASE=1
+           fi
+        elif test $_CC_MAJOR_VERSION -ge 15; then
+           _USE_DYNAMICBASE=1    
+        fi
+
+        if test -n "$_USE_DYNAMICBASE"; then
+           DLLFLAGS="$DLLFLAGS -DYNAMICBASE"
+        fi
+
+        # Ensure that mt is Microsoft (R) Manifest Tool and not magnetic
+        # tape manipulation utility (or something else)
+        if test "$MSC_VER" -ge "1400"; then
+            
+            _MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
+            
+
+            MSMT_TOOL=`mt 2>&1|grep 'Microsoft (R) Manifest Tool'`
+            if test -n "$MSMT_TOOL"; then
+                MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
+                if test -z "$MSMANIFEST_TOOL_VERSION"; then
+                    echo "configure: warning: Unknown version of the Microsoft (R) Manifest Tool." 1>&2
+                fi
+                MT=mt
+                unset MSMT_TOOL
+            else
+                { echo "configure: error: Microsoft (R) Manifest Tool must be in your \$PATH." 1>&2; exit 1; }
+            fi
+        fi
+        
+        CFLAGS="$CFLAGS -W3 -nologo -GF -Gy"
+        DLLFLAGS="$DLLFLAGS -OUT:\"\$@\""
+        _DEBUG_FLAGS=-Zi
+        _OPTIMIZE_FLAGS=-O2
+
+        PROFILE_GEN_CFLAGS="-GL"
+        PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT"
+        PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952"
+        PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE"
+
+        if test -z "$MOZ_OPTIMIZE"; then
+            CFLAGS="$CFLAGS -Od"
+        fi
+
+        if test -n "$USE_DEBUG_RTL"; then
+            CFLAGS="$CFLAGS -MDd"
+        else
+            CFLAGS="$CFLAGS -MD"
+        fi
+
+        if test -n "$MOZ_DEBUG"; then
+            cat >> confdefs.h <<\EOF
+#define _DEBUG 1
+EOF
+
+        else
+            DEFINES="$DEFINES -U_DEBUG"
+        fi
+
+        if test -n "$MOZ_DEBUG_SYMBOLS"; then
+            if test -n "$MOZ_OPTIMIZE"; then
+                DLLFLAGS="$DLLFLAGS -DEBUG -OPT:REF"
+                LDFLAGS="$LDFLAGS -DEBUG -OPT:REF"
+            else
+                DLLFLAGS="$DLLFLAGS -DEBUG"
+                LDFLAGS="$LDFLAGS -DEBUG"
+            fi
+        fi
+
+        OS_DLLFLAGS="-nologo -DLL -SUBSYSTEM:WINDOWS"
+        if test "$MSC_VER" -le "1200" -a -z "$MOZ_DEBUG_SYMBOLS"; then
+            OS_DLLFLAGS="$OS_DLLFLAGS -PDB:NONE"
+        fi
+        
+        if test "$OS_TARGET" = "WINNT"; then
+            CFLAGS="$CFLAGS -GT"
+            LIBNSPR='$(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+            LIBPLC='$(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        else
+            LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+            LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        fi
+    fi # GNU_CC
+
+    if test -n "$USE_STATIC_TLS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_USE_STATIC_TLS 1
+EOF
+
+    fi
+
+    if test "$OS_TARGET" = "WINNT"; then
+        cat >> confdefs.h <<\EOF
+#define WINNT 1
+EOF
+
+    else
+        cat >> confdefs.h <<\EOF
+#define WIN95 1
+EOF
+
+        # undefine WINNT as some versions of mingw gcc define it by default
+        DEFINES="$DEFINES -UWINNT"
+        cat >> confdefs.h <<\EOF
+#define _PR_GLOBAL_THREADS_ONLY 1
+EOF
+
+    fi
+
+    if test "$CPU_ARCH" = "x86"; then
+        CPU_ARCH_TAG=
+    else
+        CPU_ARCH_TAG=$CPU_ARCH
+    fi
+
+    if test -n "$USE_DEBUG_RTL"; then
+        OBJDIR_SUFFIX=OBJD
+    fi
+
+    case "$OS_TARGET" in
+    WINNT)
+	    MDCPUCFG_H=_winnt.cfg
+	    ;;
+    WIN95)
+	    MDCPUCFG_H=_win95.cfg
+	    ;;
+    *)
+	    { echo "configure: error: Missing OS_TARGET for ${target}.  Use --enable-win32-target to set." 1>&2; exit 1; }
+   	;;
+    esac
+
+    case "$target_cpu" in
+    i*86)
+	if test -n "$USE_64"; then
+	    cat >> confdefs.h <<\EOF
+#define _AMD64_ 1
+EOF
+
+	else		
+	    cat >> confdefs.h <<\EOF
+#define _X86_ 1
+EOF
+
+	fi
+        ;;
+    x86_64)
+	    cat >> confdefs.h <<\EOF
+#define _AMD64_ 1
+EOF
+
+	    USE_64=1
+	    ;;
+    ia64)
+	    cat >> confdefs.h <<\EOF
+#define _IA64_ 1
+EOF
+
+	    USE_64=1
+	    ;;
+    *)
+	    cat >> confdefs.h <<\EOF
+#define _CPU_ARCH_NOT_DEFINED 1
+EOF
+
+	    ;;
+    esac
+    ;;
+
+*-wince*|*-winmo*)
+    cat >> confdefs.h <<\EOF
+#define XP_PC 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define WIN32 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define WINCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_GLOBAL_THREADS_ONLY 1
+EOF
+
+
+    AR_FLAGS='-NOLOGO -OUT:"$@"'
+
+    OBJ_SUFFIX=obj
+    LIB_SUFFIX=lib
+    DLL_SUFFIX=dll
+    MKSHLIB='$(LD) -DLL $(DSO_LDOPTS) -OUT:$@'
+
+    PR_MD_ARCH_DIR=windows
+    RESOLVE_LINK_SYMBOLS=1
+
+    MDCPUCFG_H=_win95.cfg
+    LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+    LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+
+    DLLFLAGS='-OUT:"$@"'
+    if test -n "$MOZ_DEBUG_SYMBOLS"; then
+        OS_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
+        OS_DLLFLAGS='-DEBUG -DEBUGTYPE:CV'
+        DSO_LDOPTS='-DEBUG -DEBUGTYPE:CV'
+    fi
+    _DEBUG_FLAGS=-Zi
+    _OPTIMIZE_FLAGS=-O2
+    ;;
+
+*-ncr-sysv*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NCR 1
+EOF
+
+    USE_NSPR_THREADS=1
+    if test "$OS_RELEASE" = "2.03"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIM 1
+EOF
+
+    else
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIM_UNION 1
+EOF
+
+    fi
+
+    if test -z "$GNU_CC"; then
+        CFLAGS="$CFLAGS -Hnocopyr"
+        CXXFLAGS="$CXXFLAGS -Hnocopyr"
+    else
+        CFLAGS="$CFLAGS -fPIC -Wall"
+        CXXFLAGS="$CXXFLAGS -fPIC -Wall"
+        DSO_LDOPTS=-G
+    fi
+    MDCPUCFG_H=_ncr.cfg
+    PR_MD_CSRCS=ncr.c
+    ;;
+
+mips-nec-sysv*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NEC 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define nec_ews 1
+EOF
+
+    USE_NSPR_THREADS=1
+    if test -z "$GNU_CC"; then
+        CC='$(NSDEPTH)/build/hcc cc -Xa -KGnum=0 -KOlimit=4000'
+        CXX=g++
+    fi
+    OS_LIBS="$OS_LIBS -lsocket -lnsl -ldl"
+    DSO_LDOPTS=-G
+    MDCPUCFG_H=_nec.cfg
+    PR_MD_CSRCS=nec.c
+    ;;
+
+*-netbsd*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NETBSD 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    MDCPUCFG_H=_netbsd.cfg
+    PR_MD_CSRCS=netbsd.c
+
+    DSO_CFLAGS='-fPIC -DPIC'
+    CFLAGS="$CFLAGS -ansi -Wall"
+    CXXFLAGS="$CXXFLAGS -ansi -Wall"
+    MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)'
+
+    if test -z "$OBJECT_FMT"; then
+        if echo __ELF__ | ${CC-cc} -E - | grep -q __ELF__ 2>/dev/null; then
+            OBJECT_FMT=a.out
+            DLL_SUFFIX=so.1.0
+            DSO_LDOPTS='-shared'
+        else
+            OBJECT_FMT=ELF
+            DLL_SUFFIX=so
+            DSO_LDOPTS='-shared -Wl,-soname,$(notdir $@)'
+        fi
+    fi
+
+    if test "$LIBRUNPATH"; then
+        DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH"
+    fi
+    ;;
+
+mips-sony-newsos*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SONY 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __svr4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __svr4__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SVID_GETTOD 1
+EOF
+
+    USE_NSPR_THREADS=1
+    CFLAGS="$CFLAGS -Xa -fullwarn"
+    CXXFLAGS="$CXXFLAGS -Xa -fullwarn"
+    DSO_LDOPTS=-G
+    MDCPUCFG_H=_sony.cfg
+    PR_MD_CSRCS=sony.c
+    ;;
+
+*-nextstep*|*-openstep*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NEXTSTEP 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+    CFLAGS="$CFLAGS -Wall -fno-common -traditional-cpp -posix"
+    CXXFLAGS="$CXXFLAGS -Wall -fno-common -traditional-cpp -posix"
+    USE_NSPR_THREADS=1
+    DLL_SUFFIX=dylib
+    MDCPUCFG_H=_nextstep.cfg
+    PR_MD_CSRCS=nextstep.c
+    ;;
+
+
+*-nto*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NTO 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _QNX_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+    MDCPUCFG_H=_nto.cfg
+    PR_MD_CSRCS=nto.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(notdir $@) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS=-shared
+    OS_LIBS="$OS_LIBS -lsocket"
+    _OPTIMIZE_FLAGS="-O1"
+    _DEBUG_FLAGS="-gstabs"
+	;;
+
+*-openbsd*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define OPENBSD 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+    CFLAGS="$CFLAGS -ansi -Wall"
+    CXXFLAGS="$CXXFLAGS -ansi -Wall"
+    DLL_SUFFIX=so.1.0
+    DSO_CFLAGS=-fPIC
+    MDCPUCFG_H=_openbsd.cfg
+    PR_MD_CSRCS=openbsd.c
+    OS_LIBS="-lc"
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    DSO_LDOPTS='-shared -fPIC'
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    ;;
+
+*-osf*)
+    SHELL_OVERRIDE="SHELL		= /usr/bin/ksh"
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define OSF1 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+    # OSF1 and HPUX report the POLLHUP event for a socket when the
+    # shutdown(SHUT_WR) operation is called for the remote end, even though
+    # the socket is still writeable. Use select(), instead of poll(), to
+    # workaround this problem.
+    cat >> confdefs.h <<\EOF
+#define _PR_POLL_WITH_SELECT 1
+EOF
+
+
+    if echo "$OS_RELEASE" | egrep -c '(V2.0|V3.2)' 2>/dev/null ; then
+        USE_NSPR_THREADS=1
+    fi
+
+    if test -z "$GNU_CC"; then
+        CC="$CC -std1 -ieee_with_inexact"
+        if test "$OS_RELEASE" != "V2.0"; then
+            CC="$CC -readonly_strings"
+        fi
+        _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000"
+        ac_safe=`echo "machine/builtins.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for machine/builtins.h""... $ac_c" 1>&6
+echo "configure:4714: checking for machine/builtins.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4719 "configure"
+#include "confdefs.h"
+#include <machine/builtins.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4724: \"$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
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define OSF1_HAVE_MACHINE_BUILTINS_H 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    else
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+    fi
+
+    if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_INT_LOCALTIME_R 1
+EOF
+
+    else
+        cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+    fi
+    if echo $OS_RELEASE | grep -c V4.0 >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define OSF1V4_MAP_PRIVATE_BUG 1
+EOF
+
+    fi
+    DSO_LDOPTS='-shared -all -expect_unresolved "*" -soname $(notdir $@)'
+    MDCPUCFG_H=_osf1.cfg
+    PR_MD_CSRCS=osf1.c
+    ;;
+
+*-qnx*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define QNX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_qnx.cfg
+    PR_MD_CSRCS=qnx.c
+    ;;
+
+*-riscos*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define RISCOS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+    USE_PTHREADS=1
+    MDCPUCFG_H=_riscos.cfg
+    PR_MD_CSRCS=riscos.c
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    ;;
+
+*-*-sco*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SCO 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define sco 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _SVID3 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+    CC='cc -b elf -KPIC'
+    CXX='$(NSDEPTH)/build/hcpp CC +.cpp +w'
+    USE_NSPR_THREADS=1
+    CPU_ARCH=x86
+    DSO_LDOPTS='-b elf -G'
+    MDCPUCFG_H=_scoos.cfg
+    PR_MD_SRCS=scoos.c
+    ;;
+
+*-sinix*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SNI 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define RELIANTUNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define sinix 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SVID_GETTOD 1
+EOF
+
+    if echo "$OS_TEST" | grep -c 86 2>/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+        CPU_ARCH=x86
+    else
+        CPU_ARCH=mips
+    fi
+
+    if test "$GNU_CC"; then
+        AS='$(CC) -x assembler-with-cpp'
+        if test "$CPU_ARCH" = "mips"; then
+            LD=gld
+        fi
+        CFLAGS="$CFLAGS -Wall -Wno-format"
+    else
+        AS='/usr/bin/cc'
+        _OPTIMIZE_FLAGS='-O -F Olimit,4000'
+    fi
+
+    DSO_LDOPTS='-G -z defs -h $(@:$(OBJDIR)/%.so=%.so)'
+
+    if test "$OS_RELEASE" = "5.43"; then
+        cat >> confdefs.h <<\EOF
+#define IP_MULTICAST 1
+EOF
+
+    fi
+
+    OS_LIBS="$OS_LIBS -lsocket -lnsl -lresolv -ldl -lc"
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_reliantunix.cfg
+    PR_MD_CSRCS=reliantunix.c
+    if test "${OS_ARCH}" = "mips"; then
+        PR_MD_ASFILES=os_ReliantUNIX.s
+    fi
+    ;;
+
+*-sunos*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SUNOS4 1
+EOF
+
+    CFLAGS="$CFLAGS -Wall -Wno-format"
+    if test "$USE_MDUPDATE"; then
+        CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+    fi
+    CPU_ARCH=sparc
+    DLL_SUFFIX=so.1.0
+    DSO_LDOPTS=
+    DSO_CFLAGS=-fPIC
+    USE_NSPR_THREADS=1
+    if test "$OS_RELEASE" = "4.1.3_U1"; then
+        _OPTIMIZE_FLAGS=
+        OS_LIBS="$OS_LIBS -lm"
+    fi
+    MDCPUCFG_H=_sunos4.cfg
+    PR_MD_CSRCS=sunos4.c
+    ;;
+
+*-solaris*)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __svr4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __svr4__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SOLARIS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+    CPU_ARCH=`uname -p`
+    MDCPUCFG_H=_solaris.cfg
+    PR_MD_CSRCS=solaris.c
+    LD=/usr/ccs/bin/ld
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    RESOLVE_LINK_SYMBOLS=1
+    case "${OS_RELEASE}" in
+    5.8|5.9)
+        ;;
+    *)
+        # It is safe to use the -Bdirect linker flag on Solaris 10 or later.
+        USE_B_DIRECT=1
+        ;;
+    esac
+    if test -n "$GNU_CC"; then
+        DSO_CFLAGS=-fPIC
+        if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
+            GCC_USE_GNU_LD=1
+        fi
+        DSO_LDOPTS='-shared -Wl,-h,$(notdir $@),-z,combreloc,-z,defs,-z,ignore' 
+        if test -n "$USE_B_DIRECT"; then
+            DSO_LDOPTS="$DSO_LDOPTS,-Bdirect"
+        fi
+    else
+        DSO_CFLAGS=-KPIC
+        DSO_LDOPTS='-G -h $(notdir $@) -z combreloc -z defs -z ignore'
+        if test -n "$USE_B_DIRECT"; then
+            DSO_LDOPTS="$DSO_LDOPTS -Bdirect"
+        fi
+    fi
+    if test -n "$GNU_CC"; then
+        CFLAGS="$CFLAGS -Wall"
+        CXXFLAGS="$CXXFLAGS -Wall"
+        if test -n "$USE_MDUPDATE"; then
+            CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+            CXXFLAGS="$CXXFLAGS -MDupdate \$(DEPENDENCIES)"
+        fi
+        GCC_AS=`$CC -print-prog-name=as`
+        if test "`echo | $GCC_AS -v 2>&1 | grep -c GNU`" != "0"; then
+            GNU_AS=1
+        fi
+    else
+        CFLAGS="$CFLAGS -xstrconst"
+        CXXFLAGS="$CXXFLAGS -Qoption cg -xstrconst -features=tmplife"
+        if test -z "$MOZ_OPTIMIZE"; then
+            CFLAGS="$CFLAGS -xs"
+            CXXFLAGS="$CXXFLAGS -xs"
+        fi
+        _OPTIMIZE_FLAGS=-xO4
+    fi
+    if test -z "$GNU_AS"; then
+        ASFLAGS="$ASFLAGS -Wa,-P"
+    fi
+    if test -n "$USE_64"; then
+        if test -n "$GNU_CC"; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        else
+            if test "$OS_TEST" = "i86pc"; then
+                CC="$CC -xarch=amd64"
+                CXX="$CXX -xarch=amd64"
+            else
+                CC="$CC -xarch=v9"
+                CXX="$CXX -xarch=v9"
+            fi
+        fi
+    fi
+    if test "$OS_TEST" = "i86pc"; then
+        if test -z "$USE_64"; then
+            cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+        fi
+        CPU_ARCH_TAG=_$OS_TEST
+        # The default debug format, DWARF (-g), is not supported by gcc
+        # on i386-ANY-sysv4/solaris, but the stabs format is.  It is
+        # assumed that the Solaris assembler /usr/ccs/bin/as is used.
+        # If your gcc uses GNU as, you do not need the -Wa,-s option.
+        if test -n "$MOZ_DEBUG" && test -n "$GNU_CC"; then
+            _DEBUG_FLAGS=-gstabs
+            if test -z "$GNU_AS"; then
+                _DEBUG_FLAGS="$_DEBUG_FLAGS -Wa,-s"
+            fi
+        fi
+    fi
+    case "${target_os}" in
+    solaris2.3*)
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        ;;
+    solaris2.4*)
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        ;;
+    solaris2.5*)
+        cat >> confdefs.h <<\EOF
+#define SOLARIS2_5 1
+EOF
+    
+        ;;
+    *)
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        # The lfcompile64(5) man page on Solaris 2.6 says:
+        #     For applications that do not wish to conform to the POSIX or
+        #     X/Open  specifications,  the  64-bit transitional interfaces
+        #     are available by default.  No compile-time flags need to  be
+        #     set.
+        # But gcc 2.7.2.x fails to define _LARGEFILE64_SOURCE by default.
+        # The native compiler, gcc 2.8.x, and egcs don't have this problem.
+        if test -n "$GNU_CC"; then
+            cat >> confdefs.h <<\EOF
+#define _LARGEFILE64_SOURCE 1
+EOF
+
+        fi
+        ;;
+    esac
+    case "${target_os}" in
+    solaris2.3*)
+        ;;
+    solaris2.4*)
+        ;;
+    solaris2.5*)
+        ;;
+    solaris2.6*)
+        ;;
+    solaris2.7*)
+        ;;
+    *)
+        # Solaris 8 or higher has IPv6.
+        cat >> confdefs.h <<\EOF
+#define _PR_INET6 1
+EOF
+
+        ;;
+    esac
+    if test "$CPU_ARCH" = "sparc"; then
+        # 64-bit Solaris SPARC requires V9 architecture, so the following
+        # is not needed.
+        if test -z "$USE_64"; then
+            ULTRASPARC_LIBRARY=nspr_flt
+        fi
+    fi
+    # Purify requires that binaries linked against nspr also
+    # be linked against -lrt (or -lposix4) so add it to OS_LIBS
+    _rev=`uname -r`
+    _librt=`echo $_rev 5.6 | awk '{ if ($1 > $2) print "-lrt"; else print "-lposix4" }'`
+    OS_LIBS="$OS_LIBS $_librt"
+    ;;
+
+*-sco-sysv5*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define UNIXWARE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    USE_NSPR_THREADS=1
+    if echo $OS_RELEASE | grep -c 2.1 2>/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        CC='$(NSDEPTH)/build/hcc cc'
+        CXX='$(NSDEPTH)/build/hcpp CC'
+        MDCPUCFG_H=_unixware.cfg
+    else
+        cat >> confdefs.h <<\EOF
+#define _LARGEFILE64_SOURCE 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_SOCKADDR_LEN 1
+EOF
+
+        MDCPUCFG_H=_unixware7.cfg
+    fi
+    PR_MD_CSRCS=unixware.c
+    DSO_LDOPTS=-G
+    CPU_ARCH=x86
+    ;;
+
+*-symbian*)
+    # Check whether --with-symbian-sdk or --without-symbian-sdk was given.
+if test "${with_symbian_sdk+set}" = set; then
+  withval="$with_symbian_sdk"
+  SYMBIAN_SDK_DIR=$withval
+fi
+
+
+    echo -----------------------------------------------------------------------------
+    echo Building with Symbian SDK in: $SYMBIAN_SDK_DIR
+    echo -----------------------------------------------------------------------------
+
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYMBIAN 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __arm__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SYMBIAN32__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _UNICODE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NDEBUG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SUPPORT_CPP_EXCEPTIONS__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define MOZ_STDERR_TO_STDOUT 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+    USE_PTHREADS=1
+    LIB_SUFFIX=lib
+    DLL_SUFFIX=dll
+    MKSHLIB=
+    DSO_LDOPTS=
+    DSO_CFLAGS=
+    VISIBILITY_FLAGS=
+    MDCPUCFG_H=_symbian.cfg
+    PR_MD_CSRCS=symbian.c
+    NSINSTALL=nsinstall
+    RANLIB='echo no ranlib '
+    CPU_ARCH=ARM
+    OS_ARCH=SYMBIAN
+    OS_EXE_CFLAGS="$OS_EXE_CFLAGS -D__EXE__"
+    CFLAGS="$CFLAGS -MD -nostdinc"
+    SYMBIAN_SYS_INCLUDE="-I$SYMBIAN_SDK_DIR/Epoc32/include/variant -I$SYMBIAN_SDK_DIR/Epoc32/include -I$SYMBIAN_SDK_DIR/Epoc32/include/stdapis"
+    echo -------------------------------------------------------
+    echo SYMBIAN_SYS_INCLUDE is: $SYMBIAN_SYS_INCLUDE
+    echo -------------------------------------------------------
+    case "$OS_TARGET" in
+    WINSCW)
+        CC=mwccsym2.exe
+        CXX=mwccsym2.exe
+        LD=mwldsym2.exe
+        AR=mwldsym2.exe
+        WINSCW_LD_DIR="\$(SYMBIAN_SDK_DIR)/EPOC32/RELEASE/WINSCW/UDEB"
+        CFLAGS="$CFLAGS -O0 -inline off -wchar_t off -align 4 -warnings on -w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostderr -gccdep -cwd source -i- -I\$(VPATH)"
+        SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include Symbian_OS_v9.2.hrh"
+        AR_FLAGS="-library -msgstyle gcc -stdlib -subsystem windows -noimplib -o \$@"
+        cat >> confdefs.h <<\EOF
+#define _DEBUG 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define __CW32__ 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define __WINS__ 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define __WINSCW__ 1
+EOF
+
+        DEFINES="$DEFINES -U_WIN32"
+	    ;;
+    GCCE)
+        CFLAGS="$CFLAGS -Wall -Wno-unknown-pragmas -fexceptions -march=armv5t -mapcs -pipe -x c -msoft-float"
+        CXXFLAGS="$CXXFLAGS $CFLAGS -Wno-ctor-dtor-privacy"
+        SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include $SYMBIAN_SDK_DIR/EPOC32/INCLUDE/GCCE/GCCE.h"
+        cat >> confdefs.h <<\EOF
+#define __GCCE__ 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define __EABI__ 1
+EOF
+
+        DEFINES="$DEFINES -D__PRODUCT_INCLUDE__=$SYMBIAN_SDK_DIR/Epoc32/include/variant/Symbian_OS_v9.2.hrh"
+	    ;;
+    *)
+	    { echo "configure: error: Missing OS_TARGET for ${target}. Set --enable-symbian-target to with 'WINSCW' or 'GCCE'." 1>&2; exit 1; }
+   	;;
+    esac
+    CFLAGS="$CFLAGS ${SYMBIAN_SYS_INCLUDE}"
+    ;;
+
+*-os2*)
+    cat >> confdefs.h <<\EOF
+#define XP_OS2 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define XP_PC 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define BSD_SELECT 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define TCPV40HDRS 1
+EOF
+
+    LIB_SUFFIX=lib
+    DLL_SUFFIX=dll
+    RC=rc.exe
+    PR_MD_ARCH_DIR=os2
+    PROG_SUFFIX=.exe
+    NSINSTALL=nsinstall
+    MDCPUCFG_H=_os2.cfg
+    RESOLVE_LINK_SYMBOLS=1
+
+    cat >> confdefs.h <<\EOF
+#define OS2 1
+EOF
+
+    AR=emxomfar
+    AR_FLAGS='r $@'
+    CFLAGS="$CFLAGS -Wall -Zomf"
+    CXXFLAGS="$CFLAGS -Wall -Zomf"
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    DSO_CFLAGS=
+    DSO_LDOPTS='-Zomf -Zdll'
+    LDFLAGS='-Zmap'
+    _OPTIMIZE_FLAGS="-O2 -s"
+    _DEBUG_FLAGS="-g -fno-inline"
+    if test -n "$MOZ_OPTIMIZE"; then
+      DSO_LDOPTS="$DSO_LDOPTS -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
+    fi
+    IMPLIB='emximp -o'
+    FILTER='emxexp -o'
+    if test -n "$MOZ_OS2_HIGH_MEMORY"; then
+      LDFLAGS="$LDFLAGS -Zhigh-mem"
+      cat >> confdefs.h <<\EOF
+#define MOZ_OS2_HIGH_MEMORY 1
+EOF
+
+    fi
+
+    # GCC for OS/2 currently predefines these, but we don't want them
+    DEFINES="$DEFINES -Uunix -U__unix -U__unix__"
+    ;;
+
+*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    ;;
+   
+esac
+
+if test -z "$SKIP_LIBRARY_CHECKS"; then
+
+
+
+case $target in
+*-darwin*|*-beos*|*-os2*)
+    ;;
+*)
+    echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:5373: 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 5381 "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:5392: \"$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
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6
+echo "configure:5409: checking for dlfcn.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5414 "configure"
+#include "confdefs.h"
+#include <dlfcn.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5419: \"$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
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  OS_LIBS="-ldl $OS_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    ;;
+esac
+
+
+
+
+if test $ac_cv_prog_gcc = yes; then
+    echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:5452: 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 5458 "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
+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 5476 "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
+fi
+rm -f conftest*
+
+  fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+  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:5500: 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 5505 "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();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5528: \"$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
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+# Check whether --enable-strip or --disable-strip was given.
+if test "${enable_strip+set}" = set; then
+  enableval="$enable_strip"
+   if test "$enableval" = "yes"; then
+	    ENABLE_STRIP=1
+      fi 
+fi
+
+
+case "${target_os}" in
+hpux*)
+if test -z "$GNU_CC"; then
+
+    echo $ac_n "checking for +Olit support""... $ac_c" 1>&6
+echo "configure:5569: checking for +Olit support" >&5
+if eval "test \"`echo '$''{'ac_cv_hpux_usable_olit_option'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+                  ac_cv_hpux_usable_olit_option=no
+        rm -f conftest*
+        echo 'int main() { return 0; }' | cat > conftest.c
+        ${CC-cc} ${CFLAGS} +Olit=all -o conftest conftest.c > conftest.out 2>&1
+        if test $? -eq 0; then
+            if test -z "`egrep -i '(unrecognize|unknown)' conftest.out`"; then
+                ac_cv_hpux_usable_olit_option=yes
+            fi
+        fi
+        rm -f conftest*
+        
+fi
+
+echo "$ac_t""$ac_cv_hpux_usable_olit_option" 1>&6
+
+    if test "$ac_cv_hpux_usable_olit_option" = "yes"; then
+        CFLAGS="$CFLAGS +Olit=all"
+        CXXFLAGS="$CXXFLAGS +Olit=all"
+    else
+        CFLAGS="$CFLAGS +ESlit"
+        CXXFLAGS="$CXXFLAGS +ESlit"
+    fi
+fi
+;;
+esac
+
+
+
+case "$target_os" in
+darwin*)
+    _HAVE_PTHREADS=1
+    ;;
+wince*)
+    _HAVE_PTHREADS=
+    ;;
+*)
+    
+echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6
+echo "configure:5611: checking for pthread_create in -lpthreads" >&5
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthreads $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthreads $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; then
+        echo "$ac_t""yes" 1>&6
+        _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads"
+    else
+        echo "$ac_t""no" 1>&6
+        
+echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
+echo "configure:5633: checking for pthread_create in -lpthread" >&5
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthread $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthread $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; 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_create in -lc_r""... $ac_c" 1>&6
+echo "configure:5655: checking for pthread_create in -lc_r" >&5
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc_r $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc_r $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; 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_create in -lc""... $ac_c" 1>&6
+echo "configure:5677: checking for pthread_create in -lc" >&5
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; then
+        echo "$ac_t""yes" 1>&6
+        _HAVE_PTHREADS=1
+                
+    else
+        echo "$ac_t""no" 1>&6
+        
+    fi
+
+            
+    fi
+
+        
+    fi
+
+    
+    fi
+
+    ;;
+esac
+
+# Check whether --with-pthreads or --without-pthreads was given.
+if test "${with_pthreads+set}" = set; then
+  withval="$with_pthreads"
+   if test "$withval" = "yes"; then
+	    if test -n "$_HAVE_PTHREADS"; then
+		    USE_PTHREADS=1 
+		    USE_USER_PTHREADS=
+		    USE_NSPR_THREADS=
+	    else
+		    { echo "configure: error:  --with-pthreads specified for a system without pthread support " 1>&2; exit 1; };
+	    fi
+	  else
+	    USE_PTHREADS=
+	    _PTHREAD_LDFLAGS=
+	  fi
+else
+   if test -n "$_HAVE_PTHREADS" && test -z "$USE_USER_PTHREADS" && test -z "$USE_NSPR_THREADS"; then
+	    USE_PTHREADS=1
+	    USE_USER_PTHREADS=
+	    USE_NSPR_THREADS=
+	  fi
+fi
+
+
+# Check whether --enable-user-pthreads or --disable-user-pthreads was given.
+if test "${enable_user_pthreads+set}" = set; then
+  enableval="$enable_user_pthreads"
+   if test "$enableval" = "yes"; then
+        if test -n "$_HAVE_PTHREADS"; then
+		    USE_PTHREADS=
+		    USE_USER_PTHREADS=1
+		    USE_NSPR_THREADS=
+	    else
+		    { echo "configure: error:  --enable-user-pthreads specified for a system without pthread support " 1>&2; exit 1; };
+	    fi
+	  fi
+fi
+
+
+# Check whether --enable-nspr-threads or --disable-nspr-threads was given.
+if test "${enable_nspr_threads+set}" = set; then
+  enableval="$enable_nspr_threads"
+   if test "$enableval" = "yes"; then
+	    USE_PTHREADS=
+	    USE_USER_PTHREADS=
+	    USE_NSPR_THREADS=1
+	  fi
+fi
+
+
+case "$target" in
+*-beos*)
+    # Check whether --with-bthreads or --without-bthreads was given.
+if test "${with_bthreads+set}" = set; then
+  withval="$with_bthreads"
+  	if test "$withval" = "yes"; then
+    	    USE_BTHREADS=1
+	        USE_USER_PTHREADS=
+	        USE_PTHREADS=
+	    fi
+fi
+
+    ;;
+esac
+
+fi # SKIP_LIBRARY_CHECKS
+
+# Check whether --enable-ipv6 or --disable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then
+  enableval="$enable_ipv6"
+   if test "$enableval" = "yes"; then
+	    USE_IPV6=1
+      else
+	    USE_IPV6=
+      fi
+fi
+
+
+
+# Check whether --enable-boehm or --disable-boehm was given.
+if test "${enable_boehm+set}" = set; then
+  enableval="$enable_boehm"
+   if test "$enableval" = "yes"; then
+        cat >> confdefs.h <<\EOF
+#define GC_LEAK_DETECTOR 1
+EOF
+
+        GC_LEAK_DETECTOR=1
+    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:5809: 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
+		case "$target_os" in
+	    freebsd*)
+# Freebsd doesn't use -pthread for compiles, it uses them for linking
+            ;;
+	    *)
+            CFLAGS="$CFLAGS -pthread"
+            CXXFLAGS="$CXXFLAGS -pthread"
+            ;;
+        esac
+	fi
+    fi
+    rm -f conftest*
+    echo "$ac_t""$ac_cv_have_dash_pthread" 1>&6
+
+			    ac_cv_have_dash_pthreads=no
+    if test "$ac_cv_have_dash_pthread" = "no"; then
+	    echo $ac_n "checking whether ${CC-cc} accepts -pthreads""... $ac_c" 1>&6
+echo "configure:5832: checking whether ${CC-cc} accepts -pthreads" >&5
+    	echo 'int main() { return 0; }' | cat > conftest.c
+	    ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1
+    	if test $? -eq 0; then
+	    	if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthreads`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then
+			    ac_cv_have_dash_pthreads=yes
+			    CFLAGS="$CFLAGS -pthreads"
+			    CXXFLAGS="$CXXFLAGS -pthreads"
+		    fi
+	    fi
+	    rm -f conftest*
+    	echo "$ac_t""$ac_cv_have_dash_pthreads" 1>&6
+    fi
+
+    case "$target" in
+    *-solaris*)
+        if test "$ac_cv_have_dash_pthreads" = "yes"; then
+            _PTHREAD_LDFLAGS=
+        fi
+	    ;;
+    *-freebsd*)
+	    cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _THREAD_SAFE 1
+EOF
+
+	    	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS="-pthread"
+	    else
+	        _PTHREAD_LDFLAGS="-lc_r"
+	    fi
+	    ;;
+    *-netbsd*)
+	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS="-pthread"
+	    fi
+	    ;;
+    *-bsdi*)
+	    cat >> confdefs.h <<\EOF
+#define _THREAD_SAFE 1
+EOF
+
+	    	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS=
+	    fi
+	    ;;
+    *-openbsd*)
+        if test "$ac_cv_have_dash_pthread" = "yes"; then
+            _PTHREAD_LDFLAGS=-pthread
+        fi
+        ;;
+    *-linux*|*-gnu*|*-k*bsd*-gnu)
+        cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+        ;;
+    esac
+
+else 
+    if test -n "$USE_USER_PTHREADS"; then
+	    USE_PTHREADS=
+	    USE_NSPR_THREADS=
+    else
+        _PTHREAD_LDFLAGS=
+    fi
+fi
+
+case "$target" in
+*-aix*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    case "$target_os" in
+    aix4.1*)
+        if test -z "$USE_PTHREADS"; then
+            cat >> confdefs.h <<\EOF
+#define AIX_RENAME_SELECT 1
+EOF
+
+        fi
+        ;;
+    aix4.2*)
+        if test -z "$USE_NSPR_THREADS"; then
+            cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+        fi
+        ;;
+    aix4.3*)
+        if test -z "$USE_NSPR_THREADS"; then
+            cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+        fi
+        if test -n "$USE_PTHREADS"; then
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_THREADSAFE_GETHOST 1
+EOF
+
+        fi
+        ;;
+    *)
+        if test -z "$USE_NSPR_THREADS"; then
+            cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+        fi
+        if test -n "$USE_PTHREADS"; then
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_THREADSAFE_GETHOST 1
+EOF
+
+        fi
+        ;;
+    esac
+    ;;
+*-bsdi*)
+    if test -n "$USE_PTHREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NEED_PTHREAD_INIT 1
+EOF
+
+    fi
+    ;;
+*-freebsd*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    ;;
+*-hpux*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi 
+    if test "$USE_PTHREADS"; then
+        if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+            cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+            cat >> confdefs.h <<\EOF
+#define _PR_DCETHREADS 1
+EOF
+
+        else
+            cat >> confdefs.h <<EOF
+#define _POSIX_C_SOURCE 199506L
+EOF
+
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_THREADSAFE_GETHOST 1
+EOF
+
+        fi
+    fi
+    if test "$USE_USER_PTHREADS"; then
+        cat >> confdefs.h <<EOF
+#define _POSIX_C_SOURCE 199506L
+EOF
+
+    fi
+    ;;
+*-irix*)
+    if test "${target_os}" = "irix6.5"; then
+        if test -n "$USE_PTHREADS"; then
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETHOST_R 1
+EOF
+
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETHOST_R_POINTER 1
+EOF
+
+        fi
+    fi
+    ;;
+*-linux*|*-gnu*|*-k*bsd*-gnu)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    ;;
+*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*|*-os2*|*-beos*)
+        USE_PTHREADS=
+    _PTHREAD_LDFLAGS=
+    USE_USER_PTHREADS=
+    ;;
+*-netbsd*|*-openbsd*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    ;;
+*-osf*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    if test -n "$USE_PTHREADS"; then
+        if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then
+            :
+        else
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_THREADSAFE_GETHOST 1
+EOF
+
+        fi
+    fi
+    ;;
+*-solaris*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    if test -n "$USE_PTHREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+        if test "$OS_TEST" = "i86pc"; then
+            if test -n "$USE_64"; then
+               PR_MD_ASFILES=os_SunOS_x86_64.s
+            else
+               PR_MD_ASFILES=os_SunOS_x86.s
+            fi
+        else
+            if test -n "$USE_64"; then
+                PR_MD_ASFILES=os_SunOS_sparcv9.s
+            fi
+        fi
+    fi
+    ;;
+*-nto*)
+    if test -n "$USE_PTHREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETHOST_R 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETHOST_R_POINTER 1
+EOF
+
+    fi
+    ;;
+esac
+
+OS_LIBS="$_PTHREAD_LDFLAGS $OS_LIBS"
+
+if test -n "$_SAVE_OPTIMIZE_FLAGS"; then
+    _OPTIMIZE_FLAGS="$_SAVE_OPTIMIZE_FLAGS"
+fi
+
+if test -n "$_SAVE_DEBUG_FLAGS"; then
+    _DEBUG_FLAGS="$_SAVE_DEBUG_FLAGS"
+fi
+
+if test -n "$MOZ_OPTIMIZE"; then
+    CFLAGS="$CFLAGS $_OPTIMIZE_FLAGS"
+    CXXFLAGS="$CXXFLAGS $_OPTIMIZE_FLAGS"
+fi
+
+if test -n "$MOZ_DEBUG_SYMBOLS"; then
+    CFLAGS="$CFLAGS $_DEBUG_FLAGS"
+    CXXFLAGS="$CXXFLAGS $_DEBUG_FLAGS"
+fi
+
+if test -n "$MOZ_OPTIMIZE"; then
+    OBJDIR_TAG=_OPT
+else
+    OBJDIR_TAG=_DBG
+fi
+
+if test -n "$USE_64"; then
+    COMPILER_TAG=_64
+fi
+
+RELEASE_OBJDIR_NAME="${OS_CONFIG}${CPU_ARCH_TAG}${COMPILER_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}.${OBJDIR_SUFFIX}"
+
+case "$target_os" in
+cygwin*|msvc*|mks*)
+    CC="\$(CYGWIN_WRAPPER) $CC"
+    CXX="\$(CYGWIN_WRAPPER) $CXX"
+    RC="\$(CYGWIN_WRAPPER) $RC"
+    ;;
+esac
+
+# Check whether --enable-wrap-malloc or --disable-wrap-malloc was given.
+if test "${enable_wrap_malloc+set}" = set; then
+  enableval="$enable_wrap_malloc"
+       if test "$enableval" = "yes"; then
+	    _WRAP_MALLOC=1
+      fi 
+fi
+
+
+if test -n "$_WRAP_MALLOC"; then
+    if test "$GNU_CC"; then
+       WRAP_MALLOC_CFLAGS="${LDFLAGS} -Wl,--wrap -Wl,malloc -Wl,--wrap -Wl,calloc -Wl,--wrap -Wl,valloc -Wl,--wrap -Wl,free -Wl,--wrap -Wl,realloc -Wl,--wrap -Wl,memalign -Wl,--wrap -Wl,__builtin_new -Wl,--wrap -Wl,__builtin_vec_new -Wl,--wrap -Wl,__builtin_delete -Wl,--wrap -Wl,__builtin_vec_delete -Wl,--wrap -Wl,PR_Free -Wl,--wrap -Wl,PR_Malloc -Wl,--wrap -Wl,PR_Calloc -Wl,--wrap -Wl,PR_Realloc -Wl,--wrap -Wl,strdup -Wl,--wrap -Wl,strndup -Wl,--wrap -Wl,posix_memalign"
+       DSO_LDOPTS="$DSO_LDOPTS $WRAP_MALLOC_CFLAGS"
+    else
+       { echo "configure: error: --enable-wrap-malloc is not supported for non-GNU toolchains" 1>&2; exit 1; }
+    fi
+fi
+
+# Check whether --with-wrap-malloc or --without-wrap-malloc was given.
+if test "${with_wrap_malloc+set}" = set; then
+  withval="$with_wrap_malloc"
+  WRAP_MALLOC_LIB=$withval
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MAKEFILES="
+Makefile 
+config/Makefile
+config/autoconf.mk
+config/nsprincl.mk
+config/nsprincl.sh
+config/nspr-config
+lib/Makefile 
+lib/ds/Makefile 
+lib/libc/Makefile 
+lib/libc/include/Makefile 
+lib/libc/src/Makefile 
+lib/tests/Makefile
+pkg/Makefile
+pkg/linux/Makefile
+pkg/solaris/Makefile
+pkg/solaris/SUNWpr/Makefile
+pkg/solaris/SUNWprd/Makefile
+pr/Makefile 
+pr/include/Makefile 
+pr/include/md/Makefile 
+pr/include/obsolete/Makefile 
+pr/include/private/Makefile 
+pr/src/Makefile 
+pr/src/io/Makefile 
+pr/src/linking/Makefile 
+pr/src/malloc/Makefile 
+pr/src/md/Makefile 
+pr/src/md/${PR_MD_ARCH_DIR}/Makefile 
+pr/src/memory/Makefile 
+pr/src/misc/Makefile 
+pr/src/threads/Makefile 
+pr/tests/Makefile 
+pr/tests/dll/Makefile 
+"
+
+
+if test -z "$USE_PTHREADS" && test -z "$USE_BTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/threads/combined/Makefile"
+elif test -n "$USE_PTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/pthreads/Makefile"
+elif test -n "$USE_BTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/bthreads/Makefile"
+fi
+
+if test -n "$USE_CPLUS"; then
+    MAKEFILES="$MAKEFILES pr/src/cplus/Makefile pr/src/cplus/tests/Makefile"
+fi
+
+echo $MAKEFILES > unallmakefiles
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' ' | tr '\015' ' '` # Manually modified for MKS support.
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "$MAKEFILES" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CC@%$CC%g
+s%@dist_prefix@%$dist_prefix%g
+s%@dist_bindir@%$dist_bindir%g
+s%@dist_includedir@%$dist_includedir%g
+s%@dist_libdir@%$dist_libdir%g
+s%@WHOAMI@%$WHOAMI%g
+s%@HOST_CC@%$HOST_CC%g
+s%@CXX@%$CXX%g
+s%@RANLIB@%$RANLIB%g
+s%@AR@%$AR%g
+s%@AS@%$AS%g
+s%@LD@%$LD%g
+s%@STRIP@%$STRIP%g
+s%@WINDRES@%$WINDRES%g
+s%@CPP@%$CPP%g
+s%@PERL@%$PERL%g
+s%@SHELL_OVERRIDE@%$SHELL_OVERRIDE%g
+s%@MOZILLA_CLIENT@%$MOZILLA_CLIENT%g
+s%@HOST_CFLAGS@%$HOST_CFLAGS%g
+s%@HOST_LDFLAGS@%$HOST_LDFLAGS%g
+s%@GNU_CC@%$GNU_CC%g
+s%@GCC_USE_GNU_LD@%$GCC_USE_GNU_LD%g
+s%@MSC_VER@%$MSC_VER%g
+s%@CROSS_COMPILE@%$CROSS_COMPILE%g
+s%@MOZ_OPTIMIZE@%$MOZ_OPTIMIZE%g
+s%@MOZ_DEBUG@%$MOZ_DEBUG%g
+s%@MOZ_DEBUG_SYMBOLS@%$MOZ_DEBUG_SYMBOLS%g
+s%@USE_CPLUS@%$USE_CPLUS%g
+s%@USE_IPV6@%$USE_IPV6%g
+s%@USE_N32@%$USE_N32%g
+s%@USE_64@%$USE_64%g
+s%@OBJECT_MODE@%$OBJECT_MODE%g
+s%@GC_LEAK_DETECTOR@%$GC_LEAK_DETECTOR%g
+s%@ENABLE_STRIP@%$ENABLE_STRIP%g
+s%@USE_PTHREADS@%$USE_PTHREADS%g
+s%@USE_BTHREADS@%$USE_BTHREADS%g
+s%@USE_USER_PTHREADS@%$USE_USER_PTHREADS%g
+s%@USE_NSPR_THREADS@%$USE_NSPR_THREADS%g
+s%@LIBNSPR@%$LIBNSPR%g
+s%@LIBPLC@%$LIBPLC%g
+s%@MOD_MAJOR_VERSION@%$MOD_MAJOR_VERSION%g
+s%@MOD_MINOR_VERSION@%$MOD_MINOR_VERSION%g
+s%@MOD_PATCH_VERSION@%$MOD_PATCH_VERSION%g
+s%@NSPR_MODNAME@%$NSPR_MODNAME%g
+s%@MDCPUCFG_H@%$MDCPUCFG_H%g
+s%@PR_MD_CSRCS@%$PR_MD_CSRCS%g
+s%@PR_MD_ASFILES@%$PR_MD_ASFILES%g
+s%@PR_MD_ARCH_DIR@%$PR_MD_ARCH_DIR%g
+s%@CPU_ARCH@%$CPU_ARCH%g
+s%@OBJ_SUFFIX@%$OBJ_SUFFIX%g
+s%@LIB_SUFFIX@%$LIB_SUFFIX%g
+s%@DLL_SUFFIX@%$DLL_SUFFIX%g
+s%@ASM_SUFFIX@%$ASM_SUFFIX%g
+s%@WRAP_MALLOC_CFLAGS@%$WRAP_MALLOC_CFLAGS%g
+s%@WRAP_MALLOC_LIB@%$WRAP_MALLOC_LIB%g
+s%@MKSHLIB@%$MKSHLIB%g
+s%@DSO_CFLAGS@%$DSO_CFLAGS%g
+s%@DSO_LDOPTS@%$DSO_LDOPTS%g
+s%@OS_TARGET@%$OS_TARGET%g
+s%@OS_ARCH@%$OS_ARCH%g
+s%@OS_RELEASE@%$OS_RELEASE%g
+s%@OS_TEST@%$OS_TEST%g
+s%@MACOSX_DEPLOYMENT_TARGET@%$MACOSX_DEPLOYMENT_TARGET%g
+s%@DEFINES@%$DEFINES%g
+s%@AR_FLAGS@%$AR_FLAGS%g
+s%@ASFLAGS@%$ASFLAGS%g
+s%@FILTER@%$FILTER%g
+s%@IMPLIB@%$IMPLIB%g
+s%@PROFILE_GEN_CFLAGS@%$PROFILE_GEN_CFLAGS%g
+s%@PROFILE_GEN_LDFLAGS@%$PROFILE_GEN_LDFLAGS%g
+s%@PROFILE_USE_CFLAGS@%$PROFILE_USE_CFLAGS%g
+s%@PROFILE_USE_LDFLAGS@%$PROFILE_USE_LDFLAGS%g
+s%@OS_LIBS@%$OS_LIBS%g
+s%@RESOLVE_LINK_SYMBOLS@%$RESOLVE_LINK_SYMBOLS%g
+s%@AIX_LINK_OPTS@%$AIX_LINK_OPTS%g
+s%@NOSUCHFILE@%$NOSUCHFILE%g
+s%@MOZ_OBJFORMAT@%$MOZ_OBJFORMAT%g
+s%@ULTRASPARC_LIBRARY@%$ULTRASPARC_LIBRARY%g
+s%@OBJDIR@%$OBJDIR%g
+s%@OBJDIR_NAME@%$OBJDIR_NAME%g
+s%@RELEASE_OBJDIR_NAME@%$RELEASE_OBJDIR_NAME%g
+s%@NSINSTALL@%$NSINSTALL%g
+s%@OPTIMIZER@%$OPTIMIZER%g
+s%@RC@%$RC%g
+s%@RCFLAGS@%$RCFLAGS%g
+s%@DLLFLAGS@%$DLLFLAGS%g
+s%@EXEFLAGS@%$EXEFLAGS%g
+s%@OS_DLLFLAGS@%$OS_DLLFLAGS%g
+s%@CYGWIN_WRAPPER@%$CYGWIN_WRAPPER%g
+s%@VISIBILITY_FLAGS@%$VISIBILITY_FLAGS%g
+s%@WRAP_SYSTEM_INCLUDES@%$WRAP_SYSTEM_INCLUDES%g
+s%@MACOS_SDK_DIR@%$MACOS_SDK_DIR%g
+s%@SYMBIAN_SDK_DIR@%$SYMBIAN_SDK_DIR%g
+s%@NEXT_ROOT@%$NEXT_ROOT%g
+s%@MT@%$MT%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"$MAKEFILES"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+chmod +x config/nspr-config
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/configure.in b/nspr-4.8.6/mozilla/nsprpub/configure.in
new file mode 100644
index 0000000..119404c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/configure.in
@@ -0,0 +1,3137 @@
+dnl -*- Mode: Autoconf; tab-width: 4; indent-tabs-mode: nil; -*-
+dnl 
+dnl ***** BEGIN LICENSE BLOCK *****
+dnl Version: MPL 1.1/GPL 2.0/LGPL 2.1
+dnl
+dnl The contents of this file are subject to the Mozilla Public License Version
+dnl 1.1 (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl http://www.mozilla.org/MPL/
+dnl
+dnl Software distributed under the License is distributed on an "AS IS" basis,
+dnl WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+dnl for the specific language governing rights and limitations under the
+dnl License.
+dnl
+dnl The Original Code is the Netscape Portable Runtime (NSPR).
+dnl
+dnl The Initial Developer of the Original Code is
+dnl Netscape Communications Corporation.
+dnl Portions created by the Initial Developer are Copyright (C) 1998
+dnl the Initial Developer. All Rights Reserved.
+dnl
+dnl Contributor(s):
+dnl   Christopher Seawood <cls@seawood.org>
+dnl   Howard Chu <hyc@symas.com>
+dnl   Mark Mentovai <mark@moxienet.com>
+dnl
+dnl Alternatively, the contents of this file may be used under the terms of
+dnl either the GNU General Public License Version 2 or later (the "GPL"), or
+dnl the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+dnl in which case the provisions of the GPL or the LGPL are applicable instead
+dnl of those above. If you wish to allow use of your version of this file only
+dnl under the terms of either the GPL or the LGPL, and not to allow others to
+dnl use your version of this file under the terms of the MPL, indicate your
+dnl decision by deleting the provisions above and replace them with the notice
+dnl and other provisions required by the GPL or the LGPL. If you do not delete
+dnl the provisions above, a recipient may use your version of this file under
+dnl the terms of any one of the MPL, the GPL or the LGPL.
+dnl
+dnl ***** END LICENSE BLOCK *****
+
+AC_PREREQ(2.12)
+AC_INIT(config/libc_r.h)
+
+AC_CONFIG_AUX_DIR(${srcdir}/build/autoconf)
+AC_CANONICAL_SYSTEM
+
+dnl ========================================================
+dnl = Defaults
+dnl ========================================================
+MOD_MAJOR_VERSION=4
+MOD_MINOR_VERSION=8
+MOD_PATCH_VERSION=6
+NSPR_MODNAME=nspr20
+_HAVE_PTHREADS=
+USE_PTHREADS=
+USE_USER_PTHREADS=
+USE_NSPR_THREADS=
+USE_N32=
+USE_64=
+USE_CPLUS=
+USE_IPV6=
+USE_MDUPDATE=
+_MACOSX_DEPLOYMENT_TARGET=
+_OPTIMIZE_FLAGS=-O
+_DEBUG_FLAGS=-g
+MOZ_DEBUG=1
+MOZ_OPTIMIZE=
+OBJDIR='$(OBJDIR_NAME)'
+OBJDIR_NAME=.
+OBJDIR_SUFFIX=OBJ
+NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall'
+NOSUCHFILE=/no-such-file
+LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)'
+LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)'
+CYGWIN_WRAPPER=
+MACOS_SDK_DIR=
+NEXT_ROOT=
+MT=
+MOZ_OS2_HIGH_MEMORY=1
+MOZ_THUMB2=
+PROFILE_GEN_CFLAGS=
+PROFILE_GEN_LDFLAGS=
+PROFILE_USE_CFLAGS=
+PROFILE_USE_LDFLAGS=
+
+dnl Link in libraries necessary to resolve all symbols for shared libs
+RESOLVE_LINK_SYMBOLS=
+
+dnl ========================================================
+dnl =
+dnl = Dont change the following lines.  Doing so breaks:
+dnl =
+dnl = CFLAGS="-foo" ./configure
+dnl =
+dnl ========================================================
+CFLAGS="${CFLAGS=}"
+CXXFLAGS="${CXXFLAGS=}"
+LDFLAGS="${LDFLAGS=}"
+DLLFLAGS="${DLLFLAGS=}"
+HOST_CFLAGS="${HOST_CFLAGS=}"
+HOST_LDFLAGS="${HOST_LDFLAGS=}"
+
+case "$target" in
+*-cygwin*|*-mingw*)
+    # Check to see if we are really running in a msvc environemnt
+    _WIN32_MSVC=
+    AC_CHECK_PROGS(CC, cl)
+    if test "$CC" = "cl"; then
+        echo 'main() { return 0; }' > dummy.c
+        ${CC} -o dummy dummy.c >/dev/null 2>&1
+        if test $? = 0; then
+            _WIN32_MSVC=1
+            CXX=$CC
+        else
+            AC_MSG_WARN([$(CC) test failed.  Using normal feature tests])
+        fi
+        rm -f dummy dummy.o dummy.obj dummy.exe dummy.c
+    fi
+    ;;
+*-msvc*)
+    _WIN32_MSVC=1
+    ;;
+*-mks*)
+    _WIN32_MSVC=1
+    ;;
+esac
+
+if test -n "$_WIN32_MSVC"; then
+    SKIP_PATH_CHECKS=1
+    SKIP_COMPILER_CHECKS=1
+    SKIP_LIBRARY_CHECKS=1
+fi
+
+dnl ========================================================
+dnl = Android uses a very custom (hacky) toolchain; we need to do this
+dnl = here, so that the compiler checks can succeed
+dnl ========================================================
+
+AC_ARG_WITH(android-ndk,
+[  --with-android-ndk=DIR
+                      location where the Android NDK can be found],
+    android_ndk=$withval)
+
+AC_ARG_WITH(android-toolchain,
+[  --with-android-toolchain=DIR
+                            location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0],
+    android_toolchain=$withval)
+
+AC_ARG_WITH(android-platform,
+[  --with-android-platform=DIR
+                           location of platform dir, default NDK/build/platforms/android-5/arch-arm],
+    android_platform=$withval)
+
+if test "$target" = "arm-android-eabi" ; then
+    if test -z "$android_ndk" ; then
+       AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
+    fi
+
+    if test -z "$android_toolchain" ; then
+       android_toolchain="$android_ndk"/build/prebuilt/`uname -s | tr "[[:upper:]]" "[[:lower:]]"`-x86/arm-eabi-4.4.0
+    fi
+
+    if test -z "$android_platform" ; then
+       android_platform="$android_ndk"/build/platforms/android-5/arch-arm
+    fi
+
+    dnl set up compilers
+    AS="$android_toolchain"/bin/arm-eabi-as
+    CC="$android_toolchain"/bin/arm-eabi-gcc
+    CXX="$android_toolchain"/bin/arm-eabi-g++
+    CPP="$android_toolchain"/bin/arm-eabi-cpp
+    LD="$android_toolchain"/bin/arm-eabi-ld
+    AR="$android_toolchain"/bin/arm-eabi-ar
+    RANLIB="$android_toolchain"/bin/arm-eabi-ranlib
+    STRIP="$android_toolchain"/bin/arm-eabi-strip
+
+    CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS"
+    CFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions $CFLAGS"
+    CXXFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fpic -fno-short-enums -fno-exceptions $CXXFLAGS"
+    LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform $LDFLAGS"
+
+    dnl prevent cross compile section from using these flags as host flags
+    if test -z "$HOST_CPPFLAGS" ; then
+        HOST_CPPFLAGS=" "
+    fi
+    if test -z "$HOST_CFLAGS" ; then
+        HOST_CFLAGS=" "
+    fi
+    if test -z "$HOST_CXXFLAGS" ; then
+        HOST_CXXFLAGS=" "
+    fi
+    if test -z "$HOST_LDFLAGS" ; then
+        HOST_LDFLAGS=" "
+    fi
+
+    AC_DEFINE(ANDROID)
+fi
+
+dnl ========================================================
+dnl =
+dnl = Check options that may affect the compiler
+dnl =
+dnl ========================================================
+dist_prefix='${MOD_DEPTH}/dist'
+dist_bindir='${dist_prefix}/bin'
+dist_includedir='${dist_prefix}/include/nspr'
+dist_libdir='${dist_prefix}/lib'
+dnl If the --includedir option was not specified, add '/nspr' to autoconf's
+dnl default value of includedir.
+if test "${includedir}" = '${prefix}/include'; then
+    includedir='${prefix}/include/nspr'
+fi
+
+AC_ARG_WITH(dist-prefix,
+    [  --with-dist-prefix=DIST_PREFIX
+                          place build files in DIST_PREFIX [dist]],
+    dist_prefix=$withval)
+
+AC_ARG_WITH(dist-bindir,
+    [  --with-dist-bindir=DIR  build execuatables in DIR [DIST_PREFIX/bin]],
+    dist_bindir=$withval)
+
+AC_ARG_WITH(dist-includedir,
+    [  --with-dist-includedir=DIR
+                          build include files in DIR [DIST_PREFIX/include/nspr]],
+    dist_includedir=$withval)
+
+AC_ARG_WITH(dist-libdir,
+    [  --with-dist-libdir=DIR  build library files in DIR [DIST_PREFIX/lib]],
+    dist_libdir=$withval)
+
+AC_SUBST(dist_prefix)
+AC_SUBST(dist_bindir)
+AC_SUBST(dist_includedir)
+AC_SUBST(dist_libdir)
+
+dnl Check if NSPR is being compiled for Mozilla
+dnl Let --with-arg override environment setting
+dnl
+AC_ARG_WITH(mozilla,
+    [  --with-mozilla          Compile NSPR with Mozilla support],
+    [   if test "$withval" = "yes"; then
+            AC_DEFINE(MOZILLA_CLIENT)
+            MOZILLA_CLIENT=1
+	    else
+	        MOZILLA_CLIENT=
+	    fi],
+    [	if test -n "$MOZILLA_CLIENT"; then
+	        AC_DEFINE(MOZILLA_CLIENT)
+	    fi])
+
+AC_ARG_ENABLE(optimize,
+    [  --enable-optimize[=OPT] Enable code optimizations (ie. -O2) ],
+    [ if test "$enableval" != "no"; then
+          MOZ_OPTIMIZE=1
+          if test -n "$enableval" -a "$enableval" != "yes"; then
+            _OPTIMIZE_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+            _SAVE_OPTIMIZE_FLAGS=$_OPTIMIZE_FLAGS
+          fi
+      else
+          MOZ_OPTIMIZE=
+      fi ])
+
+AC_ARG_ENABLE(debug,
+    [  --enable-debug[=DBG]    Enable debugging (using compiler flags DBG)],
+    [ if test "$enableval" != "no"; then
+          MOZ_DEBUG=1
+          MOZ_DEBUG_SYMBOLS=1
+          if test -n "$enableval" -a "$enableval" != "yes"; then
+              _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+              _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS
+          fi
+      else
+          MOZ_DEBUG=
+      fi ],
+      MOZ_DEBUG_SYMBOLS=1)
+
+AC_ARG_ENABLE(debug-symbols,
+    [  --enable-debug-symbols[=DBG]    Enable debugging symbols
+                                       (using compiler flags DBG)],
+    [ if test "$enableval" != "no"; then
+          MOZ_DEBUG_SYMBOLS=1
+          if test -n "$enableval" -a "$enableval" != "yes"; then
+              if test -z "$_SAVE_DEBUG_FLAGS"; then
+                  _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+                  _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS
+              else
+                  AC_MSG_ERROR([--enable-debug-symbols flags cannot be used with --enable-debug flags])
+              fi
+          fi
+      else
+          MOZ_DEBUG_SYMBOLS=
+      fi ])
+
+AC_ARG_ENABLE(win32-target,
+    [  --enable-win32-target=\$t
+                          Specify win32 flavor. (WIN95 or WINNT)],
+    OS_TARGET=`echo $enableval | tr a-z A-Z`)
+
+AC_ARG_ENABLE(symbian-target,
+    [  --enable-symbian-target=\$t
+                          Specify symbian flavor. (WINSCW or GCCE)],
+    OS_TARGET=`echo $enableval | tr a-z A-Z`)
+
+AC_ARG_ENABLE(debug-rtl,
+    [  --enable-debug-rtl      Use the MSVC debug runtime library],
+    [ if test "$enableval" = "yes"; then
+	    USE_DEBUG_RTL=1
+      fi ])
+
+AC_ARG_ENABLE(n32,
+    [  --enable-n32            Enable n32 ABI support (IRIX only)],
+    [ if test "$enableval" = "yes"; then
+	USE_N32=1
+      else if test "$enableval" = "no"; then
+	USE_N32=
+      fi
+    fi ])
+
+AC_ARG_ENABLE(64bit,
+    [  --enable-64bit          Enable 64-bit support (on certain platforms)],
+    [ if test "$enableval" = "yes"; then
+	    USE_64=1
+      fi ])
+
+AC_ARG_ENABLE(mdupdate,
+    [  --enable-mdupdate       Enable use of certain compilers' mdupdate feature],
+    [ if test "$enableval" = "yes"; then
+	    USE_MDUPDATE=1
+      fi ])
+
+AC_ARG_ENABLE(cplus,
+    [  --enable-cplus          Enable some c++ api routines],
+    [ if test "$enableval" = "yes"; then
+	    USE_CPLUS=1
+      fi]) 
+
+AC_ARG_WITH(arm-kuser,
+    [  --with-arm-kuser        Use kuser helpers (Linux/ARM only)
+                          (Requires kernel 2.6.13 or later)],
+    [ if test "$withval" = "yes"; then
+	    AC_DEFINE(_PR_ARM_KUSER)
+      fi ])
+
+dnl ========================================================
+dnl = Mac OS X SDK support
+dnl ========================================================
+AC_ARG_WITH(macos-sdk,
+    [  --with-macos-sdk=dir    Location of platform SDK to use (Mac OS X only)],
+    MACOS_SDK_DIR=$withval)
+
+AC_ARG_ENABLE(macos-target,
+             [  --enable-macos-target=VER
+                          Set the minimum MacOS version needed at runtime
+                          [10.2 for ppc, 10.4 for x86]],
+             [_MACOSX_DEPLOYMENT_TARGET=$enableval])
+
+dnl ========================================================
+dnl =
+dnl = Set the threading model
+dnl =
+dnl ========================================================
+case "$target" in
+
+*-aix*)
+    case "${target_os}" in
+    aix3.2*)
+        USE_NSPR_THREADS=1
+        ;;
+    *)
+        USE_PTHREADS=1
+        ;;
+    esac
+    ;;
+
+esac
+
+dnl ========================================================
+dnl =
+dnl = Set the default C compiler
+dnl =
+dnl ========================================================
+if test -z "$CC"; then
+    case "$target" in
+
+    *-aix*)
+        if test -z "$USE_NSPR_THREADS"; then
+            CC=xlc_r
+        else
+            CC=xlc
+        fi
+    ;;
+
+    *-hpux*)
+        CC=cc
+    ;;
+
+    *-irix*)
+        CC=cc
+    ;;
+
+    *-osf*)
+        CC=cc
+    ;;
+
+    *-solaris*)
+        CC=cc
+    ;;
+
+    esac
+fi
+
+dnl ========================================================
+dnl =
+dnl = Set the default C++ compiler
+dnl =
+dnl ========================================================
+if test -z "$CXX"; then
+    case "$target" in
+
+    *-aix*)
+        if test -z "$USE_NSPR_THREADS"; then
+            CXX=xlC_r
+        else
+            CXX=xlC
+        fi
+    ;;
+
+    *-hpux*)
+        case "${target_os}" in
+        hpux10.30)
+            CXX=aCC
+            ;;
+        hpux11.*)
+            CXX=aCC
+            ;;
+        *)
+            CXX=CC
+            ;;
+        esac
+    ;;
+
+    *-irix*)
+        CXX=CC
+    ;;
+
+    *-osf*)
+        CXX=cxx
+    ;;
+
+    *-solaris*)
+        CXX=CC
+    ;;
+
+    esac
+fi
+
+if test -z "$SKIP_PATH_CHECKS"; then
+    AC_PATH_PROG(WHOAMI, $WHOAMI whoami, echo not_whoami)
+fi
+
+if test -n "$MOZ_DEBUG"; then
+    AC_DEFINE(DEBUG)
+    DEFINES="$DEFINES -UNDEBUG"
+
+    case "${target_os}" in
+    beos*)
+        DEFINES="$DEFINES -DDEBUG_${USER}"
+        ;;
+    msvc*|mks*|cygwin*|mingw*|wince*|winmo*|os2*)
+        DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`"
+        ;;
+    *) 
+        DEFINES="$DEFINES -DDEBUG_`$WHOAMI`"
+        ;;
+    esac
+else
+    AC_DEFINE(NDEBUG)
+    DEFINES="$DEFINES -UDEBUG"
+fi
+
+if test -z "$SKIP_COMPILER_CHECKS"; then
+dnl ========================================================
+dnl Checks for compilers.
+dnl ========================================================
+if test "$target" != "$host"; then
+    echo "cross compiling from $host to $target"
+    cross_compiling=yes
+
+    _SAVE_CC="$CC"
+    _SAVE_CFLAGS="$CFLAGS"
+    _SAVE_LDFLAGS="$LDFLAGS"
+
+    AC_MSG_CHECKING([for $host compiler])
+    AC_CHECK_PROGS(HOST_CC, $HOST_CC gcc cc /usr/ucb/cc, "")
+    if test -z "$HOST_CC"; then
+        AC_MSG_ERROR([no acceptable cc found in \$PATH])
+    fi
+    AC_MSG_RESULT([$HOST_CC])
+    if test -z "$HOST_CFLAGS"; then
+        HOST_CFLAGS="$CFLAGS"
+    fi
+    if test -z "$HOST_LDFLAGS"; then
+        HOST_LDFLAGS="$LDFLAGS"
+    fi
+
+    CC="$HOST_CC"
+    CFLAGS="$HOST_CFLAGS"
+    LDFLAGS="$HOST_LDFLAGS"
+
+    AC_MSG_CHECKING([whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works])
+    AC_TRY_COMPILE([], [return(0);], 
+        [ac_cv_prog_host_cc_works=1 AC_MSG_RESULT([yes])],
+        AC_MSG_ERROR([installation or configuration problem: $host compiler $HOST_CC cannot create executables.]) )
+
+    CC=$_SAVE_CC
+    CFLAGS=$_SAVE_CFLAGS
+    LDFLAGS=$_SAVE_LDFLAGS
+
+    case "$build:$target" in 
+      powerpc-apple-darwin8*:i?86-apple-darwin*)
+        dnl The Darwin cross compiler doesn't necessarily point itself at a
+        dnl root that has libraries for the proper architecture, it defaults
+        dnl to the system root.  The libraries in the system root on current
+        dnl versions of PPC OS X 10.4 aren't fat, so these target compiler
+        dnl checks will fail.  Fake a working SDK in that case.
+        _SAVE_CFLAGS=$CFLAGS 
+        _SAVE_CXXFLAGS=$CXXLAGS
+        CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CFLAGS"
+        CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS"
+        ;;        
+    esac            
+
+    AC_CHECK_PROGS(CC, $CC "${target_alias}-gcc" "${target}-gcc", echo)
+    unset ac_cv_prog_CC
+    AC_PROG_CC
+    if test -n "$USE_CPLUS"; then
+        AC_CHECK_PROGS(CXX, $CXX "${target_alias}-g++" "${target}-g++", echo)
+        unset ac_cv_prog_CXX
+        AC_PROG_CXX
+    fi
+
+    case "$build:$target" in
+      powerpc-apple-darwin8*:i?86-apple-darwin*)
+        dnl Revert the changes made above.  From this point on, the target
+        dnl compiler will never be used without applying the SDK to CFLAGS
+        dnl (see --with-macos-sdk below).
+        CFLAGS=$_SAVE_CFLAGS
+        CXXFLAGS=$_SAVE_CXXFLAGS
+        ;;
+    esac
+
+    AC_CHECK_PROGS(RANLIB, $RANLIB "${target_alias}-ranlib" "${target}-ranlib", echo)
+    AC_CHECK_PROGS(AR, $AR "${target_alias}-ar" "${target}-ar", echo)
+    AC_CHECK_PROGS(AS, $AS "${target_alias}-as" "${target}-as", echo)
+    AC_CHECK_PROGS(LD, $LD "${target_alias}-ld" "${target}-ld", echo)
+    AC_CHECK_PROGS(STRIP, $STRIP "${target_alias}-strip" "${target}-strip", echo)
+    AC_CHECK_PROGS(WINDRES, $WINDRES "${target_alias}-windres" "${target}-windres", echo)
+
+else
+    AC_PROG_CC
+    if test -n "$USE_CPLUS"; then
+        if test "$CC" = "cl" -a -z "$CXX"; then
+            CXX=$CC
+        else        
+            AC_PROG_CXX
+        fi
+    fi
+    AC_PROG_CPP
+    AC_PROG_RANLIB
+    AC_PATH_PROGS(AS, as, $CC)
+    AC_PATH_PROGS(AR, ar, echo not_ar)
+    AC_PATH_PROGS(LD, ld link, echo not_ld)
+    AC_PATH_PROGS(STRIP, strip, echo not_strip)
+    AC_PATH_PROGS(WINDRES, windres, echo not_windres)
+    if test -z "$HOST_CC"; then
+        HOST_CC="$CC"
+    fi
+    if test -z "$HOST_CFLAGS"; then
+        HOST_CFLAGS="$CFLAGS"
+    fi
+fi
+
+if test "$GCC" = "yes"; then
+    GNU_CC=1
+fi
+if test "$GXX" = "yes"; then
+    GNU_CXX=1
+fi
+if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then
+    GNU_AS=1
+fi
+rm -f a.out
+
+case "$build:$target" in
+    i?86-apple-darwin*:powerpc-apple-darwin*)
+        dnl cross_compiling will have erroneously been set to "no" in this
+        dnl case, because the x86 build host is able to run ppc code in a
+        dnl translated environment, making a cross compiler appear native.
+        cross_compiling=yes
+        ;;
+esac
+
+if test "$cross_compiling"  = "yes"; then
+    CROSS_COMPILE=1
+else
+    CROSS_COMPILE=
+fi
+
+dnl ========================================================
+dnl Check for gcc -pipe support
+dnl ========================================================
+AC_MSG_CHECKING([for gcc -pipe support])
+if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then
+    echo '#include <stdio.h>' > dummy-hello.c
+    echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c
+    ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5
+    cat dummy-hello.s | ${AS} -o dummy-hello.S - 2>&5
+    if test $? = 0; then
+        _res_as_stdin="yes"
+    else
+        _res_as_stdin="no"
+    fi
+    if test "$_res_as_stdin" = "yes"; then
+        _SAVE_CFLAGS=$CFLAGS
+        CFLAGS="$CFLAGS -pipe"
+        AC_TRY_COMPILE( [ #include <stdio.h> ],
+            [printf("Hello World\n");],
+            [_res_gcc_pipe="yes"],
+            [_res_gcc_pipe="no"] )
+        CFLAGS=$_SAVE_CFLAGS
+    fi
+    if test "$_res_as_stdin" = "yes" && test "$_res_gcc_pipe" = "yes"; then
+        _res="yes";
+        CFLAGS="$CFLAGS -pipe"
+        CXXFLAGS="$CXXFLAGS -pipe"
+    else
+        _res="no"
+    fi
+    rm -f dummy-hello.c dummy-hello.s dummy-hello.S dummy-hello a.out
+    AC_MSG_RESULT([$_res])
+else
+    AC_MSG_RESULT([no])
+fi
+
+dnl ========================================================
+dnl Profile guided optimization
+dnl ========================================================
+dnl Test for profiling options
+dnl Under gcc 3.4+, use -fprofile-generate/-fprofile-use
+
+_SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction"
+
+AC_MSG_CHECKING([whether C compiler supports -fprofile-generate])
+AC_TRY_COMPILE([], [return 0;],
+               [ PROFILE_GEN_CFLAGS="-fprofile-generate"
+                 result="yes" ], result="no")
+AC_MSG_RESULT([$result])
+
+if test $result = "yes"; then
+   PROFILE_GEN_LDFLAGS="-fprofile-generate"
+   PROFILE_USE_CFLAGS="-fprofile-use -fprofile-correction -Wcoverage-mismatch -freorder-blocks-and-partition"
+   PROFILE_USE_LDFLAGS="-fprofile-use"
+fi
+
+CFLAGS="$_SAVE_CFLAGS"
+
+dnl ===============================================================
+dnl Check for .hidden assembler directive and visibility attribute.
+dnl Borrowed from glibc configure.in
+dnl ===============================================================
+if test "$GNU_CC"; then
+    AC_CACHE_CHECK(for visibility(hidden) attribute,
+        ac_cv_visibility_hidden,
+        [cat > conftest.c <<EOF
+        int foo __attribute__ ((visibility ("hidden"))) = 1;
+EOF
+        ac_cv_visibility_hidden=no
+        if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+            if grep '\.hidden.*foo' conftest.s >/dev/null; then
+                ac_cv_visibility_hidden=yes
+            fi
+        fi
+        rm -f conftest.[cs]
+        ])
+    if test "$ac_cv_visibility_hidden" = "yes"; then
+        AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
+        AC_CACHE_CHECK(for visibility pragma support,
+            ac_cv_visibility_pragma,
+            [cat > conftest.c <<EOF
+#pragma GCC visibility push(hidden)
+            int foo_hidden = 1;
+#pragma GCC visibility push(default)
+            int foo_default = 1;
+EOF
+            ac_cv_visibility_pragma=no
+            if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+                if grep '\.hidden.*foo_hidden' conftest.s >/dev/null; then
+                    if ! grep '\.hidden.*foo_default' conftest.s > /dev/null; then
+                        ac_cv_visibility_pragma=yes
+                    fi
+                fi
+            fi
+            rm -f conftest.[cs]
+            ])
+        if test "$ac_cv_visibility_pragma" = "yes"; then
+            AC_DEFINE(HAVE_VISIBILITY_PRAGMA)
+            # To work around a build problem on Linux x86-64 (Bugzilla bug
+            # 293438), we use the -fvisibility=hidden flag.  This flag is less
+            # optimal than #pragma GCC visibility push(hidden) because the flag
+            # assumes that symbols defined outside the current source file have
+            # the default visibility.  This has the advantage that we don't need
+            # to wrap system header files, but has the disadvantage that calls
+            # to hidden symbols defined in other source files cannot be
+            # optimized by the compiler.  The -fvisibility=hidden flag does
+            # hide and export symbols correctly.
+            #VISIBILITY_FLAGS='-I$(dist_includedir)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
+            #WRAP_SYSTEM_INCLUDES=1
+            VISIBILITY_FLAGS="-fvisibility=hidden"
+            WRAP_SYSTEM_INCLUDES=
+        fi
+    fi
+fi # GNU_CC
+
+fi # SKIP_COMPILER_CHECKS
+
+dnl ========================================================
+dnl Checks for programs.
+dnl ========================================================
+if test -z "$SKIP_PATH_CHECKS"; then
+    AC_PATH_PROGS(PERL, perl5 perl, echo not_perl)
+elif test -z "$PERL"; then
+    PERL=perl
+fi
+
+dnl ========================================================
+dnl Default platform specific options
+dnl ========================================================
+OBJ_SUFFIX=o
+LIB_SUFFIX=a
+DLL_SUFFIX=so
+ASM_SUFFIX=s
+MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@'
+PR_MD_ASFILES=
+PR_MD_CSRCS=
+PR_MD_ARCH_DIR=unix
+AR_FLAGS='cr $@'
+AS='$(CC)'
+ASFLAGS='$(CFLAGS)'
+
+if test -n "$CROSS_COMPILE"; then
+    OS_ARCH=`echo $target_os | sed -e 's|/|_|g'`
+    OS_RELEASE=
+    OS_TEST="${target_cpu}"
+    case "${target_os}" in
+        linux*)       OS_ARCH=Linux ;;
+        solaris*)     OS_ARCH=SunOS OS_RELEASE=5 ;;
+        mingw*)       OS_ARCH=WINNT ;;
+        wince*)       OS_ARCH=WINCE ;;
+        winmo*)       OS_ARCH=WINCE ;;
+        darwin*)      OS_ARCH=Darwin ;;
+        riscos*)      OS_ARCH=RISCOS ;;
+    esac
+else
+    OS_ARCH=`uname -s | sed -e 's|/|_|g'`
+    OS_RELEASE=`uname -r`
+    OS_TEST=`uname -m`
+fi
+
+if test "$OS_ARCH" = "IRIX64"; then
+    OS_ARCH=IRIX
+fi
+
+if test "$OS_ARCH" = "AIX"; then
+    OS_RELEASE=`uname -v`.`uname -r`
+fi
+
+if test "$OS_ARCH" = "FreeBSD"; then
+    OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'`
+fi
+
+if test "$OS_ARCH" = "Linux"; then
+    OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'`
+    OS_RELEASE=`echo $OS_RELEASE | awk -F\. '{ print $1 "." $2 }'`
+fi
+
+#######################################################################
+# Master "Core Components" macros for getting the OS target           #
+#######################################################################
+
+#
+# Note: OS_TARGET should be specified on the command line for gmake.
+# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built.
+# The difference between the Win95 target and the WinNT target is that
+# the WinNT target uses Windows NT specific features not available
+# in Windows 95. The Win95 target will run on Windows NT, but (supposedly)
+# at lesser performance (the Win95 target uses threads; the WinNT target
+# uses fibers).
+#
+# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no
+# cross-compilation.
+#
+
+#
+# The following hack allows one to build on a WIN95 machine (as if
+# s/he were cross-compiling on a WINNT host for a WIN95 target).
+# It also accomodates for MKS's uname.exe.  If you never intend
+# to do development on a WIN95 machine, you don't need this hack.
+#
+case "$OS_ARCH" in
+WIN95)
+    OS_ARCH=WINNT
+    OS_TARGET=WIN95
+    ;;
+Windows_95)
+    OS_ARCH=Windows_NT
+    OS_TARGET=WIN95
+    ;;
+Windows_98)
+    OS_ARCH=Windows_NT
+    OS_TARGET=WIN95
+    ;;
+CYGWIN_9*|CYGWIN_ME*)
+    OS_ARCH='CYGWIN_NT-4.0'
+    OS_TARGET=WIN95
+    ;;
+OS_2)
+    OS_ARCH=OS2
+    OS_TARGET=OS2
+    ;;
+esac
+
+#
+# On WIN32, we also define the variable CPU_ARCH.
+#
+
+case "$OS_ARCH" in
+WINNT)
+    CPU_ARCH=`uname -p`
+    if test "$CPU_ARCH" = "I386"; then
+        CPU_ARCH=x86
+    fi
+    ;;
+Windows_NT)
+#
+# If uname -s returns "Windows_NT", we assume that we are using
+# the uname.exe in MKS toolkit.
+#
+# The -r option of MKS uname only returns the major version number.
+# So we need to use its -v option to get the minor version number.
+# Moreover, it doesn't have the -p option, so we need to use uname -m.
+#
+    OS_ARCH=WINNT
+    OS_MINOR_RELEASE=`uname -v`
+    if test "$OS_MINOR_RELEASE" = "00"; then
+        OS_MINOR_RELEASE=0
+    fi
+    OS_RELEASE="${OS_RELEASE}.${OS_MINOR_RELEASE}"
+    CPU_ARCH=`uname -m`
+    #
+    # MKS's uname -m returns "586" on a Pentium machine.
+    #
+    if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    fi
+    ;;
+CYGWIN_NT*|MINGW*_NT*)
+#
+# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using
+# the uname.exe in the Cygwin tools.
+# If uname -s returns MINGW32_NT-5.1, we assume that we are using
+# the uname.exe in the MSYS tools.
+#
+    OS_RELEASE=`expr $OS_ARCH : '.*NT-\(.*\)'`
+    OS_ARCH=WINNT
+    CPU_ARCH=`uname -m`
+    #
+    # Cygwin's uname -m returns "i686" on a Pentium Pro machine.
+    #
+    if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    fi
+    ;;
+esac
+
+if test -n "$MOZILLA_CLIENT" && test "$OS_ARCH" = "WINNT"; then
+    OS_TARGET=WIN95
+    if test -n "$MOZ_DEBUG"; then
+        USE_DEBUG_RTL=1
+    fi
+fi
+if test -z "$OS_TARGET"; then
+    OS_TARGET=$OS_ARCH
+fi
+if test "$OS_TARGET" = "WIN95"; then
+    OS_RELEASE="4.0"
+fi
+OS_CONFIG="${OS_TARGET}${OS_RELEASE}"
+
+dnl ========================================================
+dnl Enable high-memory support on OS/2 by default.
+dnl ========================================================
+AC_ARG_ENABLE(os2-high-mem,
+    [  --disable-os2-high-mem  Disable high-memory support on OS/2],
+    [ if test "$enableval" = "no"; then
+        MOZ_OS2_HIGH_MEMORY=
+      else
+        MOZ_OS2_HIGH_MEMORY=1
+      fi ])
+
+dnl ========================================================
+dnl = Enable building the Thumb2 instruction set
+dnl ========================================================
+AC_ARG_ENABLE(thumb2,
+ [  --enable-thumb2              Enable Thumb2 instruction set],
+ [ if test "$enableval" = "yes"; then
+     MOZ_THUMB2=1,
+   fi ])
+
+if test -n "$MOZ_THUMB2"; then
+  case "$target_cpu" in
+    arm*)
+      if test "$GNU_CC"; then
+        CFLAGS="$CFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
+        CXXFLAGS="$CXXFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
+        ASFLAGS="$ASFLAGS -march=armv7-a -mthumb"
+      else
+        AC_MSG_ERROR([--enable-thumb2 is not supported for non-GNU toolchains])
+      fi
+    ;;
+    *)
+      AC_MSG_ERROR([--enable-thumb2 is not supported for non-ARM CPU architectures])
+    ;;
+  esac
+fi
+
+dnl ========================================================
+dnl Override of system specific host options
+dnl ========================================================
+case "$host" in
+*-mingw*)
+    NSINSTALL=nsinstall
+    ;;
+*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*)
+    NSINSTALL='$(CYGWIN_WRAPPER) nsinstall'
+    if test `echo "${PATH}" | grep -c \;` = 0; then
+        CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper'
+    fi
+    ;;
+*-beos*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE"
+    ;;
+*os2*)
+    ;;
+*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX"
+    ;;
+esac
+
+dnl ========================================================
+dnl Override of system specific target options
+dnl ========================================================
+case "$target" in
+
+*-aix*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(AIX)
+    AC_DEFINE(SYSV)
+    DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib'
+    AC_CHECK_HEADER(sys/atomic_op.h, AC_DEFINE(AIX_HAVE_ATOMIC_OP_H))
+    case "${target_os}" in
+    aix3.2*)
+        AC_DEFINE(AIX_RENAME_SELECT)
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        AIX_LINK_OPTS='-bnso -berok'
+        PR_MD_ASFILES=os_AIX.s
+        ;;
+    aix4.1*)
+        AC_DEFINE(AIX_TIMERS)
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        AC_DEFINE(AIX4_1)
+        MKSHLIB=
+        DSO_LDOPTS=
+        AIX_LINK_OPTS='-bnso -berok'
+        LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)_shr'
+        LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)_shr'
+        ;;
+    aix4.2*)
+        AC_DEFINE(AIX_TIMERS)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    aix4.3*)
+        AC_DEFINE(AIX_TIMERS)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AC_DEFINE(AIX4_3_PLUS)
+        AC_DEFINE(HAVE_SOCKLEN_T)
+        AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+        USE_IPV6=1
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    *)
+        AC_DEFINE(AIX_TIMERS)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AC_DEFINE(AIX4_3_PLUS)
+        AC_DEFINE(HAVE_SOCKLEN_T)
+        AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+        USE_IPV6=1
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    esac
+    CFLAGS="$CFLAGS -qro -qroconst"
+    AIX_WRAP='$(DIST)/lib/aixwrap.o'
+    AIX_TMP='./_aix_tmp.o'
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_aix64.cfg
+        OBJECT_MODE=64
+    else
+        MDCPUCFG_H=_aix32.cfg
+    fi
+    PR_MD_CSRCS=aix.c
+    RESOLVE_LINK_SYMBOLS=1
+    ;;
+        
+*-beos*)
+    AC_DEFINE(XP_BEOS)
+    AC_DEFINE(BeOS)
+    AC_DEFINE(BEOS)
+    AC_DEFINE(_POSIX_SOURCE)
+    DSO_LDOPTS=-nostart
+    MDCPUCFG_H=_beos.cfg
+    USE_BTHREADS=1
+    PR_MD_ARCH_DIR=beos
+    RESOLVE_LINK_SYMBOLS=1
+    case "${target_cpu}" in
+    i*86)
+        _OPTIMIZE_FLAGS=-O2
+        _DEBUG_FLAGS='-gdwarf-2 -O0'
+        MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@'
+        AC_CHECK_LIB(bind, gethostbyaddr, [OS_LIBS="$OS_LIBS -lbind -lsocket"])
+        ;;
+    powerpc)
+        CC=mwcc
+        CCC=mwcc
+        LD=mwld
+        DSO_LDOPTS='-xms -export pragma -init _init_routine_ -term _term_routine_ -lroot -lnet /boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o /boot/develop/lib/ppc/start_dyn.o'
+        _OPTIMIZE_FLAGS=-O2    
+        _DEBUG_FLAGS='-g -O0'
+        ;;
+    esac
+    ;;
+
+*-bsdi*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(BSDI)
+    AC_DEFINE(NEED_BSDREGEX)
+
+    CFLAGS="$CFLAGS -Wall -Wno-format"
+    CXXFLAGS="$CXXFLAGS -Wall -Wno-format"
+
+    if echo "$OS_TEST" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    elif echo "$OS_TEST" | grep -c sparc >/dev/null; then 
+        CPU_ARCH=sparc
+    fi
+
+    MDCPUCFG_H=_bsdi.cfg
+    PR_MD_CSRCS=bsdi.c
+
+    DSO_LDOPTS=-r
+
+    case "$target_os" in
+    bsdi1.1*)
+        AC_DEFINE(_PR_BSDI_JMPBUF_IS_ARRAY)
+        AC_DEFINE(_PR_STAT_HAS_ONLY_ST_ATIME)
+        AC_DEFINE(_PR_NEED_H_ERRNO)
+        MKSHLIB=
+        DSO_CFLAGS=
+        DSO_LDOPTS=
+        ;;
+
+    bsdi2.1*)
+        AC_DEFINE(_PR_TIMESPEC_HAS_TS_SEC)
+        AC_DEFINE(_PR_BSDI_JMPBUF_IS_ARRAY)
+        AC_DEFINE(HAVE_DLL)
+        AC_DEFINE(USE_DLFCN)
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC)
+        PR_MD_ASFILES=os_BSD_OS_386_2.s
+        ;;
+
+    bsdi4.* | bsdi5.*)
+        AC_DEFINE(_PR_SELECT_CONST_TIMEVAL)
+        AC_DEFINE(_PR_BSDI_JMPBUF_IS_STRUCT)
+        AC_DEFINE(HAVE_DLL)
+        AC_DEFINE(USE_DLFCN)
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC)
+        MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)'
+        DSO_CFLAGS=-fPIC
+        DSO_LDOPTS='-shared -Wl,-soname,$(@:$(OBJDIR)/%.so=%.so)'
+        STRIP="$STRIP -d"
+        case "$target_os" in
+        bsdi4.2* | bsdi4.3* | bsdi5.*)
+            AC_DEFINE(_PR_HAVE_GETPROTO_R)
+            AC_DEFINE(_PR_HAVE_GETPROTO_R_POINTER)
+            ;;
+        esac
+        ;;
+    *)
+        AC_DEFINE(_PR_SELECT_CONST_TIMEVAL)
+        AC_DEFINE(_PR_BSDI_JMPBUF_IS_STRUCT)
+        AC_DEFINE(HAVE_DLL)
+        AC_DEFINE(USE_DLFCN)
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC)
+        ;;
+    esac
+
+    ;;
+
+*-darwin*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(DARWIN)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    AC_DEFINE(HAVE_SOCKLEN_T)
+    AS='$(CC) -x assembler-with-cpp'
+    CFLAGS="$CFLAGS -Wall -fno-common"
+    case "${target_cpu}" in
+        i*86*)
+            if test -n "$USE_64"; then
+                CPU_ARCH=x86_64
+                CC="$CC -arch x86_64"
+            else        
+                CPU_ARCH=i386
+            fi
+            ;;
+        *)
+            CPU_ARCH=ppc
+            ;;
+    esac
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names'
+    _OPTIMIZE_FLAGS=-O2
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    STRIP="$STRIP -x -S"
+    DLL_SUFFIX=dylib
+    USE_PTHREADS=1
+    MDCPUCFG_H=_darwin.cfg
+    PR_MD_CSRCS=darwin.c
+    PR_MD_ASFILES=os_Darwin.s
+
+    # Add Mac OS X support for loading CFM & CFBundle plugins
+    if test -f "${MACOS_SDK_DIR}/System/Library/Frameworks/Carbon.framework/Carbon"; then
+        AC_DEFINE(XP_MACOSX)
+        OS_TARGET=MacOSX
+
+        if test -n "$_MACOSX_DEPLOYMENT_TARGET" ; then
+            dnl Use the specified value
+            export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET
+        elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then
+            dnl No value specified on the command line or in the environment,
+            dnl use the lesser of the library's minimum or the architecture's
+            dnl minimum.
+            case "${target_cpu}" in
+                powerpc*)
+                    dnl Architecture minimum 10.2
+                    export MACOSX_DEPLOYMENT_TARGET=10.2
+                    ;;
+                i*86*)
+                    dnl Architecture minimum 10.4
+                    export MACOSX_DEPLOYMENT_TARGET=10.4
+                    ;;
+            esac
+        fi
+
+        dnl MACOS_SDK_DIR will be set to the SDK location whenever one is
+        dnl in use.  NEXT_ROOT will be set and exported if it's needed for
+        dnl ld.
+
+        if test "$MACOS_SDK_DIR"; then
+            dnl Sync this section with the one in Mozilla's top level.
+
+            if test ! -d "$MACOS_SDK_DIR"; then
+                AC_MSG_ERROR([SDK not found.  When using --with-macos-sdk, you must
+specify a valid SDK.  SDKs are installed when the optional cross-development
+tools are selected during the Xcode/Developer Tools installation.])
+            fi
+
+            changequote(,)
+            CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'`
+            GCC_VERSION_FULL=`echo $CC_VERSION | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'`
+            GCC_VERSION=`echo $GCC_VERSION_FULL | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'`
+            changequote([,])
+            GCC_VERSION_MAJOR=`echo $GCC_VERSION_FULL | $PERL -pe 's/(^\d*).*/$1/;'`
+            if test "$GCC_VERSION_MAJOR" -lt "4" ; then
+                SDK_C_FRAMEWORK="-F${MACOS_SDK_DIR}/System/Library/Frameworks"
+                if test -d "${MACOS_SDK_DIR}/Library/Frameworks" ; then
+                    SDK_C_FRAMEWORK="$SDK_C_FRAMEWORK -F${MACOS_SDK_DIR}/Library/Frameworks"
+                fi
+
+                SDK_C_INCLUDE="-isystem ${MACOS_SDK_DIR}/usr/include/gcc/darwin/${GCC_VERSION} -isystem ${MACOS_SDK_DIR}/usr/include ${SDK_C_FRAMEWORK}"
+
+                CFLAGS="$CFLAGS -nostdinc ${SDK_C_INCLUDE}"
+
+                dnl CPP needs to be set for AC_CHECK_HEADER.
+                CPP="$CPP -nostdinc ${SDK_C_INCLUDE}"
+
+                changequote(,)
+                HOST_DARWIN_MAJOR=`echo "$build_os" | sed -E -e 's/^darwin([0-9]+).*$/\1/'`
+                changequote([,])
+                if test "$HOST_DARWIN_MAJOR" -lt 9 ; then
+                    dnl The build host is running Tiger (10.4) or earlier.
+                    dnl ld support for -syslibroot is compiler-agnostic, but
+                    dnl only available on Tiger and later.  On Tiger and
+                    dnl earlier build hosts, just rely on NEXT_ROOT, because
+                    dnl it's not been shown to cause any problems.
+                    MACOS_SDK_LIBS="-L${MACOS_SDK_DIR}/usr/lib/gcc/darwin -L${MACOS_SDK_DIR}/usr/lib/gcc/darwin/${GCC_VERSION_FULL} -L${MACOS_SDK_DIR}/usr/lib ${SDK_C_FRAMEWORK}"
+                else
+                    dnl The build host is running Leopard (10.5) or later.
+                    dnl With NEXT_ROOT set, the linker will still not apply
+                    dnl it when resolving dependencies.  This causes problems
+                    dnl on Leopard, where an SDK depends on frameworks which
+                    dnl were present in earlier OS releases (and the associated
+                    dnl SDK) but not in Leopard.  -syslibroot does not have
+                    dnl this problem, but it results in harmless warnings when
+                    dnl NEXT_ROOT is set.  NEXT_ROOT needs to remain set even
+                    dnl on Leopard because the compiler uses it too.
+                    MACOS_SDK_LIBS="-Wl,-syslibroot,${MACOS_SDK_DIR}"
+                fi
+
+                LDFLAGS="${MACOS_SDK_LIBS} $LDFLAGS"
+                export NEXT_ROOT=$MACOS_SDK_DIR
+
+                if test -n "$CROSS_COMPILE" ; then
+                    dnl NEXT_ROOT will be in the environment, but it
+                    dnl shouldn't be set for the build host.  HOST_CXX is
+                    dnl presently unused.
+                    HOST_CC="NEXT_ROOT= $HOST_CC"
+                    HOST_CXX="NEXT_ROOT= $HOST_CXX"
+                fi
+            else
+                dnl gcc >= 4.0 uses different paths than above, but knows
+                dnl how to find them itself.
+                CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}"
+
+                dnl CPP needs to be set for AC_CHECK_HEADER.
+                CPP="$CPP -isysroot ${MACOS_SDK_DIR}"
+
+                dnl If gcc >= 4.0.0, we're guaranteed to be on Tiger, which
+                dnl has an ld that supports -syslibroot.  Don't set
+                dnl NEXT_ROOT because it will be ignored and cause
+                dnl warnings when -syslibroot is specified.
+                if test "$GCC_VERSION_FULL" != "4.0.0" ; then
+                    dnl gcc > 4.0.0 will pass -syslibroot to ld automatically
+                    dnl based on the -isysroot it receives.
+                    LDFLAGS="$LDFLAGS -isysroot ${MACOS_SDK_DIR}"
+                else
+                    dnl gcc 4.0.0 doesn't pass -syslibroot to ld, it needs
+                    dnl to be explicit.
+                    LDFLAGS="$LDFLAGS -Wl,-syslibroot,${MACOS_SDK_DIR}"
+                fi
+            fi
+        fi
+    fi
+    ;;
+
+*-dgux*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(DGUX)
+    AC_DEFINE(_DGUX_SOURCE)
+    AC_DEFINE(_POSIX4A_DRAFT6_SOURCE)
+    DSO_LDOPTS=-G
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS=
+    MDCPUCFG_H=_dgux.cfg
+    PR_MD_CSRCS=dgux.c
+    ;;
+
+*-freebsd*)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(FREEBSD)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    AC_DEFINE(HAVE_SOCKLEN_T)
+    CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall"
+    MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf`
+    if test "$MOZ_OBJFORMAT" = "elf"; then
+        DLL_SUFFIX=so
+    else
+        DLL_SUFFIX=so.1.0
+    fi
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    MDCPUCFG_H=_freebsd.cfg
+    PR_MD_CSRCS=freebsd.c
+    ;;
+
+*-hpux*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(HPUX)
+    AC_DEFINE(_HPUX_SOURCE)
+    # OSF1 and HPUX report the POLLHUP event for a socket when the
+    # shutdown(SHUT_WR) operation is called for the remote end, even though
+    # the socket is still writeable. Use select(), instead of poll(), to
+    # workaround this problem.
+    AC_DEFINE(_PR_POLL_WITH_SELECT)
+    AC_DEFINE(_USE_BIG_FDS)
+    DSO_LDOPTS='-b +h $(notdir $@)'
+    PR_MD_CSRCS=hpux.c
+    if test "$OS_TEST" = "ia64"; then
+        DLL_SUFFIX=so
+        DSO_LDOPTS="$DSO_LDOPTS +b '\$\$ORIGIN'"
+        CPU_ARCH_TAG=_$OS_TEST 
+        if test -z "$USE_64"; then
+            COMPILER_TAG=_32
+        fi
+        PR_MD_ASFILES=os_HPUX_ia64.s
+    else
+        AC_DEFINE(hppa)
+        DLL_SUFFIX=sl
+        PR_MD_ASFILES=os_HPUX.s
+    fi
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_hpux64.cfg
+    else
+        MDCPUCFG_H=_hpux32.cfg
+    fi
+    if test -z "$GNU_CC"; then
+        CC="$CC -Ae"
+        CXX="$CXX -ext"
+        DSO_CFLAGS=+Z
+    else
+        DSO_CFLAGS=-fPIC
+        ASFLAGS="$ASFLAGS -x assembler-with-cpp"
+    fi
+
+    if test -n "$MOZILLA_CLIENT"; then
+        DEFAULT_IMPL_STRATEGY=_EMU
+    fi
+
+    if echo "$OS_RELEASE" | grep ^A.09 >/dev/null; then
+        AC_DEFINE(_PR_NEED_H_ERRNO)
+        AC_DEFINE(HPUX9)
+        DEFAULT_IMPL_STRATEGY=_EMU
+    	USE_NSPR_THREADS=1
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(A.09|B.10)' >/dev/null; then
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+        AC_DEFINE(_PR_NEED_H_ERRNO)
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+        AC_DEFINE(HAVE_INT_LOCALTIME_R)
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.30|B.11)' >/dev/null; then
+        AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+    fi
+
+    # HP-UX 11i v2 (B.11.23) or higher
+    changequote(<<,>>)
+    case "$OS_RELEASE" in
+    [C-Z]*|B.[2-9]*|B.1[2-9]*|B.11.[3-9]*|B.11.2[3-9]*)
+        USE_IPV6=1
+        ;;
+    esac
+    changequote([,])
+
+    if test "$OS_RELEASE" = "B.10.01"; then
+        AC_DEFINE(HPUX10)
+        DEFAULT_IMPL_STRATEGY=_EMU
+    fi
+
+    if test "$OS_RELEASE" = "B.10.10"; then
+        AC_DEFINE(HPUX10)
+        AC_DEFINE(HPUX10_10)
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$OS_RELEASE" = "B.10.20"; then
+        AC_DEFINE(HPUX10)
+        AC_DEFINE(HPUX10_20)
+        if test -z "$GNU_CC"; then
+            CFLAGS="$CFLAGS +DAportable +DS1.1"
+            CXXFLAGS="$CXXFLAGS +DAportable +DS1.1"
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$OS_RELEASE" = "B.10.30"; then
+        AC_DEFINE(HPUX10)
+        AC_DEFINE(HPUX10_30)
+        if test -z "$GNU_CC"; then
+            CFLAGS="$CFLAGS +DAportable +DS1.1"
+            CXXFLAGS="$CXXFLAGS +DAportable +DS1.1"
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if echo "$OS_RELEASE" | grep ^B.11 >/dev/null; then
+        AC_DEFINE(HPUX10)
+        AC_DEFINE(HPUX11)
+        AC_DEFINE(_LARGEFILE64_SOURCE)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+        if test -z "$GNU_CC"; then
+            if test -z "$USE_64"; then
+                if test "$OS_TEST" = "ia64"; then
+                    CFLAGS="$CFLAGS +DD32"
+                    CXXFLAGS="$CXXFLAGS +DD32"
+                else
+                    CFLAGS="$CFLAGS +DAportable +DS2.0"
+                    CXXFLAGS="$CXXFLAGS +DAportable +DS2.0"
+                fi
+            else
+                if test "$OS_TEST" = "ia64"; then
+                    CFLAGS="$CFLAGS +DD64"
+                    CXXFLAGS="$CXXFLAGS +DD64"
+                else
+                    CFLAGS="$CFLAGS +DA2.0W +DS2.0"
+                    CXXFLAGS="$CXXFLAGS +DA2.0W +DS2.0"
+                fi
+            fi
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$DEFAULT_IMPL_STRATEGY" = "_EMU"; then
+        USE_NSPR_THREADS=1
+        USE_PTHREADS=
+        USE_USER_PTHREADS=
+    elif test "$DEFAULT_IMPL_STRATEGY" = "_PTH"; then
+        USE_PTHREADS=1
+        if test "$USE_NSPR_THREADS"; then
+            USE_PTHREADS=
+        fi
+        if test "$USE_USER_PTHREADS"; then
+            USE_PTHREADS=
+        fi
+    fi
+    ;;
+
+*-irix*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(IRIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(_SGI_MP_SOURCE)
+    AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+    PR_MD_CSRCS=irix.c
+    PR_MD_ASFILES=os_Irix.s
+    MKSHLIB='$(LD) $(DSO_LDOPTS) -rdata_shared -shared -soname $(notdir $@) -o $@'
+    STRIP="$STRIP -f"
+    RESOLVE_LINK_SYMBOLS=1
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_irix64.cfg
+    else
+        MDCPUCFG_H=_irix32.cfg
+    fi
+    case "${target_os}" in
+    irix6*)
+        AC_DEFINE(IRIX6)
+        USE_PTHREADS=1
+        USE_N32=1
+        COMPILER_TAG=_n32
+        IMPL_STRATEGY=_PTH
+        ;;
+    irix5*)
+        AC_DEFINE(IRIX5)
+        USE_NSPR_THREADS=1
+        ;;
+    *)
+        USE_PTHREADS=1
+        USE_N32=1
+        ;;
+    esac
+    if test "$GNU_CC"; then
+        dnl
+        dnl If we are using gcc with native binutils, we need to
+        dnl suppress the
+        dnl #lineno "filename" num num
+        dnl lines, which confuse IRIX native as.  Add -Wp,-P to the
+        dnl gcc command line, which passes -P to the preprocessor.
+        dnl
+	    AS='$(CC) -Wp,-P -x assembler-with-cpp -D_ASM -mips2 $(INCLUDES)'
+	    CFLAGS="$CFLAGS -Wall -Wno-format"
+	    _OPTIMIZE_FLAGS="-O6"
+    else
+	    if test -n "$USE_N32"; then
+		AS='as -D_ASM $(INCLUDES) -n32'
+	    else
+		AS='as -D_ASM $(INCLUDES)'
+	    fi
+	    CFLAGS="$CFLAGS -fullwarn -xansi"
+	    if test "$USE_N32"; then
+	        _OPTIMIZE_FLAGS="-O -OPT:Olimit=4000"
+	    else
+	        _OPTIMIZE_FLAGS="-O -Olimit 4000"
+	    fi
+	    if test "$USE_MDUPDATE"; then
+                CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+	    fi
+	    case "${target}" in
+	    *-irix6.*)
+	        CFLAGS="$CFLAGS -multigot"
+	        DSO_LDOPTS="-no_unresolved"
+	        if test "$USE_N32"; then
+		        CFLAGS="$CFLAGS -n32 -woff 1209"
+		        DSO_LDOPTS="$DSO_LDOPTS -n32"
+	        else
+		        if test "$USE_64"; then
+		            CFLAGS="$CFLAGS -64"
+		        else
+		            CFLAGS="$CFLAGS -32"
+		        fi
+	        fi
+	        ;;
+	    *)
+	        CFLAGS="$CFLAGS -xgot"
+	        ;;
+	    esac
+    fi
+    if test "${target_os}" = "irix5.3"; then
+	    AC_DEFINE(IRIX5_3)
+    fi
+    case "${target_os}" in
+	irix6.5)
+	    if test -z "$GNU_CC"; then
+		    CFLAGS="$CFLAGS -mips3"
+	    fi
+	    AC_DEFINE(_PR_HAVE_GETPROTO_R)
+	    AC_DEFINE(_PR_HAVE_GETPROTO_R_POINTER)
+	    AC_DEFINE(_PR_HAVE_SGI_PRDA_PROCMASK)
+	    ;;
+	irix5*)
+	    ;;
+	*)
+	    AC_DEFINE(_PR_HAVE_SGI_PRDA_PROCMASK)
+	    ;;
+	esac
+    ;;
+
+arm-android-eabi)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+        IMPL_STRATEGY=_PTH
+    fi
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(_GNU_SOURCE)
+    AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+    AC_DEFINE(LINUX)
+    CFLAGS="$CFLAGS -Wall"
+    CXXFLAGS="$CXXFLAGS -Wall"
+    MDCPUCFG_H=_linux.cfg
+    PR_MD_CSRCS=linux.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) $(WRAP_MALLOC_LIB) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS="-g -fno-inline"  # most people on linux use gcc/gdb, and that
+                                   # combo is not yet good at debugging inlined
+                                   # functions (even when using DWARF2 as the
+                                   # debugging format)
+    COMPILER_TAG=_glibc
+    CPU_ARCH=arm
+    CPU_ARCH_TAG=_arm
+    OS_TARGET=Android
+    ;;
+
+*-linux*|*-gnu*|*-k*bsd*-gnu)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+        IMPL_STRATEGY=_PTH
+    fi
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(_GNU_SOURCE)
+    AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+    case "${target_os}" in
+    linux*)
+        AC_DEFINE(LINUX)
+        ;;
+    esac
+    CFLAGS="$CFLAGS -Wall"
+    CXXFLAGS="$CXXFLAGS -Wall"
+    MDCPUCFG_H=_linux.cfg
+    PR_MD_CSRCS=linux.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) $(WRAP_MALLOC_LIB) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS="-g -fno-inline"  # most people on linux use gcc/gdb, and that
+                                   # combo is not yet good at debugging inlined
+                                   # functions (even when using DWARF2 as the
+                                   # debugging format)
+    COMPILER_TAG=_glibc
+    if echo "$OS_TEST" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    else
+        CPU_ARCH=$OS_TEST
+    fi
+    CPU_ARCH_TAG=_${CPU_ARCH}
+    case "${target_cpu}" in
+    alpha)
+        AC_DEFINE(_ALPHA_)
+        AC_DEFINE(__alpha)
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+        ;;
+    i*86)
+        AC_DEFINE(i386)
+        PR_MD_ASFILES=os_Linux_x86.s
+        ;;
+    ia64)
+        PR_MD_ASFILES=os_Linux_ia64.s
+        ;;
+    x86_64)
+        if test -n "$USE_64"; then
+            PR_MD_ASFILES=os_Linux_x86_64.s
+        else
+            AC_DEFINE(i386)
+            PR_MD_ASFILES=os_Linux_x86.s
+            CC="$CC -m32"
+            CXX="$CXX -m32"
+        fi
+        ;;
+    ppc|powerpc)
+        PR_MD_ASFILES=os_Linux_ppc.s
+        ;;
+    powerpc64)
+        if test -n "$USE_64"; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        else
+            PR_MD_ASFILES=os_Linux_ppc.s
+        fi
+        ;;
+    m68k)
+        CFLAGS="$CFLAGS -m68020-60"
+        CXXFLAGS="$CXXFLAGS -m68020-60"
+        ;;
+    esac    
+    ;;
+
+*-mingw*|*-cygwin*|*-msvc*|*-mks*)
+    AC_DEFINE(XP_PC)
+    AC_DEFINE(WIN32)
+    PR_MD_ARCH_DIR=windows
+    RESOLVE_LINK_SYMBOLS=1
+
+    if test -n "$GNU_CC"; then
+        CC="$CC -mno-cygwin"
+        CXX="$CXX -mno-cygwin"
+        DLL_SUFFIX=dll
+        MKSHLIB='$(CC) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(IMPORT_LIBRARY) $(DLLBASE) -o $(subst $(OBJDIR)/,,$(SHARED_LIBRARY))'
+        RC=$WINDRES
+        # Use temp file for windres (bug 213281)
+        RCFLAGS='-O coff --use-temp-file'
+    else
+        CC=cl
+        CXX=cl
+        LD=link
+        AR='lib -NOLOGO -OUT:"$@"'
+        AR_FLAGS=
+        RANLIB='echo not_ranlib'
+        STRIP='echo not_strip'
+        RC=rc.exe
+        GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb'
+        OBJ_SUFFIX=obj
+        LIB_SUFFIX=lib
+        DLL_SUFFIX=dll
+
+        # Determine compiler version
+        changequote(,)
+        _MSVC_VER_FILTER='s|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p'
+        changequote([,])
+        CC_VERSION=`"${CC}" -v 2>&1 | sed -ne "$_MSVC_VER_FILTER"`
+        _CC_MAJOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $1 }'`
+        _CC_MINOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $2 }'`
+        _CC_RELEASE=`echo ${CC_VERSION} | awk -F\. '{ print $3 }'`
+        _CC_BUILD=`echo ${CC_VERSION} | awk -F\. '{ print $4 }'`
+        MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION}
+
+        if test "$_CC_MAJOR_VERSION" -eq "14"; then
+           dnl -DYNAMICBASE is only supported on VC8SP1 or newer,
+           dnl so be very specific here!
+           dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762
+           if test $_CC_RELEASE -gt 50727; then
+              _USE_DYNAMICBASE=1
+           elif test $_CC_BUILD -ge 762; then
+              _USE_DYNAMICBASE=1
+           fi
+        elif test $_CC_MAJOR_VERSION -ge 15; then
+           _USE_DYNAMICBASE=1    
+        fi
+
+        if test -n "$_USE_DYNAMICBASE"; then
+           DLLFLAGS="$DLLFLAGS -DYNAMICBASE"
+        fi
+
+        # Ensure that mt is Microsoft (R) Manifest Tool and not magnetic
+        # tape manipulation utility (or something else)
+        if test "$MSC_VER" -ge "1400"; then
+            changequote(,)
+            _MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
+            changequote([,])
+
+            MSMT_TOOL=`mt 2>&1|grep 'Microsoft (R) Manifest Tool'`
+            if test -n "$MSMT_TOOL"; then
+                MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
+                if test -z "$MSMANIFEST_TOOL_VERSION"; then
+                    AC_MSG_WARN([Unknown version of the Microsoft (R) Manifest Tool.])
+                fi
+                MT=mt
+                unset MSMT_TOOL
+            else
+                AC_MSG_ERROR([Microsoft (R) Manifest Tool must be in your \$PATH.])
+            fi
+        fi
+        
+        CFLAGS="$CFLAGS -W3 -nologo -GF -Gy"
+        DLLFLAGS="$DLLFLAGS -OUT:\"\$@\""
+        _DEBUG_FLAGS=-Zi
+        _OPTIMIZE_FLAGS=-O2
+
+        PROFILE_GEN_CFLAGS="-GL"
+        PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT"
+        PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952"
+        PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE"
+
+        if test -z "$MOZ_OPTIMIZE"; then
+            CFLAGS="$CFLAGS -Od"
+        fi
+
+        if test -n "$USE_DEBUG_RTL"; then
+            CFLAGS="$CFLAGS -MDd"
+        else
+            CFLAGS="$CFLAGS -MD"
+        fi
+
+        if test -n "$MOZ_DEBUG"; then
+            AC_DEFINE(_DEBUG)
+        else
+            DEFINES="$DEFINES -U_DEBUG"
+        fi
+
+        if test -n "$MOZ_DEBUG_SYMBOLS"; then
+            if test -n "$MOZ_OPTIMIZE"; then
+                DLLFLAGS="$DLLFLAGS -DEBUG -OPT:REF"
+                LDFLAGS="$LDFLAGS -DEBUG -OPT:REF"
+            else
+                DLLFLAGS="$DLLFLAGS -DEBUG"
+                LDFLAGS="$LDFLAGS -DEBUG"
+            fi
+        fi
+
+        OS_DLLFLAGS="-nologo -DLL -SUBSYSTEM:WINDOWS"
+        if test "$MSC_VER" -le "1200" -a -z "$MOZ_DEBUG_SYMBOLS"; then
+            OS_DLLFLAGS="$OS_DLLFLAGS -PDB:NONE"
+        fi
+        
+        if test "$OS_TARGET" = "WINNT"; then
+            CFLAGS="$CFLAGS -GT"
+            LIBNSPR='$(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+            LIBPLC='$(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        else
+            LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+            LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        fi
+    fi # GNU_CC
+
+    if test -n "$USE_STATIC_TLS"; then
+        AC_DEFINE(_PR_USE_STATIC_TLS)
+    fi
+
+    if test "$OS_TARGET" = "WINNT"; then
+        AC_DEFINE(WINNT)
+    else
+        AC_DEFINE(WIN95)
+        # undefine WINNT as some versions of mingw gcc define it by default
+        DEFINES="$DEFINES -UWINNT"
+        AC_DEFINE(_PR_GLOBAL_THREADS_ONLY)
+    fi
+
+    if test "$CPU_ARCH" = "x86"; then
+        CPU_ARCH_TAG=
+    else
+        CPU_ARCH_TAG=$CPU_ARCH
+    fi
+
+    if test -n "$USE_DEBUG_RTL"; then
+        OBJDIR_SUFFIX=OBJD
+    fi
+
+    case "$OS_TARGET" in
+    WINNT)
+	    MDCPUCFG_H=_winnt.cfg
+	    ;;
+    WIN95)
+	    MDCPUCFG_H=_win95.cfg
+	    ;;
+    *)
+	    AC_MSG_ERROR([Missing OS_TARGET for ${target}.  Use --enable-win32-target to set.])
+   	;;
+    esac
+
+    case "$target_cpu" in
+    i*86)
+	if test -n "$USE_64"; then
+	    AC_DEFINE(_AMD64_)
+	else		
+	    AC_DEFINE(_X86_)
+	fi
+        ;;
+    x86_64)
+	    AC_DEFINE(_AMD64_)
+	    USE_64=1
+	    ;;
+    ia64)
+	    AC_DEFINE(_IA64_)
+	    USE_64=1
+	    ;;
+    *)
+	    AC_DEFINE(_CPU_ARCH_NOT_DEFINED)
+	    ;;
+    esac
+    ;;
+
+*-wince*|*-winmo*)
+    AC_DEFINE(XP_PC)
+    AC_DEFINE(WIN32)
+    AC_DEFINE(WINCE)
+    AC_DEFINE(_PR_GLOBAL_THREADS_ONLY)
+
+    AR_FLAGS='-NOLOGO -OUT:"$@"'
+
+    OBJ_SUFFIX=obj
+    LIB_SUFFIX=lib
+    DLL_SUFFIX=dll
+    MKSHLIB='$(LD) -DLL $(DSO_LDOPTS) -OUT:$@'
+
+    PR_MD_ARCH_DIR=windows
+    RESOLVE_LINK_SYMBOLS=1
+
+    MDCPUCFG_H=_win95.cfg
+    LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+    LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+
+    DLLFLAGS='-OUT:"$@"'
+    if test -n "$MOZ_DEBUG_SYMBOLS"; then
+        OS_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
+        OS_DLLFLAGS='-DEBUG -DEBUGTYPE:CV'
+        DSO_LDOPTS='-DEBUG -DEBUGTYPE:CV'
+    fi
+    _DEBUG_FLAGS=-Zi
+    _OPTIMIZE_FLAGS=-O2
+    ;;
+
+*-ncr-sysv*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(NCR)
+    USE_NSPR_THREADS=1
+    if test "$OS_RELEASE" = "2.03"; then
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIM)
+    else
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIM_UNION)
+    fi
+
+    if test -z "$GNU_CC"; then
+        CFLAGS="$CFLAGS -Hnocopyr"
+        CXXFLAGS="$CXXFLAGS -Hnocopyr"
+    else
+        CFLAGS="$CFLAGS -fPIC -Wall"
+        CXXFLAGS="$CXXFLAGS -fPIC -Wall"
+        DSO_LDOPTS=-G
+    fi
+    MDCPUCFG_H=_ncr.cfg
+    PR_MD_CSRCS=ncr.c
+    ;;
+
+mips-nec-sysv*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(__SVR4)
+    AC_DEFINE(NEC)
+    AC_DEFINE(nec_ews)
+    USE_NSPR_THREADS=1
+    if test -z "$GNU_CC"; then
+        CC='$(NSDEPTH)/build/hcc cc -Xa -KGnum=0 -KOlimit=4000'
+        CXX=g++
+    fi
+    OS_LIBS="$OS_LIBS -lsocket -lnsl -ldl"
+    DSO_LDOPTS=-G
+    MDCPUCFG_H=_nec.cfg
+    PR_MD_CSRCS=nec.c
+    ;;
+
+*-netbsd*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(NETBSD)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    MDCPUCFG_H=_netbsd.cfg
+    PR_MD_CSRCS=netbsd.c
+
+    DSO_CFLAGS='-fPIC -DPIC'
+    CFLAGS="$CFLAGS -ansi -Wall"
+    CXXFLAGS="$CXXFLAGS -ansi -Wall"
+    MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)'
+
+    if test -z "$OBJECT_FMT"; then
+        if echo __ELF__ | ${CC-cc} -E - | grep -q __ELF__ 2>/dev/null; then
+            OBJECT_FMT=a.out
+            DLL_SUFFIX=so.1.0
+            DSO_LDOPTS='-shared'
+        else
+            OBJECT_FMT=ELF
+            DLL_SUFFIX=so
+            DSO_LDOPTS='-shared -Wl,-soname,$(notdir $@)'
+        fi
+    fi
+
+    if test "$LIBRUNPATH"; then
+        DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH"
+    fi
+    ;;
+
+mips-sony-newsos*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SONY)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(__svr4)
+    AC_DEFINE(__svr4__)
+    AC_DEFINE(HAVE_SVID_GETTOD)
+    USE_NSPR_THREADS=1
+    CFLAGS="$CFLAGS -Xa -fullwarn"
+    CXXFLAGS="$CXXFLAGS -Xa -fullwarn"
+    DSO_LDOPTS=-G
+    MDCPUCFG_H=_sony.cfg
+    PR_MD_CSRCS=sony.c
+    ;;
+
+*-nextstep*|*-openstep*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(NEXTSTEP)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    AC_DEFINE(_POSIX_SOURCE)
+    CFLAGS="$CFLAGS -Wall -fno-common -traditional-cpp -posix"
+    CXXFLAGS="$CXXFLAGS -Wall -fno-common -traditional-cpp -posix"
+    USE_NSPR_THREADS=1
+    DLL_SUFFIX=dylib
+    MDCPUCFG_H=_nextstep.cfg
+    PR_MD_CSRCS=nextstep.c
+    ;;
+
+
+*-nto*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(NTO)
+    AC_DEFINE(_QNX_SOURCE)
+    AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+    MDCPUCFG_H=_nto.cfg
+    PR_MD_CSRCS=nto.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(notdir $@) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS=-shared
+    OS_LIBS="$OS_LIBS -lsocket"
+    _OPTIMIZE_FLAGS="-O1"
+    _DEBUG_FLAGS="-gstabs"
+	;;
+
+*-openbsd*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(OPENBSD)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    AC_DEFINE(HAVE_SOCKLEN_T)
+    CFLAGS="$CFLAGS -ansi -Wall"
+    CXXFLAGS="$CXXFLAGS -ansi -Wall"
+    DLL_SUFFIX=so.1.0
+    DSO_CFLAGS=-fPIC
+    MDCPUCFG_H=_openbsd.cfg
+    PR_MD_CSRCS=openbsd.c
+    OS_LIBS="-lc"
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    DSO_LDOPTS='-shared -fPIC'
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    ;;
+
+*-osf*)
+    SHELL_OVERRIDE="SHELL		= /usr/bin/ksh"
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(OSF1)
+    AC_DEFINE(_REENTRANT)
+    # OSF1 and HPUX report the POLLHUP event for a socket when the
+    # shutdown(SHUT_WR) operation is called for the remote end, even though
+    # the socket is still writeable. Use select(), instead of poll(), to
+    # workaround this problem.
+    AC_DEFINE(_PR_POLL_WITH_SELECT)
+
+    if echo "$OS_RELEASE" | egrep -c '(V2.0|V3.2)' 2>/dev/null ; then
+        USE_NSPR_THREADS=1
+    fi
+
+    if test -z "$GNU_CC"; then
+        CC="$CC -std1 -ieee_with_inexact"
+        if test "$OS_RELEASE" != "V2.0"; then
+            CC="$CC -readonly_strings"
+        fi
+        _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000"
+        AC_CHECK_HEADER(machine/builtins.h, AC_DEFINE(OSF1_HAVE_MACHINE_BUILTINS_H))
+    else
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+    fi
+
+    if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then
+        AC_DEFINE(HAVE_INT_LOCALTIME_R)
+    else
+        AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+        AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+    fi
+    if echo $OS_RELEASE | grep -c V4.0 >/dev/null; then
+        AC_DEFINE(OSF1V4_MAP_PRIVATE_BUG)
+    fi
+    DSO_LDOPTS='-shared -all -expect_unresolved "*" -soname $(notdir $@)'
+    MDCPUCFG_H=_osf1.cfg
+    PR_MD_CSRCS=osf1.c
+    ;;
+
+*-qnx*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(QNX)
+    AC_DEFINE(_PR_NEED_H_ERRNO)
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_qnx.cfg
+    PR_MD_CSRCS=qnx.c
+    ;;
+
+*-riscos*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(RISCOS)
+    AC_DEFINE(_PR_NEED_H_ERRNO)
+    USE_PTHREADS=1
+    MDCPUCFG_H=_riscos.cfg
+    PR_MD_CSRCS=riscos.c
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    ;;
+
+*-*-sco*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SCO)
+    AC_DEFINE(sco)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(_SVID3)
+    AC_DEFINE(_PR_NEED_H_ERRNO)
+    CC='cc -b elf -KPIC'
+    CXX='$(NSDEPTH)/build/hcpp CC +.cpp +w'
+    USE_NSPR_THREADS=1
+    CPU_ARCH=x86
+    DSO_LDOPTS='-b elf -G'
+    MDCPUCFG_H=_scoos.cfg
+    PR_MD_SRCS=scoos.c
+    ;;
+
+*-sinix*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SNI)
+    AC_DEFINE(RELIANTUNIX)
+    AC_DEFINE(sinix)
+    AC_DEFINE(HAVE_SVID_GETTOD)
+    if echo "$OS_TEST" | grep -c 86 2>/dev/null; then
+        AC_DEFINE(i386)
+        CPU_ARCH=x86
+    else
+        CPU_ARCH=mips
+    fi
+
+    if test "$GNU_CC"; then
+        AS='$(CC) -x assembler-with-cpp'
+        if test "$CPU_ARCH" = "mips"; then
+            LD=gld
+        fi
+        CFLAGS="$CFLAGS -Wall -Wno-format"
+    else
+        AS='/usr/bin/cc'
+        _OPTIMIZE_FLAGS='-O -F Olimit,4000'
+    fi
+
+    DSO_LDOPTS='-G -z defs -h $(@:$(OBJDIR)/%.so=%.so)'
+
+    if test "$OS_RELEASE" = "5.43"; then
+        AC_DEFINE(IP_MULTICAST)
+    fi
+
+    OS_LIBS="$OS_LIBS -lsocket -lnsl -lresolv -ldl -lc"
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_reliantunix.cfg
+    PR_MD_CSRCS=reliantunix.c
+    if test "${OS_ARCH}" = "mips"; then
+        PR_MD_ASFILES=os_ReliantUNIX.s
+    fi
+    ;;
+
+*-sunos*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SUNOS4)
+    CFLAGS="$CFLAGS -Wall -Wno-format"
+    if test "$USE_MDUPDATE"; then
+        CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+    fi
+    CPU_ARCH=sparc
+    DLL_SUFFIX=so.1.0
+    DSO_LDOPTS=
+    DSO_CFLAGS=-fPIC
+    USE_NSPR_THREADS=1
+    if test "$OS_RELEASE" = "4.1.3_U1"; then
+        _OPTIMIZE_FLAGS=
+        OS_LIBS="$OS_LIBS -lm"
+    fi
+    MDCPUCFG_H=_sunos4.cfg
+    PR_MD_CSRCS=sunos4.c
+    ;;
+
+*-solaris*)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(__svr4)
+    AC_DEFINE(__svr4__)
+    AC_DEFINE(SOLARIS)
+    AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+    CPU_ARCH=`uname -p`
+    MDCPUCFG_H=_solaris.cfg
+    PR_MD_CSRCS=solaris.c
+    LD=/usr/ccs/bin/ld
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    RESOLVE_LINK_SYMBOLS=1
+    case "${OS_RELEASE}" in
+    5.8|5.9)
+        ;;
+    *)
+        # It is safe to use the -Bdirect linker flag on Solaris 10 or later.
+        USE_B_DIRECT=1
+        ;;
+    esac
+    if test -n "$GNU_CC"; then
+        DSO_CFLAGS=-fPIC
+        if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
+            GCC_USE_GNU_LD=1
+        fi
+        DSO_LDOPTS='-shared -Wl,-h,$(notdir $@),-z,combreloc,-z,defs,-z,ignore' 
+        if test -n "$USE_B_DIRECT"; then
+            DSO_LDOPTS="$DSO_LDOPTS,-Bdirect"
+        fi
+    else
+        DSO_CFLAGS=-KPIC
+        DSO_LDOPTS='-G -h $(notdir $@) -z combreloc -z defs -z ignore'
+        if test -n "$USE_B_DIRECT"; then
+            DSO_LDOPTS="$DSO_LDOPTS -Bdirect"
+        fi
+    fi
+    if test -n "$GNU_CC"; then
+        CFLAGS="$CFLAGS -Wall"
+        CXXFLAGS="$CXXFLAGS -Wall"
+        if test -n "$USE_MDUPDATE"; then
+            CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+            CXXFLAGS="$CXXFLAGS -MDupdate \$(DEPENDENCIES)"
+        fi
+        GCC_AS=`$CC -print-prog-name=as`
+        if test "`echo | $GCC_AS -v 2>&1 | grep -c GNU`" != "0"; then
+            GNU_AS=1
+        fi
+    else
+        CFLAGS="$CFLAGS -xstrconst"
+        CXXFLAGS="$CXXFLAGS -Qoption cg -xstrconst -features=tmplife"
+        if test -z "$MOZ_OPTIMIZE"; then
+            CFLAGS="$CFLAGS -xs"
+            CXXFLAGS="$CXXFLAGS -xs"
+        fi
+        _OPTIMIZE_FLAGS=-xO4
+    fi
+    if test -z "$GNU_AS"; then
+        ASFLAGS="$ASFLAGS -Wa,-P"
+    fi
+    if test -n "$USE_64"; then
+        if test -n "$GNU_CC"; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        else
+            if test "$OS_TEST" = "i86pc"; then
+                CC="$CC -xarch=amd64"
+                CXX="$CXX -xarch=amd64"
+            else
+                CC="$CC -xarch=v9"
+                CXX="$CXX -xarch=v9"
+            fi
+        fi
+    fi
+    if test "$OS_TEST" = "i86pc"; then
+        if test -z "$USE_64"; then
+            AC_DEFINE(i386)
+        fi
+        CPU_ARCH_TAG=_$OS_TEST
+        # The default debug format, DWARF (-g), is not supported by gcc
+        # on i386-ANY-sysv4/solaris, but the stabs format is.  It is
+        # assumed that the Solaris assembler /usr/ccs/bin/as is used.
+        # If your gcc uses GNU as, you do not need the -Wa,-s option.
+        if test -n "$MOZ_DEBUG" && test -n "$GNU_CC"; then
+            _DEBUG_FLAGS=-gstabs
+            if test -z "$GNU_AS"; then
+                _DEBUG_FLAGS="$_DEBUG_FLAGS -Wa,-s"
+            fi
+        fi
+    fi
+    case "${target_os}" in
+    solaris2.3*)
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        ;;
+    solaris2.4*)
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        ;;
+    solaris2.5*)
+        AC_DEFINE(SOLARIS2_5)    
+        ;;
+    *)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        # The lfcompile64(5) man page on Solaris 2.6 says:
+        #     For applications that do not wish to conform to the POSIX or
+        #     X/Open  specifications,  the  64-bit transitional interfaces
+        #     are available by default.  No compile-time flags need to  be
+        #     set.
+        # But gcc 2.7.2.x fails to define _LARGEFILE64_SOURCE by default.
+        # The native compiler, gcc 2.8.x, and egcs don't have this problem.
+        if test -n "$GNU_CC"; then
+            AC_DEFINE(_LARGEFILE64_SOURCE)
+        fi
+        ;;
+    esac
+    case "${target_os}" in
+    solaris2.3*)
+        ;;
+    solaris2.4*)
+        ;;
+    solaris2.5*)
+        ;;
+    solaris2.6*)
+        ;;
+    solaris2.7*)
+        ;;
+    *)
+        # Solaris 8 or higher has IPv6.
+        AC_DEFINE(_PR_INET6)
+        ;;
+    esac
+    if test "$CPU_ARCH" = "sparc"; then
+        # 64-bit Solaris SPARC requires V9 architecture, so the following
+        # is not needed.
+        if test -z "$USE_64"; then
+            ULTRASPARC_LIBRARY=nspr_flt
+        fi
+    fi
+    # Purify requires that binaries linked against nspr also
+    # be linked against -lrt (or -lposix4) so add it to OS_LIBS
+    _rev=`uname -r`
+    _librt=`echo $_rev 5.6 | awk '{ if ($1 > $2) print "-lrt"; else print "-lposix4" }'`
+    OS_LIBS="$OS_LIBS $_librt"
+    ;;
+
+*-sco-sysv5*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(UNIXWARE)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SYSV)
+    USE_NSPR_THREADS=1
+    if echo $OS_RELEASE | grep -c 2.1 2>/dev/null; then
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        CC='$(NSDEPTH)/build/hcc cc'
+        CXX='$(NSDEPTH)/build/hcpp CC'
+        MDCPUCFG_H=_unixware.cfg
+    else
+        AC_DEFINE(_LARGEFILE64_SOURCE)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AC_DEFINE(_PR_HAVE_SOCKADDR_LEN)
+        MDCPUCFG_H=_unixware7.cfg
+    fi
+    PR_MD_CSRCS=unixware.c
+    DSO_LDOPTS=-G
+    CPU_ARCH=x86
+    ;;
+
+*-symbian*)
+    AC_ARG_WITH(symbian-sdk,
+    [  --with-symbian-sdk=SYMBIAN_SDK_DIR
+                          The path to the Symbian SDK],
+    SYMBIAN_SDK_DIR=$withval)
+
+    echo -----------------------------------------------------------------------------
+    echo Building with Symbian SDK in: $SYMBIAN_SDK_DIR
+    echo -----------------------------------------------------------------------------
+
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SYMBIAN)
+    AC_DEFINE(__arm__)
+    AC_DEFINE(__SYMBIAN32__)
+    AC_DEFINE(_UNICODE)
+    AC_DEFINE(NDEBUG)
+    AC_DEFINE(__SUPPORT_CPP_EXCEPTIONS__)
+    AC_DEFINE(MOZ_STDERR_TO_STDOUT)
+    AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+    AC_DEFINE(HAVE_SOCKLEN_T)
+    USE_PTHREADS=1
+    LIB_SUFFIX=lib
+    DLL_SUFFIX=dll
+    MKSHLIB=
+    DSO_LDOPTS=
+    DSO_CFLAGS=
+    VISIBILITY_FLAGS=
+    MDCPUCFG_H=_symbian.cfg
+    PR_MD_CSRCS=symbian.c
+    NSINSTALL=nsinstall
+    RANLIB='echo no ranlib '
+    CPU_ARCH=ARM
+    OS_ARCH=SYMBIAN
+    OS_EXE_CFLAGS="$OS_EXE_CFLAGS -D__EXE__"
+    CFLAGS="$CFLAGS -MD -nostdinc"
+    SYMBIAN_SYS_INCLUDE="-I$SYMBIAN_SDK_DIR/Epoc32/include/variant -I$SYMBIAN_SDK_DIR/Epoc32/include -I$SYMBIAN_SDK_DIR/Epoc32/include/stdapis"
+    echo -------------------------------------------------------
+    echo SYMBIAN_SYS_INCLUDE is: $SYMBIAN_SYS_INCLUDE
+    echo -------------------------------------------------------
+    case "$OS_TARGET" in
+    WINSCW)
+        CC=mwccsym2.exe
+        CXX=mwccsym2.exe
+        LD=mwldsym2.exe
+        AR=mwldsym2.exe
+        WINSCW_LD_DIR="\$(SYMBIAN_SDK_DIR)/EPOC32/RELEASE/WINSCW/UDEB"
+        CFLAGS="$CFLAGS -O0 -inline off -wchar_t off -align 4 -warnings on -w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostderr -gccdep -cwd source -i- -I\$(VPATH)"
+        SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include Symbian_OS_v9.2.hrh"
+        AR_FLAGS="-library -msgstyle gcc -stdlib -subsystem windows -noimplib -o \$@"
+        AC_DEFINE(_DEBUG)
+        AC_DEFINE(__CW32__)
+        AC_DEFINE(__WINS__)
+        AC_DEFINE(__WINSCW__)
+        DEFINES="$DEFINES -U_WIN32"
+	    ;;
+    GCCE)
+        CFLAGS="$CFLAGS -Wall -Wno-unknown-pragmas -fexceptions -march=armv5t -mapcs -pipe -x c -msoft-float"
+        CXXFLAGS="$CXXFLAGS $CFLAGS -Wno-ctor-dtor-privacy"
+        SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include $SYMBIAN_SDK_DIR/EPOC32/INCLUDE/GCCE/GCCE.h"
+        AC_DEFINE(__GCCE__)
+        AC_DEFINE(__EABI__)
+        DEFINES="$DEFINES -D__PRODUCT_INCLUDE__=$SYMBIAN_SDK_DIR/Epoc32/include/variant/Symbian_OS_v9.2.hrh"
+	    ;;
+    *)
+	    AC_MSG_ERROR([Missing OS_TARGET for ${target}. Set --enable-symbian-target to with 'WINSCW' or 'GCCE'.])
+   	;;
+    esac
+    CFLAGS="$CFLAGS ${SYMBIAN_SYS_INCLUDE}"
+    ;;
+
+*-os2*)
+    AC_DEFINE(XP_OS2)
+    AC_DEFINE(XP_PC)
+    AC_DEFINE(BSD_SELECT)
+    AC_DEFINE(TCPV40HDRS)
+    LIB_SUFFIX=lib
+    DLL_SUFFIX=dll
+    RC=rc.exe
+    PR_MD_ARCH_DIR=os2
+    PROG_SUFFIX=.exe
+    NSINSTALL=nsinstall
+    MDCPUCFG_H=_os2.cfg
+    RESOLVE_LINK_SYMBOLS=1
+
+    AC_DEFINE(OS2)
+    AR=emxomfar
+    AR_FLAGS='r $@'
+    CFLAGS="$CFLAGS -Wall -Zomf"
+    CXXFLAGS="$CFLAGS -Wall -Zomf"
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    DSO_CFLAGS=
+    DSO_LDOPTS='-Zomf -Zdll'
+    LDFLAGS='-Zmap'
+    _OPTIMIZE_FLAGS="-O2 -s"
+    _DEBUG_FLAGS="-g -fno-inline"
+    if test -n "$MOZ_OPTIMIZE"; then
+      DSO_LDOPTS="$DSO_LDOPTS -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
+    fi
+    IMPLIB='emximp -o'
+    FILTER='emxexp -o'
+    if test -n "$MOZ_OS2_HIGH_MEMORY"; then
+      LDFLAGS="$LDFLAGS -Zhigh-mem"
+      AC_DEFINE(MOZ_OS2_HIGH_MEMORY)
+    fi
+
+    # GCC for OS/2 currently predefines these, but we don't want them
+    DEFINES="$DEFINES -Uunix -U__unix -U__unix__"
+    ;;
+
+*)
+    AC_DEFINE(XP_UNIX)
+    ;;
+   
+esac
+
+if test -z "$SKIP_LIBRARY_CHECKS"; then
+dnl ========================================================
+dnl Check for system libraries
+dnl ========================================================
+dnl AC_CHECK_LIB(C, main)
+dnl AC_CHECK_LIB(C_r, main)
+dnl AC_CHECK_LIB(c, main)
+dnl AC_CHECK_LIB(c_r, main)
+dnl AC_CHECK_LIB(dce, main)
+dnl AC_CHECK_LIB(dl, main)
+dnl AC_CHECK_LIB(dld, main)
+dnl AC_CHECK_LIB(gen, main)
+dnl AC_CHECK_LIB(ip6, main)
+dnl AC_CHECK_LIB(l, main)
+dnl AC_CHECK_LIB(m, main)
+dnl AC_CHECK_LIB(nsl, main)
+dnl AC_CHECK_LIB(posix4, main)
+dnl AC_CHECK_LIB(prstrms, main)
+dnl AC_CHECK_LIB(prstrms_shr, main)
+dnl AC_CHECK_LIB(pthread, main)
+dnl AC_CHECK_LIB(pthreads, main)
+dnl AC_CHECK_LIB(resolv, main)
+dnl AC_CHECK_LIB(rt, main)
+dnl AC_CHECK_LIB(socket, main)
+dnl AC_CHECK_LIB(svld, main)
+dnl AC_CHECK_LIB(thread, main)
+dnl AC_CHECK_LIB(vms_jackets, main)
+
+
+dnl We don't want anything to link with libdl even if it's present on OS X, 
+dnl since it's not used and not part of the default installation.
+dnl The same goes for BeOS.
+dnl OS/2 has dlfcn in libc.
+
+case $target in
+*-darwin*|*-beos*|*-os2*)
+    ;;
+*)
+    AC_CHECK_LIB(dl, dlopen,
+        AC_CHECK_HEADER(dlfcn.h,
+            OS_LIBS="-ldl $OS_LIBS"))
+    ;;
+esac
+
+
+dnl ========================================================
+dnl Check for system header files.
+dnl ========================================================
+dnl AC_HEADER_DIRENT
+dnl AC_HEADER_STDC
+dnl AC_HEADER_SYS_WAIT
+dnl AC_CHECK_HEADERS(fcntl.h limits.h sys/file.h sys/ioctl.h sys/time.h unistd.h)
+
+dnl ========================================================
+dnl Check for typedefs and structs
+dnl ========================================================
+dnl AC_C_CONST
+dnl AC_TYPE_UID_T
+dnl AC_TYPE_MODE_T
+dnl AC_TYPE_OFF_T
+dnl AC_TYPE_PID_T
+dnl AC_TYPE_SIZE_T
+dnl AC_STRUCT_ST_BLKSIZE
+dnl AC_STRUCT_ST_BLOCKS
+dnl AC_STRUCT_ST_RDEV
+dnl AC_HEADER_TIME
+dnl AC_STRUCT_TM
+
+dnl ========================================================
+dnl Checks for library functions.
+dnl ========================================================
+AC_PROG_GCC_TRADITIONAL
+AC_CHECK_FUNCS(lchown strerror)
+
+dnl AC_FUNC_MEMCMP
+dnl AC_FUNC_MMAP
+dnl AC_FUNC_SETVBUF_REVERSED
+dnl AC_FUNC_STRCOLL
+dnl AC_FUNC_STRFTIME
+dnl AC_FUNC_UTIME_NULL
+dnl AC_FUNC_VPRINTF
+dnl AC_CHECK_FUNCS(ftime getcwd gethostname gettimeofday getwd mkdir mktime putenv rmdir select socket strdup strerror strstr strtol strtoul uname)
+
+dnl ========================================================
+dnl Check options
+dnl ========================================================
+
+dnl ========================================================
+dnl =
+dnl = --enable-strip
+dnl = 
+dnl = Enable stripping of libs and executables
+dnl = 
+dnl ========================================================
+AC_ARG_ENABLE(strip,
+    [  --enable-strip          Enable stripping of shared libs and programs],
+    [ if test "$enableval" = "yes"; then
+	    ENABLE_STRIP=1
+      fi ])
+
+dnl Check for hpux options
+case "${target_os}" in
+hpux*)
+if test -z "$GNU_CC"; then
+
+    AC_CACHE_CHECK(for +Olit support,
+        ac_cv_hpux_usable_olit_option,
+        dnl since aCC doesn't throw an error on invalid options,
+        dnl we have to test this the hard way
+        [ac_cv_hpux_usable_olit_option=no
+        rm -f conftest*
+        echo 'int main() { return 0; }' | cat > conftest.c
+        ${CC-cc} ${CFLAGS} +Olit=all -o conftest conftest.c > conftest.out 2>&1
+        if test $? -eq 0; then
+            if test -z "`egrep -i '(unrecognize|unknown)' conftest.out`"; then
+                ac_cv_hpux_usable_olit_option=yes
+            fi
+        fi
+        rm -f conftest*
+        ])
+
+    if test "$ac_cv_hpux_usable_olit_option" = "yes"; then
+        CFLAGS="$CFLAGS +Olit=all"
+        CXXFLAGS="$CXXFLAGS +Olit=all"
+    else
+        CFLAGS="$CFLAGS +ESlit"
+        CXXFLAGS="$CXXFLAGS +ESlit"
+    fi
+fi
+;;
+esac
+
+dnl
+dnl Apparently, some systems cannot properly check for the pthread
+dnl library unless <pthread.h> is included so we need to test
+dnl using it
+dnl
+dnl MOZ_CHECK_PTHREADS(lib, success, failure)
+AC_DEFUN(MOZ_CHECK_PTHREADS,
+[
+AC_MSG_CHECKING([for pthread_create in -l$1])
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; then
+        AC_MSG_RESULT([yes])
+        [$2]
+    else
+        AC_MSG_RESULT([no])
+        [$3]
+    fi
+])
+
+case "$target_os" in
+darwin*)
+    _HAVE_PTHREADS=1
+    ;;
+wince*)
+    _HAVE_PTHREADS=
+    ;;
+*)
+    MOZ_CHECK_PTHREADS(pthreads,
+        _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads",
+        MOZ_CHECK_PTHREADS(pthread,
+            _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread",
+            MOZ_CHECK_PTHREADS(c_r,
+                _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r",
+                MOZ_CHECK_PTHREADS(c,
+                    _HAVE_PTHREADS=1
+                )
+            )
+        )
+    )
+    ;;
+esac
+
+AC_ARG_WITH(pthreads,
+    [  --with-pthreads         Use system pthreads library as thread subsystem],
+    [ if test "$withval" = "yes"; then
+	    if test -n "$_HAVE_PTHREADS"; then
+		    USE_PTHREADS=1 
+		    USE_USER_PTHREADS=
+		    USE_NSPR_THREADS=
+	    else
+		    AC_MSG_ERROR([ --with-pthreads specified for a system without pthread support ]);
+	    fi
+	  else
+	    USE_PTHREADS=
+	    _PTHREAD_LDFLAGS=
+	  fi],
+	[ if test -n "$_HAVE_PTHREADS" && test -z "$USE_USER_PTHREADS" && test -z "$USE_NSPR_THREADS"; then
+	    USE_PTHREADS=1
+	    USE_USER_PTHREADS=
+	    USE_NSPR_THREADS=
+	  fi])
+
+AC_ARG_ENABLE(user-pthreads,
+    [  --enable-user-pthreads  Build using userland pthreads],
+    [ if test "$enableval" = "yes"; then
+        if test -n "$_HAVE_PTHREADS"; then
+		    USE_PTHREADS=
+		    USE_USER_PTHREADS=1
+		    USE_NSPR_THREADS=
+	    else
+		    AC_MSG_ERROR([ --enable-user-pthreads specified for a system without pthread support ]);
+	    fi
+	  fi])
+
+AC_ARG_ENABLE(nspr-threads,
+    [  --enable-nspr-threads   Build using classic nspr threads],
+    [ if test "$enableval" = "yes"; then
+	    USE_PTHREADS=
+	    USE_USER_PTHREADS=
+	    USE_NSPR_THREADS=1
+	  fi])
+
+case "$target" in
+*-beos*)
+    AC_ARG_WITH(bthreads,
+    [  --with-bthreads         Use system bthreads library as thread subsystem
+                          (BeOS only)],
+    [	if test "$withval" = "yes"; then
+    	    USE_BTHREADS=1
+	        USE_USER_PTHREADS=
+	        USE_PTHREADS=
+	    fi])
+    ;;
+esac
+
+fi # SKIP_LIBRARY_CHECKS
+
+AC_ARG_ENABLE(ipv6,
+    [  --enable-ipv6           Compile ipv6 support],
+    [ if test "$enableval" = "yes"; then
+	    USE_IPV6=1
+      else
+	    USE_IPV6=
+      fi])
+
+
+AC_ARG_ENABLE(boehm,
+    [  --enable-boehm          Enable the Boehm Garbage Collector],
+    [ if test "$enableval" = "yes"; then
+        AC_DEFINE(GC_LEAK_DETECTOR)
+        GC_LEAK_DETECTOR=1
+    fi])
+
+if test -n "$USE_PTHREADS"; then
+   dnl See if -pthread is supported.
+   rm -f conftest*
+   ac_cv_have_dash_pthread=no
+   AC_MSG_CHECKING(whether ${CC-cc} accepts -pthread)
+   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
+		case "$target_os" in
+	    freebsd*)
+# Freebsd doesn't use -pthread for compiles, it uses them for linking
+            ;;
+	    *)
+            CFLAGS="$CFLAGS -pthread"
+            CXXFLAGS="$CXXFLAGS -pthread"
+            ;;
+        esac
+	fi
+    fi
+    rm -f conftest*
+    AC_MSG_RESULT($ac_cv_have_dash_pthread)
+
+	dnl
+	dnl See if -pthreads is supported.
+	dnl
+    ac_cv_have_dash_pthreads=no
+    if test "$ac_cv_have_dash_pthread" = "no"; then
+	    AC_MSG_CHECKING(whether ${CC-cc} accepts -pthreads)
+    	echo 'int main() { return 0; }' | cat > conftest.c
+	    ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1
+    	if test $? -eq 0; then
+	    	if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthreads`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then
+			    ac_cv_have_dash_pthreads=yes
+			    CFLAGS="$CFLAGS -pthreads"
+			    CXXFLAGS="$CXXFLAGS -pthreads"
+		    fi
+	    fi
+	    rm -f conftest*
+    	AC_MSG_RESULT($ac_cv_have_dash_pthreads)
+    fi
+
+    case "$target" in
+    *-solaris*)
+        if test "$ac_cv_have_dash_pthreads" = "yes"; then
+            _PTHREAD_LDFLAGS=
+        fi
+	    ;;
+    *-freebsd*)
+	    AC_DEFINE(_REENTRANT)
+	    AC_DEFINE(_THREAD_SAFE)
+	    dnl -pthread links in -lc_r, so don't specify it explicitly.
+	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS="-pthread"
+	    else
+	        _PTHREAD_LDFLAGS="-lc_r"
+	    fi
+	    ;;
+    *-netbsd*)
+	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS="-pthread"
+	    fi
+	    ;;
+    *-bsdi*)
+	    AC_DEFINE(_THREAD_SAFE)
+	    dnl -pthread links in -lc_r, so don't specify it explicitly.
+	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS=
+	    fi
+	    ;;
+    *-openbsd*)
+        if test "$ac_cv_have_dash_pthread" = "yes"; then
+            _PTHREAD_LDFLAGS=-pthread
+        fi
+        ;;
+    *-linux*|*-gnu*|*-k*bsd*-gnu)
+        AC_DEFINE(_REENTRANT)
+        ;;
+    esac
+
+else 
+    if test -n "$USE_USER_PTHREADS"; then
+	    USE_PTHREADS=
+	    USE_NSPR_THREADS=
+    else
+        _PTHREAD_LDFLAGS=
+    fi
+fi
+dnl Special thread exceptions
+
+case "$target" in
+*-aix*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    case "$target_os" in
+    aix4.1*)
+        if test -z "$USE_PTHREADS"; then
+            AC_DEFINE(AIX_RENAME_SELECT)
+        fi
+        ;;
+    aix4.2*)
+        if test -z "$USE_NSPR_THREADS"; then
+            AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+        fi
+        ;;
+    aix4.3*)
+        if test -z "$USE_NSPR_THREADS"; then
+            AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+        fi
+        if test -n "$USE_PTHREADS"; then
+            AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST)
+        fi
+        ;;
+    *)
+        if test -z "$USE_NSPR_THREADS"; then
+            AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+        fi
+        if test -n "$USE_PTHREADS"; then
+            AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST)
+        fi
+        ;;
+    esac
+    ;;
+*-bsdi*)
+    if test -n "$USE_PTHREADS"; then
+        AC_DEFINE(_PR_NEED_PTHREAD_INIT)
+    fi
+    ;;
+*-freebsd*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    ;;
+*-hpux*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi 
+    if test "$USE_PTHREADS"; then
+        if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+            AC_DEFINE(_REENTRANT)
+            AC_DEFINE(_PR_DCETHREADS)
+        else
+            AC_DEFINE_UNQUOTED(_POSIX_C_SOURCE,199506L)
+            AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST)
+        fi
+    fi
+    if test "$USE_USER_PTHREADS"; then
+        AC_DEFINE_UNQUOTED(_POSIX_C_SOURCE,199506L)
+    fi
+    ;;
+*-irix*)
+    if test "${target_os}" = "irix6.5"; then
+        if test -n "$USE_PTHREADS"; then
+            AC_DEFINE(_PR_HAVE_GETHOST_R)
+            AC_DEFINE(_PR_HAVE_GETHOST_R_POINTER)
+        fi
+    fi
+    ;;
+*-linux*|*-gnu*|*-k*bsd*-gnu)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    ;;
+*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*|*-os2*|*-beos*)
+    dnl win32, wince, os2 & beos cannot use pthreads
+    USE_PTHREADS=
+    _PTHREAD_LDFLAGS=
+    USE_USER_PTHREADS=
+    ;;
+*-netbsd*|*-openbsd*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    ;;
+*-osf*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    if test -n "$USE_PTHREADS"; then
+        if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then
+            :
+        else
+            AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST)
+        fi
+    fi
+    ;;
+*-solaris*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    if test -n "$USE_PTHREADS"; then
+        AC_DEFINE(_REENTRANT)
+        AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+        if test "$OS_TEST" = "i86pc"; then
+            if test -n "$USE_64"; then
+               PR_MD_ASFILES=os_SunOS_x86_64.s
+            else
+               PR_MD_ASFILES=os_SunOS_x86.s
+            fi
+        else
+            if test -n "$USE_64"; then
+                PR_MD_ASFILES=os_SunOS_sparcv9.s
+            fi
+        fi
+    fi
+    ;;
+*-nto*)
+    if test -n "$USE_PTHREADS"; then
+        AC_DEFINE(_PR_HAVE_GETHOST_R)
+        AC_DEFINE(_PR_HAVE_GETHOST_R_POINTER)
+    fi
+    ;;
+esac
+
+OS_LIBS="$_PTHREAD_LDFLAGS $OS_LIBS"
+
+dnl If the user passed in arg to --enable-optimize or --enable-debug,
+dnl make sure that we use it.
+if test -n "$_SAVE_OPTIMIZE_FLAGS"; then
+    _OPTIMIZE_FLAGS="$_SAVE_OPTIMIZE_FLAGS"
+fi
+
+if test -n "$_SAVE_DEBUG_FLAGS"; then
+    _DEBUG_FLAGS="$_SAVE_DEBUG_FLAGS"
+fi
+
+if test -n "$MOZ_OPTIMIZE"; then
+    CFLAGS="$CFLAGS $_OPTIMIZE_FLAGS"
+    CXXFLAGS="$CXXFLAGS $_OPTIMIZE_FLAGS"
+fi
+
+if test -n "$MOZ_DEBUG_SYMBOLS"; then
+    CFLAGS="$CFLAGS $_DEBUG_FLAGS"
+    CXXFLAGS="$CXXFLAGS $_DEBUG_FLAGS"
+fi
+
+if test -n "$MOZ_OPTIMIZE"; then
+    OBJDIR_TAG=_OPT
+else
+    OBJDIR_TAG=_DBG
+fi
+
+if test -n "$USE_64"; then
+    COMPILER_TAG=_64
+fi
+
+RELEASE_OBJDIR_NAME="${OS_CONFIG}${CPU_ARCH_TAG}${COMPILER_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}.${OBJDIR_SUFFIX}"
+
+dnl ========================================================
+dnl Use cygwin wrapper for win32 builds, except MSYS/MinGW
+dnl ========================================================
+case "$target_os" in
+cygwin*|msvc*|mks*)
+    CC="\$(CYGWIN_WRAPPER) $CC"
+    CXX="\$(CYGWIN_WRAPPER) $CXX"
+    RC="\$(CYGWIN_WRAPPER) $RC"
+    ;;
+esac
+
+dnl ========================================================
+dnl = Use malloc wrapper lib
+dnl ========================================================
+AC_ARG_ENABLE(wrap-malloc,
+[  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
+[     if test "$enableval" = "yes"; then
+	    _WRAP_MALLOC=1
+      fi ])
+
+if test -n "$_WRAP_MALLOC"; then
+    if test "$GNU_CC"; then
+       WRAP_MALLOC_CFLAGS="${LDFLAGS} -Wl,--wrap -Wl,malloc -Wl,--wrap -Wl,calloc -Wl,--wrap -Wl,valloc -Wl,--wrap -Wl,free -Wl,--wrap -Wl,realloc -Wl,--wrap -Wl,memalign -Wl,--wrap -Wl,__builtin_new -Wl,--wrap -Wl,__builtin_vec_new -Wl,--wrap -Wl,__builtin_delete -Wl,--wrap -Wl,__builtin_vec_delete -Wl,--wrap -Wl,PR_Free -Wl,--wrap -Wl,PR_Malloc -Wl,--wrap -Wl,PR_Calloc -Wl,--wrap -Wl,PR_Realloc -Wl,--wrap -Wl,strdup -Wl,--wrap -Wl,strndup -Wl,--wrap -Wl,posix_memalign"
+       DSO_LDOPTS="$DSO_LDOPTS $WRAP_MALLOC_CFLAGS"
+    else
+       AC_MSG_ERROR([--enable-wrap-malloc is not supported for non-GNU toolchains])
+    fi
+fi
+
+dnl ========================================================
+dnl = Location of malloc wrapper lib
+dnl ========================================================
+AC_ARG_WITH(wrap-malloc,
+[  --with-wrap-malloc=SHAREDLIB  Location of malloc wrapper library],
+    WRAP_MALLOC_LIB=$withval)
+
+dnl ========================================================
+dnl Substitution of found variables.
+dnl ========================================================
+AC_SUBST(SHELL_OVERRIDE)
+
+AC_SUBST(MOZILLA_CLIENT)
+AC_SUBST(CC)
+AC_SUBST(CXX)
+AC_SUBST(CFLAGS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(HOST_CC)
+AC_SUBST(HOST_CFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(HOST_LDFLAGS)
+AC_SUBST(GNU_CC)
+AC_SUBST(GCC_USE_GNU_LD)
+AC_SUBST(MSC_VER)
+AC_SUBST(CROSS_COMPILE)
+
+AC_SUBST(MOZ_OPTIMIZE)
+AC_SUBST(MOZ_DEBUG)
+AC_SUBST(MOZ_DEBUG_SYMBOLS)
+
+AC_SUBST(USE_CPLUS)
+AC_SUBST(USE_IPV6)
+AC_SUBST(USE_N32)
+AC_SUBST(USE_64)
+AC_SUBST(OBJECT_MODE)
+AC_SUBST(GC_LEAK_DETECTOR)
+AC_SUBST(ENABLE_STRIP)
+
+AC_SUBST(USE_PTHREADS)
+AC_SUBST(USE_BTHREADS)
+AC_SUBST(USE_USER_PTHREADS)
+AC_SUBST(USE_NSPR_THREADS)
+
+AC_SUBST(LIBNSPR)
+AC_SUBST(LIBPLC)
+
+AC_SUBST(MOD_MAJOR_VERSION)
+AC_SUBST(MOD_MINOR_VERSION)
+AC_SUBST(MOD_PATCH_VERSION)
+AC_SUBST(NSPR_MODNAME)
+AC_SUBST(MDCPUCFG_H)
+AC_SUBST(PR_MD_CSRCS)
+AC_SUBST(PR_MD_ASFILES)
+AC_SUBST(PR_MD_ARCH_DIR)
+AC_SUBST(CPU_ARCH)
+
+AC_SUBST(OBJ_SUFFIX)
+AC_SUBST(LIB_SUFFIX)
+AC_SUBST(DLL_SUFFIX)
+AC_SUBST(ASM_SUFFIX)
+AC_SUBST(WRAP_MALLOC_CFLAGS)
+AC_SUBST(WRAP_MALLOC_LIB)
+AC_SUBST(MKSHLIB)
+AC_SUBST(DSO_CFLAGS)
+AC_SUBST(DSO_LDOPTS)
+
+AC_SUBST(OS_TARGET)
+AC_SUBST(OS_ARCH)
+AC_SUBST(OS_RELEASE)
+AC_SUBST(OS_TEST)
+AC_SUBST(MACOSX_DEPLOYMENT_TARGET)
+
+AC_SUBST(DEFINES)
+AC_SUBST(DEFS)
+AC_SUBST(AR)
+AC_SUBST(AR_FLAGS)
+AC_SUBST(AS)
+AC_SUBST(ASFLAGS)
+AC_SUBST(LD)
+AC_SUBST(RANLIB)
+AC_SUBST(PERL)
+AC_SUBST(STRIP)
+AC_SUBST(FILTER)
+AC_SUBST(IMPLIB)
+
+AC_SUBST(PROFILE_GEN_CFLAGS)
+AC_SUBST(PROFILE_GEN_LDFLAGS)
+AC_SUBST(PROFILE_USE_CFLAGS)
+AC_SUBST(PROFILE_USE_LDFLAGS)
+
+AC_SUBST(OS_LIBS)
+AC_SUBST(RESOLVE_LINK_SYMBOLS)
+AC_SUBST(AIX_LINK_OPTS)
+AC_SUBST(NOSUCHFILE)
+AC_SUBST(MOZ_OBJFORMAT)
+AC_SUBST(ULTRASPARC_LIBRARY)
+
+AC_SUBST(OBJDIR)
+AC_SUBST(OBJDIR_NAME)
+AC_SUBST(RELEASE_OBJDIR_NAME)
+AC_SUBST(NSINSTALL)
+AC_SUBST(OPTIMIZER)
+AC_SUBST(RC)
+AC_SUBST(RCFLAGS)
+AC_SUBST(DLLFLAGS)
+AC_SUBST(EXEFLAGS)
+AC_SUBST(OS_DLLFLAGS)
+AC_SUBST(CYGWIN_WRAPPER)
+AC_SUBST(VISIBILITY_FLAGS)
+AC_SUBST(WRAP_SYSTEM_INCLUDES)
+AC_SUBST(MACOS_SDK_DIR)
+AC_SUBST(SYMBIAN_SDK_DIR)
+AC_SUBST(NEXT_ROOT)
+AC_SUBST(MT)
+
+dnl ========================================================
+dnl Generate output files.
+dnl ========================================================
+MAKEFILES="
+Makefile 
+config/Makefile
+config/autoconf.mk
+config/nsprincl.mk
+config/nsprincl.sh
+config/nspr-config
+lib/Makefile 
+lib/ds/Makefile 
+lib/libc/Makefile 
+lib/libc/include/Makefile 
+lib/libc/src/Makefile 
+lib/tests/Makefile
+pkg/Makefile
+pkg/linux/Makefile
+pkg/solaris/Makefile
+pkg/solaris/SUNWpr/Makefile
+pkg/solaris/SUNWprd/Makefile
+pr/Makefile 
+pr/include/Makefile 
+pr/include/md/Makefile 
+pr/include/obsolete/Makefile 
+pr/include/private/Makefile 
+pr/src/Makefile 
+pr/src/io/Makefile 
+pr/src/linking/Makefile 
+pr/src/malloc/Makefile 
+pr/src/md/Makefile 
+pr/src/md/${PR_MD_ARCH_DIR}/Makefile 
+pr/src/memory/Makefile 
+pr/src/misc/Makefile 
+pr/src/threads/Makefile 
+pr/tests/Makefile 
+pr/tests/dll/Makefile 
+"
+
+dnl lib/tests/Makefile
+dnl pr/tests/w16gui/Makefile
+dnl tools/Makefile
+
+if test -z "$USE_PTHREADS" && test -z "$USE_BTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/threads/combined/Makefile"
+elif test -n "$USE_PTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/pthreads/Makefile"
+elif test -n "$USE_BTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/bthreads/Makefile"
+fi
+
+if test -n "$USE_CPLUS"; then
+    MAKEFILES="$MAKEFILES pr/src/cplus/Makefile pr/src/cplus/tests/Makefile"
+fi
+
+echo $MAKEFILES > unallmakefiles
+
+AC_OUTPUT([$MAKEFILES], [chmod +x config/nspr-config])
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/Makefile.in
new file mode 100644
index 0000000..9bdc078
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/Makefile.in
@@ -0,0 +1,56 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+export NSPR20=1
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = ds libc
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/ds/Makefile.in
new file mode 100644
index 0000000..82dca03
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/Makefile.in
@@ -0,0 +1,186 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include
+
+CSRCS = \
+	plarena.c \
+	plhash.c \
+	plvrsion.c \
+	$(NULL)
+
+HEADERS = \
+	plarenas.h \
+	plarena.h \
+	plhash.h \
+	$(NULL)
+
+HEADERS := $(addprefix $(srcdir)/, $(HEADERS))
+
+ifeq ($(OS_ARCH), WINNT)
+RES=$(OBJDIR)/plds.res
+RESNAME=plds.rc
+endif # WINNT
+
+ifeq ($(OS_ARCH), AIX)
+ifeq ($(CLASSIC_NSPR),1)
+OS_LIBS = -lc
+else
+OS_LIBS = -lc_r
+endif
+endif
+
+ifeq ($(OS_ARCH),IRIX)
+OS_LIBS = -lc
+endif
+
+ifeq ($(OS_ARCH),SunOS)
+OS_LIBS = -lc
+MAPFILE = $(OBJDIR)/pldsmap.sun
+GARBAGE += $(MAPFILE)
+ifdef NS_USE_GCC
+ifdef GCC_USE_GNU_LD
+MKSHLIB += -Wl,--version-script,$(MAPFILE)
+else
+MKSHLIB += -Wl,-M,$(MAPFILE)
+endif
+else
+MKSHLIB += -M $(MAPFILE)
+endif
+# The -R '$ORIGIN' linker option instructs this library to search for its
+# dependencies in the same directory where it resides.
+MKSHLIB += -R '$$ORIGIN'
+endif
+
+ifeq ($(OS_ARCH),OS2)
+MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def
+GARBAGE += $(MAPFILE)
+MKSHLIB += $(MAPFILE)
+endif
+
+EXTRA_LIBS = $(LIBNSPR)
+
+# On NCR and SCOOS, we can't link with extra libraries when
+# we build a shared library.  If we do so, the linker doesn't
+# complain, but we would run into weird problems at run-time.
+# Therefore on these platforms, we link just the .o files.
+ifeq ($(OS_ARCH),NCR)
+EXTRA_LIBS =
+endif
+ifeq ($(OS_ARCH),SCOOS)
+EXTRA_LIBS =
+endif
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+LIBRARY_NAME	= plds
+LIBRARY_VERSION	= $(MOD_MAJOR_VERSION)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+RELEASE_LIBS	= $(TARGETS)
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+TINC = $(OBJDIR)/_pl_bld.h
+PROD = $(notdir $(SHARED_LIBRARY))
+NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
+SH_DATE = $(shell date "+%Y-%m-%d %T")
+SH_NOW = $(shell $(NOW))
+
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	SUF = i64
+else
+	SUF = LL
+endif
+
+GARBAGE += $(TINC)
+
+$(TINC):
+	@$(MAKE_OBJDIR)
+	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+	@if test ! -z "$(SH_NOW)"; then \
+	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+	else \
+	    true; \
+	fi
+	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
+
+
+$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+	$(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+endif
+#
+# Version information generation (end)
+#
+
+#
+# The Client build wants the shared libraries in $(dist_bindir),
+# so we also install them there.
+#
+
+export:: $(TARGETS)
+	$(INSTALL) -m 444 $(HEADERS) $(dist_includedir)
+	$(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifdef SHARED_LIBRARY
+ifeq ($(OS_ARCH),HP-UX)
+	$(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir)
+	$(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir)
+else
+	$(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir)
+endif
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarena.c b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarena.c
new file mode 100644
index 0000000..a6a78ae
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarena.c
@@ -0,0 +1,443 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ * 
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ * 
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation.  Portions created by Netscape are 
+ * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
+ * Rights Reserved.
+ * 
+ * Contributor(s):
+ * 
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+/*
+ * Lifetime-based fast allocation, inspired by much prior art, including
+ * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
+ * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "plarena.h"
+#include "prmem.h"
+#include "prbit.h"
+#include "prlog.h"
+#include "prlock.h"
+#include "prinit.h"
+
+static PLArena *arena_freelist;
+
+#ifdef PL_ARENAMETER
+static PLArenaStats *arena_stats_list;
+
+#define COUNT(pool,what)  (pool)->stats.what++
+#else
+#define COUNT(pool,what)  /* nothing */
+#endif
+
+#define PL_ARENA_DEFAULT_ALIGN  sizeof(double)
+
+static PRLock    *arenaLock;
+static PRCallOnceType once;
+static const PRCallOnceType pristineCallOnce;
+
+/*
+** InitializeArenas() -- Initialize arena operations.
+**
+** InitializeArenas() is called exactly once and only once from 
+** LockArena(). This function creates the arena protection 
+** lock: arenaLock.
+**
+** Note: If the arenaLock cannot be created, InitializeArenas()
+** fails quietly, returning only PR_FAILURE. This percolates up
+** to the application using the Arena API. He gets no arena
+** from PL_ArenaAllocate(). It's up to him to fail gracefully
+** or recover.
+**
+*/
+static PRStatus InitializeArenas( void )
+{
+    PR_ASSERT( arenaLock == NULL );
+    arenaLock = PR_NewLock();
+    if ( arenaLock == NULL )
+        return PR_FAILURE;
+    else
+        return PR_SUCCESS;
+} /* end ArenaInitialize() */
+
+static PRStatus LockArena( void )
+{
+    PRStatus rc = PR_CallOnce( &once, InitializeArenas );
+
+    if ( PR_FAILURE != rc )
+        PR_Lock( arenaLock );
+    return(rc);
+} /* end LockArena() */
+
+static void UnlockArena( void )
+{
+    PR_Unlock( arenaLock );
+    return;
+} /* end UnlockArena() */
+
+PR_IMPLEMENT(void) PL_InitArenaPool(
+    PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align)
+{
+    /*
+     * Look-up table of PR_BITMASK(PR_CeilingLog2(align)) values for
+     * align = 1 to 32.
+     */
+    static const PRUint8 pmasks[33] = {
+         0,                                               /*  not used */
+         0, 1, 3, 3, 7, 7, 7, 7,15,15,15,15,15,15,15,15,  /*  1 ... 16 */
+        31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31}; /* 17 ... 32 */
+
+    if (align == 0)
+        align = PL_ARENA_DEFAULT_ALIGN;
+
+    if (align < sizeof(pmasks)/sizeof(pmasks[0]))
+        pool->mask = pmasks[align];
+    else
+        pool->mask = PR_BITMASK(PR_CeilingLog2(align));
+
+    pool->first.next = NULL;
+    pool->first.base = pool->first.avail = pool->first.limit =
+        (PRUword)PL_ARENA_ALIGN(pool, &pool->first + 1);
+    pool->current = &pool->first;
+    pool->arenasize = size;                                  
+#ifdef PL_ARENAMETER
+    memset(&pool->stats, 0, sizeof pool->stats);
+    pool->stats.name = strdup(name);
+    pool->stats.next = arena_stats_list;
+    arena_stats_list = &pool->stats;
+#endif
+}
+
+
+/*
+** PL_ArenaAllocate() -- allocate space from an arena pool
+** 
+** Description: PL_ArenaAllocate() allocates space from an arena
+** pool. 
+**
+** First, try to satisfy the request from arenas starting at
+** pool->current.
+**
+** If there is not enough space in the arena pool->current, try
+** to claim an arena, on a first fit basis, from the global
+** freelist (arena_freelist).
+** 
+** If no arena in arena_freelist is suitable, then try to
+** allocate a new arena from the heap.
+**
+** Returns: pointer to allocated space or NULL
+** 
+** Notes: The original implementation had some difficult to
+** solve bugs; the code was difficult to read. Sometimes it's
+** just easier to rewrite it. I did that. larryh.
+**
+** See also: bugzilla: 45343.
+**
+*/
+
+PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
+{
+    PLArena *a;   
+    char *rp;     /* returned pointer */
+
+    PR_ASSERT((nb & pool->mask) == 0);
+    
+    nb = (PRUword)PL_ARENA_ALIGN(pool, nb); /* force alignment */
+
+    /* attempt to allocate from arenas at pool->current */
+    {
+        a = pool->current;
+        do {
+            if ( a->avail +nb <= a->limit )  {
+                pool->current = a;
+                rp = (char *)a->avail;
+                a->avail += nb;
+                return rp;
+            }
+        } while( NULL != (a = a->next) );
+    }
+
+    /* attempt to allocate from arena_freelist */
+    {
+        PLArena *p; /* previous pointer, for unlinking from freelist */
+
+        /* lock the arena_freelist. Make access to the freelist MT-Safe */
+        if ( PR_FAILURE == LockArena())
+            return(0);
+
+        for ( a = arena_freelist, p = NULL; a != NULL ; p = a, a = a->next ) {
+            if ( a->base +nb <= a->limit )  {
+                if ( p == NULL )
+                    arena_freelist = a->next;
+                else
+                    p->next = a->next;
+                UnlockArena();
+                a->avail = a->base;
+                rp = (char *)a->avail;
+                a->avail += nb;
+                /* the newly allocated arena is linked after pool->current 
+                *  and becomes pool->current */
+                a->next = pool->current->next;
+                pool->current->next = a;
+                pool->current = a;
+                if ( NULL == pool->first.next )
+                    pool->first.next = a;
+                return(rp);
+            }
+        }
+        UnlockArena();
+    }
+
+    /* attempt to allocate from the heap */ 
+    {  
+        PRUint32 sz = PR_MAX(pool->arenasize, nb);
+        sz += sizeof *a + pool->mask;  /* header and alignment slop */
+        a = (PLArena*)PR_MALLOC(sz);
+        if ( NULL != a )  {
+            a->limit = (PRUword)a + sz;
+            a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1);
+            rp = (char *)a->avail;
+            a->avail += nb;
+            /* the newly allocated arena is linked after pool->current 
+            *  and becomes pool->current */
+            a->next = pool->current->next;
+            pool->current->next = a;
+            pool->current = a;
+            if ( NULL == pool->first.next )
+                pool->first.next = a;
+            PL_COUNT_ARENA(pool,++);
+            COUNT(pool, nmallocs);
+            return(rp);
+        }
+    }
+
+    /* we got to here, and there's no memory to allocate */
+    return(NULL);
+} /* --- end PL_ArenaAllocate() --- */
+
+PR_IMPLEMENT(void *) PL_ArenaGrow(
+    PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr)
+{
+    void *newp;
+
+    PL_ARENA_ALLOCATE(newp, pool, size + incr);
+    if (newp)
+        memcpy(newp, p, size);
+    return newp;
+}
+
+static void ClearArenaList(PLArena *a, PRInt32 pattern)
+{
+
+    for (; a; a = a->next) {
+        PR_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+        a->avail = a->base;
+	PL_CLEAR_UNUSED_PATTERN(a, pattern);
+    }
+}
+
+PR_IMPLEMENT(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern)
+{
+    ClearArenaList(pool->first.next, pattern);
+}
+
+/*
+ * Free tail arenas linked after head, which may not be the true list head.
+ * Reset pool->current to point to head in case it pointed at a tail arena.
+ */
+static void FreeArenaList(PLArenaPool *pool, PLArena *head, PRBool reallyFree)
+{
+    PLArena **ap, *a;
+
+    ap = &head->next;
+    a = *ap;
+    if (!a)
+        return;
+
+#ifdef DEBUG
+    ClearArenaList(a, PL_FREE_PATTERN);
+#endif
+
+    if (reallyFree) {
+        do {
+            *ap = a->next;
+            PL_CLEAR_ARENA(a);
+            PL_COUNT_ARENA(pool,--);
+            PR_DELETE(a);
+        } while ((a = *ap) != 0);
+    } else {
+        /* Insert the whole arena chain at the front of the freelist. */
+        do {
+            ap = &(*ap)->next;
+        } while (*ap);
+        LockArena();
+        *ap = arena_freelist;
+        arena_freelist = a;
+        head->next = 0;
+        UnlockArena();
+    }
+
+    pool->current = head;
+}
+
+PR_IMPLEMENT(void) PL_ArenaRelease(PLArenaPool *pool, char *mark)
+{
+    PLArena *a;
+
+    for (a = pool->first.next; a; a = a->next) {
+        if (PR_UPTRDIFF(mark, a->base) < PR_UPTRDIFF(a->avail, a->base)) {
+            a->avail = (PRUword)PL_ARENA_ALIGN(pool, mark);
+            FreeArenaList(pool, a, PR_FALSE);
+            return;
+        }
+    }
+}
+
+PR_IMPLEMENT(void) PL_FreeArenaPool(PLArenaPool *pool)
+{
+    FreeArenaList(pool, &pool->first, PR_FALSE);
+    COUNT(pool, ndeallocs);
+}
+
+PR_IMPLEMENT(void) PL_FinishArenaPool(PLArenaPool *pool)
+{
+    FreeArenaList(pool, &pool->first, PR_TRUE);
+#ifdef PL_ARENAMETER
+    {
+        PLArenaStats *stats, **statsp;
+
+        if (pool->stats.name)
+            PR_DELETE(pool->stats.name);
+        for (statsp = &arena_stats_list; (stats = *statsp) != 0;
+             statsp = &stats->next) {
+            if (stats == &pool->stats) {
+                *statsp = stats->next;
+                return;
+            }
+        }
+    }
+#endif
+}
+
+PR_IMPLEMENT(void) PL_CompactArenaPool(PLArenaPool *ap)
+{
+}
+
+PR_IMPLEMENT(void) PL_ArenaFinish(void)
+{
+    PLArena *a, *next;
+
+    for (a = arena_freelist; a; a = next) {
+        next = a->next;
+        PR_DELETE(a);
+    }
+    arena_freelist = NULL;
+
+    if (arenaLock) {
+        PR_DestroyLock(arenaLock);
+        arenaLock = NULL;
+    }
+    once = pristineCallOnce;
+}
+
+#ifdef PL_ARENAMETER
+PR_IMPLEMENT(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb)
+{
+    pool->stats.nallocs++;
+    pool->stats.nbytes += nb;
+    if (nb > pool->stats.maxalloc)
+        pool->stats.maxalloc = nb;
+    pool->stats.variance += nb * nb;
+}
+
+PR_IMPLEMENT(void) PL_ArenaCountInplaceGrowth(
+    PLArenaPool *pool, PRUint32 size, PRUint32 incr)
+{
+    pool->stats.ninplace++;
+}
+
+PR_IMPLEMENT(void) PL_ArenaCountGrowth(
+    PLArenaPool *pool, PRUint32 size, PRUint32 incr)
+{
+    pool->stats.ngrows++;
+    pool->stats.nbytes += incr;
+    pool->stats.variance -= size * size;
+    size += incr;
+    if (size > pool->stats.maxalloc)
+        pool->stats.maxalloc = size;
+    pool->stats.variance += size * size;
+}
+
+PR_IMPLEMENT(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark)
+{
+    pool->stats.nreleases++;
+}
+
+PR_IMPLEMENT(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark)
+{
+    pool->stats.nfastrels++;
+}
+
+#include <math.h>
+#include <stdio.h>
+
+PR_IMPLEMENT(void) PL_DumpArenaStats(FILE *fp)
+{
+    PLArenaStats *stats;
+    double mean, variance;
+
+    for (stats = arena_stats_list; stats; stats = stats->next) {
+        if (stats->nallocs != 0) {
+            mean = (double)stats->nbytes / stats->nallocs;
+            variance = fabs(stats->variance / stats->nallocs - mean * mean);
+        } else {
+            mean = variance = 0;
+        }
+
+        fprintf(fp, "\n%s allocation statistics:\n", stats->name);
+        fprintf(fp, "              number of arenas: %u\n", stats->narenas);
+        fprintf(fp, "         number of allocations: %u\n", stats->nallocs);
+        fprintf(fp, " number of free arena reclaims: %u\n", stats->nreclaims);
+        fprintf(fp, "        number of malloc calls: %u\n", stats->nmallocs);
+        fprintf(fp, "       number of deallocations: %u\n", stats->ndeallocs);
+        fprintf(fp, "  number of allocation growths: %u\n", stats->ngrows);
+        fprintf(fp, "    number of in-place growths: %u\n", stats->ninplace);
+        fprintf(fp, "number of released allocations: %u\n", stats->nreleases);
+        fprintf(fp, "       number of fast releases: %u\n", stats->nfastrels);
+        fprintf(fp, "         total bytes allocated: %u\n", stats->nbytes);
+        fprintf(fp, "          mean allocation size: %g\n", mean);
+        fprintf(fp, "            standard deviation: %g\n", sqrt(variance));
+        fprintf(fp, "       maximum allocation size: %u\n", stats->maxalloc);
+    }
+}
+#endif /* PL_ARENAMETER */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarena.h b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarena.h
new file mode 100644
index 0000000..d609404
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarena.h
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ * 
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ * 
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation.  Portions created by Netscape are 
+ * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
+ * Rights Reserved.
+ * 
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifndef plarena_h___
+#define plarena_h___
+/*
+ * Lifetime-based fast allocation, inspired by much prior art, including
+ * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
+ * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
+ *
+ * Also supports LIFO allocation (PL_ARENA_MARK/PL_ARENA_RELEASE).
+ */
+#include "prtypes.h"
+#include "plarenas.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLArena          PLArena;
+
+struct PLArena {
+    PLArena     *next;          /* next arena for this lifetime */
+    PRUword     base;           /* aligned base address, follows this header */
+    PRUword     limit;          /* one beyond last byte in arena */
+    PRUword     avail;          /* points to next available byte */
+};
+
+#ifdef PL_ARENAMETER
+typedef struct PLArenaStats PLArenaStats;
+
+struct PLArenaStats {
+    PLArenaStats  *next;        /* next in arenaStats list */
+    char          *name;        /* name for debugging */
+    PRUint32      narenas;      /* number of arenas in pool */
+    PRUint32      nallocs;      /* number of PL_ARENA_ALLOCATE() calls */
+    PRUint32      nreclaims;    /* number of reclaims from freeArenas */
+    PRUint32      nmallocs;     /* number of malloc() calls */
+    PRUint32      ndeallocs;    /* number of lifetime deallocations */
+    PRUint32      ngrows;       /* number of PL_ARENA_GROW() calls */
+    PRUint32      ninplace;     /* number of in-place growths */
+    PRUint32      nreleases;    /* number of PL_ARENA_RELEASE() calls */
+    PRUint32      nfastrels;    /* number of "fast path" releases */
+    PRUint32      nbytes;       /* total bytes allocated */
+    PRUint32      maxalloc;     /* maximum allocation size in bytes */
+    PRFloat64     variance;     /* size variance accumulator */
+};
+#endif
+
+struct PLArenaPool {
+    PLArena     first;          /* first arena in pool list */
+    PLArena     *current;       /* arena from which to allocate space */
+    PRUint32    arenasize;      /* net exact size of a new arena */
+    PRUword     mask;           /* alignment mask (power-of-2 - 1) */
+#ifdef PL_ARENAMETER
+    PLArenaStats stats;
+#endif
+};
+
+/*
+ * If the including .c file uses only one power-of-2 alignment, it may define
+ * PL_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
+ * per ALLOCATE and GROW.
+ */
+#ifdef PL_ARENA_CONST_ALIGN_MASK
+#define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + PL_ARENA_CONST_ALIGN_MASK) \
+                                & ~PL_ARENA_CONST_ALIGN_MASK)
+
+#define PL_INIT_ARENA_POOL(pool, name, size) \
+        PL_InitArenaPool(pool, name, size, PL_ARENA_CONST_ALIGN_MASK + 1)
+#else
+#define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + (pool)->mask) & ~(pool)->mask)
+#endif
+
+#define PL_ARENA_ALLOCATE(p, pool, nb) \
+    PR_BEGIN_MACRO \
+        PLArena *_a = (pool)->current; \
+        PRUint32 _nb = PL_ARENA_ALIGN(pool, nb); \
+        PRUword _p = _a->avail; \
+        PRUword _q = _p + _nb; \
+        if (_q > _a->limit) \
+            _p = (PRUword)PL_ArenaAllocate(pool, _nb); \
+        else \
+            _a->avail = _q; \
+        p = (void *)_p; \
+        PL_ArenaCountAllocation(pool, nb); \
+    PR_END_MACRO
+
+#define PL_ARENA_GROW(p, pool, size, incr) \
+    PR_BEGIN_MACRO \
+        PLArena *_a = (pool)->current; \
+        PRUint32 _incr = PL_ARENA_ALIGN(pool, incr); \
+        PRUword _p = _a->avail; \
+        PRUword _q = _p + _incr; \
+        if (_p == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \
+            _q <= _a->limit) { \
+            _a->avail = _q; \
+            PL_ArenaCountInplaceGrowth(pool, size, incr); \
+        } else { \
+            p = PL_ArenaGrow(pool, p, size, incr); \
+        } \
+        PL_ArenaCountGrowth(pool, size, incr); \
+    PR_END_MACRO
+
+#define PL_ARENA_MARK(pool) ((void *) (pool)->current->avail)
+#define PR_UPTRDIFF(p,q) ((PRUword)(p) - (PRUword)(q))
+
+#define PL_CLEAR_UNUSED_PATTERN(a, pattern) \
+	   (PR_ASSERT((a)->avail <= (a)->limit), \
+	   memset((void*)(a)->avail, (pattern), (a)->limit - (a)->avail))
+#ifdef DEBUG
+#define PL_FREE_PATTERN 0xDA
+#define PL_CLEAR_UNUSED(a) PL_CLEAR_UNUSED_PATTERN((a), PL_FREE_PATTERN)
+#define PL_CLEAR_ARENA(a)  memset((void*)(a), PL_FREE_PATTERN, \
+                           (a)->limit - (PRUword)(a))
+#else
+#define PL_CLEAR_UNUSED(a)
+#define PL_CLEAR_ARENA(a)
+#endif
+
+#define PL_ARENA_RELEASE(pool, mark) \
+    PR_BEGIN_MACRO \
+        char *_m = (char *)(mark); \
+        PLArena *_a = (pool)->current; \
+        if (PR_UPTRDIFF(_m, _a->base) <= PR_UPTRDIFF(_a->avail, _a->base)) { \
+            _a->avail = (PRUword)PL_ARENA_ALIGN(pool, _m); \
+            PL_CLEAR_UNUSED(_a); \
+            PL_ArenaCountRetract(pool, _m); \
+        } else { \
+            PL_ArenaRelease(pool, _m); \
+        } \
+        PL_ArenaCountRelease(pool, _m); \
+    PR_END_MACRO
+
+#ifdef PL_ARENAMETER
+#define PL_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
+#else
+#define PL_COUNT_ARENA(pool,op)
+#endif
+
+#define PL_ARENA_DESTROY(pool, a, pnext) \
+    PR_BEGIN_MACRO \
+        PL_COUNT_ARENA(pool,--); \
+        if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
+        *(pnext) = (a)->next; \
+        PL_CLEAR_ARENA(a); \
+        free(a); \
+        (a) = 0; \
+    PR_END_MACRO
+
+#ifdef PL_ARENAMETER
+
+#include <stdio.h>
+
+PR_EXTERN(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb);
+
+PR_EXTERN(void) PL_ArenaCountInplaceGrowth(
+    PLArenaPool *pool, PRUint32 size, PRUint32 incr);
+
+PR_EXTERN(void) PL_ArenaCountGrowth(
+    PLArenaPool *pool, PRUint32 size, PRUint32 incr);
+
+PR_EXTERN(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark);
+
+PR_EXTERN(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark);
+
+PR_EXTERN(void) PL_DumpArenaStats(FILE *fp);
+
+#else  /* !PL_ARENAMETER */
+
+#define PL_ArenaCountAllocation(ap, nb)                 /* nothing */
+#define PL_ArenaCountInplaceGrowth(ap, size, incr)      /* nothing */
+#define PL_ArenaCountGrowth(ap, size, incr)             /* nothing */
+#define PL_ArenaCountRelease(ap, mark)                  /* nothing */
+#define PL_ArenaCountRetract(ap, mark)                  /* nothing */
+
+#endif /* !PL_ARENAMETER */
+
+PR_END_EXTERN_C
+
+#endif /* plarena_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarenas.h b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarenas.h
new file mode 100644
index 0000000..778d3af
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plarenas.h
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#if defined(PLARENAS_H)
+#else  /* defined(PLARENAS_H) */
+#define PLARENAS_H
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLArenaPool      PLArenaPool;
+
+/*
+** Allocate an arena pool as specified by the parameters.
+**
+** This is equivelant to allocating the space yourself and then
+** calling PL_InitArenaPool().
+**
+** This function may fail (and return a NULL) for a variety of
+** reasons. The reason for a particular failure can be discovered
+** by calling PR_GetError().
+*/
+#if 0  /* Not implemented */
+PR_EXTERN(PLArenaPool*) PL_AllocArenaPool(
+    const char *name, PRUint32 size, PRUint32 align);
+#endif
+
+/*
+** Destroy an arena pool previously allocated by PL_AllocArenaPool().
+**
+** This function may fail if the arena is not empty and the caller
+** wishes to check for empty upon descruction.
+*/
+#if 0  /* Not implemented */
+PR_EXTERN(PRStatus) PL_DestroyArenaPool(PLArenaPool *pool, PRBool checkEmpty);
+#endif
+
+
+/*
+** Initialize an arena pool with the given name for debugging and metering,
+** with a minimum size per arena of size bytes.
+**/
+PR_EXTERN(void) PL_InitArenaPool(
+    PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align);
+
+/*
+** Finish using arenas, freeing all memory associated with them.
+**/
+PR_EXTERN(void) PL_ArenaFinish(void);
+
+/*
+** Free the arenas in pool.  The user may continue to allocate from pool
+** after calling this function.  There is no need to call PL_InitArenaPool()
+** again unless PL_FinishArenaPool(pool) has been called.
+**/
+PR_EXTERN(void) PL_FreeArenaPool(PLArenaPool *pool);
+
+/*
+** Free the arenas in pool and finish using it altogether.
+**/
+PR_EXTERN(void) PL_FinishArenaPool(PLArenaPool *pool);
+
+/*
+** Compact all of the arenas in a pool so that no space is wasted.
+**/
+PR_EXTERN(void) PL_CompactArenaPool(PLArenaPool *pool);
+
+/*
+** Friend functions used by the PL_ARENA_*() macros.
+**/
+PR_EXTERN(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb);
+
+PR_EXTERN(void *) PL_ArenaGrow(
+    PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr);
+
+PR_EXTERN(void) PL_ArenaRelease(PLArenaPool *pool, char *mark);
+
+/*
+** memset contents of all arenas in pool to pattern
+*/
+PR_EXTERN(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern);
+
+PR_END_EXTERN_C
+
+#endif /* defined(PLARENAS_H) */
+
+/* plarenas */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/plds.def b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plds.def
new file mode 100644
index 0000000..a80e2bc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plds.def
@@ -0,0 +1,88 @@
+;+#
+;+# ***** BEGIN LICENSE BLOCK *****
+;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+;+#
+;+# The contents of this file are subject to the Mozilla Public License Version
+;+# 1.1 (the "License"); you may not use this file except in compliance with
+;+# the License. You may obtain a copy of the License at
+;+# http://www.mozilla.org/MPL/
+;+#
+;+# Software distributed under the License is distributed on an "AS IS" basis,
+;+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+;+# for the specific language governing rights and limitations under the
+;+# License.
+;+#
+;+# The Original Code is the Netscape Portable Runtime (NSPR).
+;+#
+;+# The Initial Developer of the Original Code is
+;+# Netscape Communications Corporation.
+;+# Portions created by the Initial Developer are Copyright (C) 2002-2003
+;+# the Initial Developer. All Rights Reserved.
+;+#
+;+# Contributor(s):
+;+#
+;+# Alternatively, the contents of this file may be used under the terms of
+;+# either the GNU General Public License Version 2 or later (the "GPL"), or
+;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+;+# in which case the provisions of the GPL or the LGPL are applicable instead
+;+# of those above. If you wish to allow use of your version of this file only
+;+# under the terms of either the GPL or the LGPL, and not to allow others to
+;+# use your version of this file under the terms of the MPL, indicate your
+;+# decision by deleting the provisions above and replace them with the notice
+;+# and other provisions required by the GPL or the LGPL. If you do not delete
+;+# the provisions above, a recipient may use your version of this file under
+;+# the terms of any one of the MPL, the GPL or the LGPL.
+;+#
+;+# ***** END LICENSE BLOCK *****
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS
+;+#   1. For all unix platforms, the string ";-"  means "remove this line"
+;+#   2. For all unix platforms, the string " DATA " will be removed from any 
+;+#     line on which it occurs.
+;+#   3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+#      On AIX, lines containing ";+" will be removed.
+;+#   4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+#   5. For all unix platforms, after the above processing has taken place,
+;+#    all characters after the first ";" on the line will be removed.
+;+#    And for AIX, the first ";" will also be removed.
+;+#  This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+#   directives are hidden behind ";", ";+", and ";-"
+;+NSPR_4.0 {
+;+    global:
+LIBRARY plds4 ;-
+EXPORTS ;-
+PL_ArenaAllocate;
+PL_ArenaFinish;
+PL_ArenaGrow;
+PL_ArenaRelease;
+PL_CompactArenaPool;
+PL_CompareStrings;
+PL_CompareValues;
+PL_FinishArenaPool;
+PL_FreeArenaPool;
+PL_HashString;
+PL_HashTableAdd;
+PL_HashTableDestroy;
+PL_HashTableDump;
+PL_HashTableEnumerateEntries;
+PL_HashTableLookup;
+PL_HashTableRawAdd;
+PL_HashTableRawLookup;
+PL_HashTableRawRemove;
+PL_HashTableRemove;
+PL_InitArenaPool;
+PL_NewHashTable;
+libVersionPoint;
+;+    local: *;
+;+};
+;+
+;+NSPR_4.1 {
+;+    global:
+PL_HashTableLookupConst;
+PL_HashTableRawLookupConst;
+;+} NSPR_4.0;
+;+
+;+NSPR_4.8.5 {
+;+    global:
+PL_ClearArenaPool;
+;+} NSPR_4.1;
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/plds.rc b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plds.rc
new file mode 100644
index 0000000..7a310df
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plds.rc
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#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
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+        BEGIN
+            VALUE "CompanyName", "Mozilla Foundation\0"
+            VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+            VALUE "FileVersion", PR_VERSION "\0"
+            VALUE "InternalName", MY_INTERNAL_NAME "\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
+    END
+END
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/plhash.c b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plhash.c
new file mode 100644
index 0000000..4f69d04
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plhash.c
@@ -0,0 +1,515 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * PL hash table package.
+ */
+#include "plhash.h"
+#include "prbit.h"
+#include "prlog.h"
+#include "prmem.h"
+#include "prtypes.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* Compute the number of buckets in ht */
+#define NBUCKETS(ht)    (1 << (PL_HASH_BITS - (ht)->shift))
+
+/* The smallest table has 16 buckets */
+#define MINBUCKETSLOG2  4
+#define MINBUCKETS      (1 << MINBUCKETSLOG2)
+
+/* Compute the maximum entries given n buckets that we will tolerate, ~90% */
+#define OVERLOADED(n)   ((n) - ((n) >> 3))
+
+/* Compute the number of entries below which we shrink the table by half */
+#define UNDERLOADED(n)  (((n) > MINBUCKETS) ? ((n) >> 2) : 0)
+
+/*
+** Stubs for default hash allocator ops.
+*/
+static void * PR_CALLBACK
+DefaultAllocTable(void *pool, PRSize size)
+{
+    return PR_MALLOC(size);
+}
+
+static void PR_CALLBACK
+DefaultFreeTable(void *pool, void *item)
+{
+    PR_Free(item);
+}
+
+static PLHashEntry * PR_CALLBACK
+DefaultAllocEntry(void *pool, const void *key)
+{
+    return PR_NEW(PLHashEntry);
+}
+
+static void PR_CALLBACK
+DefaultFreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
+{
+    if (flag == HT_FREE_ENTRY)
+        PR_Free(he);
+}
+
+static PLHashAllocOps defaultHashAllocOps = {
+    DefaultAllocTable, DefaultFreeTable,
+    DefaultAllocEntry, DefaultFreeEntry
+};
+
+PR_IMPLEMENT(PLHashTable *)
+PL_NewHashTable(PRUint32 n, PLHashFunction keyHash,
+                PLHashComparator keyCompare, PLHashComparator valueCompare,
+                const PLHashAllocOps *allocOps, void *allocPriv)
+{
+    PLHashTable *ht;
+    PRSize nb;
+
+    if (n <= MINBUCKETS) {
+        n = MINBUCKETSLOG2;
+    } else {
+        n = PR_CeilingLog2(n);
+        if ((PRInt32)n < 0)
+            return 0;
+    }
+
+    if (!allocOps) allocOps = &defaultHashAllocOps;
+
+    ht = (PLHashTable*)((*allocOps->allocTable)(allocPriv, sizeof *ht));
+    if (!ht)
+	return 0;
+    memset(ht, 0, sizeof *ht);
+    ht->shift = PL_HASH_BITS - n;
+    n = 1 << n;
+    nb = n * sizeof(PLHashEntry *);
+    ht->buckets = (PLHashEntry**)((*allocOps->allocTable)(allocPriv, nb));
+    if (!ht->buckets) {
+        (*allocOps->freeTable)(allocPriv, ht);
+        return 0;
+    }
+    memset(ht->buckets, 0, nb);
+
+    ht->keyHash = keyHash;
+    ht->keyCompare = keyCompare;
+    ht->valueCompare = valueCompare;
+    ht->allocOps = allocOps;
+    ht->allocPriv = allocPriv;
+    return ht;
+}
+
+PR_IMPLEMENT(void)
+PL_HashTableDestroy(PLHashTable *ht)
+{
+    PRUint32 i, n;
+    PLHashEntry *he, *next;
+    const PLHashAllocOps *allocOps = ht->allocOps;
+    void *allocPriv = ht->allocPriv;
+
+    n = NBUCKETS(ht);
+    for (i = 0; i < n; i++) {
+        for (he = ht->buckets[i]; he; he = next) {
+            next = he->next;
+            (*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY);
+        }
+    }
+#ifdef DEBUG
+    memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]);
+#endif
+    (*allocOps->freeTable)(allocPriv, ht->buckets);
+#ifdef DEBUG
+    memset(ht, 0xDB, sizeof *ht);
+#endif
+    (*allocOps->freeTable)(allocPriv, ht);
+}
+
+/*
+** Multiplicative hash, from Knuth 6.4.
+*/
+#define GOLDEN_RATIO    0x9E3779B9U  /* 2/(1+sqrt(5))*(2^32) */
+
+PR_IMPLEMENT(PLHashEntry **)
+PL_HashTableRawLookup(PLHashTable *ht, PLHashNumber keyHash, const void *key)
+{
+    PLHashEntry *he, **hep, **hep0;
+    PLHashNumber h;
+
+#ifdef HASHMETER
+    ht->nlookups++;
+#endif
+    h = keyHash * GOLDEN_RATIO;
+    h >>= ht->shift;
+    hep = hep0 = &ht->buckets[h];
+    while ((he = *hep) != 0) {
+        if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) {
+            /* Move to front of chain if not already there */
+            if (hep != hep0) {
+                *hep = he->next;
+                he->next = *hep0;
+                *hep0 = he;
+            }
+            return hep0;
+        }
+        hep = &he->next;
+#ifdef HASHMETER
+        ht->nsteps++;
+#endif
+    }
+    return hep;
+}
+
+/*
+** Same as PL_HashTableRawLookup but doesn't reorder the hash entries.
+*/
+PR_IMPLEMENT(PLHashEntry **)
+PL_HashTableRawLookupConst(PLHashTable *ht, PLHashNumber keyHash,
+                           const void *key)
+{
+    PLHashEntry *he, **hep;
+    PLHashNumber h;
+
+#ifdef HASHMETER
+    ht->nlookups++;
+#endif
+    h = keyHash * GOLDEN_RATIO;
+    h >>= ht->shift;
+    hep = &ht->buckets[h];
+    while ((he = *hep) != 0) {
+        if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) {
+            break;
+        }
+        hep = &he->next;
+#ifdef HASHMETER
+        ht->nsteps++;
+#endif
+    }
+    return hep;
+}
+
+PR_IMPLEMENT(PLHashEntry *)
+PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep,
+                   PLHashNumber keyHash, const void *key, void *value)
+{
+    PRUint32 i, n;
+    PLHashEntry *he, *next, **oldbuckets;
+    PRSize nb;
+
+    /* Grow the table if it is overloaded */
+    n = NBUCKETS(ht);
+    if (ht->nentries >= OVERLOADED(n)) {
+        oldbuckets = ht->buckets;
+        nb = 2 * n * sizeof(PLHashEntry *);
+        ht->buckets = (PLHashEntry**)
+            ((*ht->allocOps->allocTable)(ht->allocPriv, nb));
+        if (!ht->buckets) {
+            ht->buckets = oldbuckets;
+            return 0;
+        }
+        memset(ht->buckets, 0, nb);
+#ifdef HASHMETER
+        ht->ngrows++;
+#endif
+        ht->shift--;
+
+        for (i = 0; i < n; i++) {
+            for (he = oldbuckets[i]; he; he = next) {
+                next = he->next;
+                hep = PL_HashTableRawLookup(ht, he->keyHash, he->key);
+                PR_ASSERT(*hep == 0);
+                he->next = 0;
+                *hep = he;
+            }
+        }
+#ifdef DEBUG
+        memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
+#endif
+        (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
+        hep = PL_HashTableRawLookup(ht, keyHash, key);
+    }
+
+    /* Make a new key value entry */
+    he = (*ht->allocOps->allocEntry)(ht->allocPriv, key);
+    if (!he)
+	return 0;
+    he->keyHash = keyHash;
+    he->key = key;
+    he->value = value;
+    he->next = *hep;
+    *hep = he;
+    ht->nentries++;
+    return he;
+}
+
+PR_IMPLEMENT(PLHashEntry *)
+PL_HashTableAdd(PLHashTable *ht, const void *key, void *value)
+{
+    PLHashNumber keyHash;
+    PLHashEntry *he, **hep;
+
+    keyHash = (*ht->keyHash)(key);
+    hep = PL_HashTableRawLookup(ht, keyHash, key);
+    if ((he = *hep) != 0) {
+        /* Hit; see if values match */
+        if ((*ht->valueCompare)(he->value, value)) {
+            /* key,value pair is already present in table */
+            return he;
+        }
+        if (he->value)
+            (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE);
+        he->value = value;
+        return he;
+    }
+    return PL_HashTableRawAdd(ht, hep, keyHash, key, value);
+}
+
+PR_IMPLEMENT(void)
+PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he)
+{
+    PRUint32 i, n;
+    PLHashEntry *next, **oldbuckets;
+    PRSize nb;
+
+    *hep = he->next;
+    (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);
+
+    /* Shrink table if it's underloaded */
+    n = NBUCKETS(ht);
+    if (--ht->nentries < UNDERLOADED(n)) {
+        oldbuckets = ht->buckets;
+        nb = n * sizeof(PLHashEntry*) / 2;
+        ht->buckets = (PLHashEntry**)(
+            (*ht->allocOps->allocTable)(ht->allocPriv, nb));
+        if (!ht->buckets) {
+            ht->buckets = oldbuckets;
+            return;
+        }
+        memset(ht->buckets, 0, nb);
+#ifdef HASHMETER
+        ht->nshrinks++;
+#endif
+        ht->shift++;
+
+        for (i = 0; i < n; i++) {
+            for (he = oldbuckets[i]; he; he = next) {
+                next = he->next;
+                hep = PL_HashTableRawLookup(ht, he->keyHash, he->key);
+                PR_ASSERT(*hep == 0);
+                he->next = 0;
+                *hep = he;
+            }
+        }
+#ifdef DEBUG
+        memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
+#endif
+        (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
+    }
+}
+
+PR_IMPLEMENT(PRBool)
+PL_HashTableRemove(PLHashTable *ht, const void *key)
+{
+    PLHashNumber keyHash;
+    PLHashEntry *he, **hep;
+
+    keyHash = (*ht->keyHash)(key);
+    hep = PL_HashTableRawLookup(ht, keyHash, key);
+    if ((he = *hep) == 0)
+        return PR_FALSE;
+
+    /* Hit; remove element */
+    PL_HashTableRawRemove(ht, hep, he);
+    return PR_TRUE;
+}
+
+PR_IMPLEMENT(void *)
+PL_HashTableLookup(PLHashTable *ht, const void *key)
+{
+    PLHashNumber keyHash;
+    PLHashEntry *he, **hep;
+
+    keyHash = (*ht->keyHash)(key);
+    hep = PL_HashTableRawLookup(ht, keyHash, key);
+    if ((he = *hep) != 0) {
+        return he->value;
+    }
+    return 0;
+}
+
+/*
+** Same as PL_HashTableLookup but doesn't reorder the hash entries.
+*/
+PR_IMPLEMENT(void *)
+PL_HashTableLookupConst(PLHashTable *ht, const void *key)
+{
+    PLHashNumber keyHash;
+    PLHashEntry *he, **hep;
+
+    keyHash = (*ht->keyHash)(key);
+    hep = PL_HashTableRawLookupConst(ht, keyHash, key);
+    if ((he = *hep) != 0) {
+        return he->value;
+    }
+    return 0;
+}
+
+/*
+** Iterate over the entries in the hash table calling func for each
+** entry found. Stop if "f" says to (return value & PR_ENUMERATE_STOP).
+** Return a count of the number of elements scanned.
+*/
+PR_IMPLEMENT(int)
+PL_HashTableEnumerateEntries(PLHashTable *ht, PLHashEnumerator f, void *arg)
+{
+    PLHashEntry *he, **hep;
+    PRUint32 i, nbuckets;
+    int rv, n = 0;
+    PLHashEntry *todo = 0;
+
+    nbuckets = NBUCKETS(ht);
+    for (i = 0; i < nbuckets; i++) {
+        hep = &ht->buckets[i];
+        while ((he = *hep) != 0) {
+            rv = (*f)(he, n, arg);
+            n++;
+            if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) {
+                *hep = he->next;
+                if (rv & HT_ENUMERATE_REMOVE) {
+                    he->next = todo;
+                    todo = he;
+                }
+            } else {
+                hep = &he->next;
+            }
+            if (rv & HT_ENUMERATE_STOP) {
+                goto out;
+            }
+        }
+    }
+
+out:
+    hep = &todo;
+    while ((he = *hep) != 0) {
+        PL_HashTableRawRemove(ht, hep, he);
+    }
+    return n;
+}
+
+#ifdef HASHMETER
+#include <math.h>
+#include <stdio.h>
+
+PR_IMPLEMENT(void)
+PL_HashTableDumpMeter(PLHashTable *ht, PLHashEnumerator dump, FILE *fp)
+{
+    double mean, variance;
+    PRUint32 nchains, nbuckets;
+    PRUint32 i, n, maxChain, maxChainLen;
+    PLHashEntry *he;
+
+    variance = 0;
+    nchains = 0;
+    maxChainLen = 0;
+    nbuckets = NBUCKETS(ht);
+    for (i = 0; i < nbuckets; i++) {
+        he = ht->buckets[i];
+        if (!he)
+            continue;
+        nchains++;
+        for (n = 0; he; he = he->next)
+            n++;
+        variance += n * n;
+        if (n > maxChainLen) {
+            maxChainLen = n;
+            maxChain = i;
+        }
+    }
+    mean = (double)ht->nentries / nchains;
+    variance = fabs(variance / nchains - mean * mean);
+
+    fprintf(fp, "\nHash table statistics:\n");
+    fprintf(fp, "     number of lookups: %u\n", ht->nlookups);
+    fprintf(fp, "     number of entries: %u\n", ht->nentries);
+    fprintf(fp, "       number of grows: %u\n", ht->ngrows);
+    fprintf(fp, "     number of shrinks: %u\n", ht->nshrinks);
+    fprintf(fp, "   mean steps per hash: %g\n", (double)ht->nsteps
+                                                / ht->nlookups);
+    fprintf(fp, "mean hash chain length: %g\n", mean);
+    fprintf(fp, "    standard deviation: %g\n", sqrt(variance));
+    fprintf(fp, " max hash chain length: %u\n", maxChainLen);
+    fprintf(fp, "        max hash chain: [%u]\n", maxChain);
+
+    for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++)
+        if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT)
+            break;
+}
+#endif /* HASHMETER */
+
+PR_IMPLEMENT(int)
+PL_HashTableDump(PLHashTable *ht, PLHashEnumerator dump, FILE *fp)
+{
+    int count;
+
+    count = PL_HashTableEnumerateEntries(ht, dump, fp);
+#ifdef HASHMETER
+    PL_HashTableDumpMeter(ht, dump, fp);
+#endif
+    return count;
+}
+
+PR_IMPLEMENT(PLHashNumber)
+PL_HashString(const void *key)
+{
+    PLHashNumber h;
+    const PRUint8 *s;
+
+    h = 0;
+    for (s = (const PRUint8*)key; *s; s++)
+        h = PR_ROTATE_LEFT32(h, 4) ^ *s;
+    return h;
+}
+
+PR_IMPLEMENT(int)
+PL_CompareStrings(const void *v1, const void *v2)
+{
+    return strcmp((const char*)v1, (const char*)v2) == 0;
+}
+
+PR_IMPLEMENT(int)
+PL_CompareValues(const void *v1, const void *v2)
+{
+    return v1 == v2;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/plhash.h b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plhash.h
new file mode 100644
index 0000000..d752d16
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plhash.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef plhash_h___
+#define plhash_h___
+/*
+ * API to portable hash table code.
+ */
+#include <stdio.h>
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLHashEntry  PLHashEntry;
+typedef struct PLHashTable  PLHashTable;
+typedef PRUint32 PLHashNumber;
+#define PL_HASH_BITS 32  /* Number of bits in PLHashNumber */
+typedef PLHashNumber (PR_CALLBACK *PLHashFunction)(const void *key);
+typedef PRIntn (PR_CALLBACK *PLHashComparator)(const void *v1, const void *v2);
+
+typedef PRIntn (PR_CALLBACK *PLHashEnumerator)(PLHashEntry *he, PRIntn i, void *arg);
+
+/* Flag bits in PLHashEnumerator's return value */
+#define HT_ENUMERATE_NEXT       0       /* continue enumerating entries */
+#define HT_ENUMERATE_STOP       1       /* stop enumerating entries */
+#define HT_ENUMERATE_REMOVE     2       /* remove and free the current entry */
+#define HT_ENUMERATE_UNHASH     4       /* just unhash the current entry */
+
+typedef struct PLHashAllocOps {
+    void *              (PR_CALLBACK *allocTable)(void *pool, PRSize size);
+    void                (PR_CALLBACK *freeTable)(void *pool, void *item);
+    PLHashEntry *       (PR_CALLBACK *allocEntry)(void *pool, const void *key);
+    void                (PR_CALLBACK *freeEntry)(void *pool, PLHashEntry *he, PRUintn flag);
+} PLHashAllocOps;
+
+#define HT_FREE_VALUE   0               /* just free the entry's value */
+#define HT_FREE_ENTRY   1               /* free value and entire entry */
+
+struct PLHashEntry {
+    PLHashEntry         *next;          /* hash chain linkage */
+    PLHashNumber        keyHash;        /* key hash function result */
+    const void          *key;           /* ptr to opaque key */
+    void                *value;         /* ptr to opaque value */
+};
+
+struct PLHashTable {
+    PLHashEntry         **buckets;      /* vector of hash buckets */
+    PRUint32              nentries;       /* number of entries in table */
+    PRUint32              shift;          /* multiplicative hash shift */
+    PLHashFunction      keyHash;        /* key hash function */
+    PLHashComparator    keyCompare;     /* key comparison function */
+    PLHashComparator    valueCompare;   /* value comparison function */
+    const PLHashAllocOps *allocOps;     /* allocation operations */
+    void                *allocPriv;     /* allocation private data */
+#ifdef HASHMETER
+    PRUint32              nlookups;       /* total number of lookups */
+    PRUint32              nsteps;         /* number of hash chains traversed */
+    PRUint32              ngrows;         /* number of table expansions */
+    PRUint32              nshrinks;       /* number of table contractions */
+#endif
+};
+
+/*
+ * Create a new hash table.
+ * If allocOps is null, use default allocator ops built on top of malloc().
+ */
+PR_EXTERN(PLHashTable *)
+PL_NewHashTable(PRUint32 numBuckets, PLHashFunction keyHash,
+                PLHashComparator keyCompare, PLHashComparator valueCompare,
+                const PLHashAllocOps *allocOps, void *allocPriv);
+
+PR_EXTERN(void)
+PL_HashTableDestroy(PLHashTable *ht);
+
+/* Higher level access methods */
+PR_EXTERN(PLHashEntry *)
+PL_HashTableAdd(PLHashTable *ht, const void *key, void *value);
+
+PR_EXTERN(PRBool)
+PL_HashTableRemove(PLHashTable *ht, const void *key);
+
+PR_EXTERN(void *)
+PL_HashTableLookup(PLHashTable *ht, const void *key);
+
+PR_EXTERN(void *)
+PL_HashTableLookupConst(PLHashTable *ht, const void *key);
+
+PR_EXTERN(PRIntn)
+PL_HashTableEnumerateEntries(PLHashTable *ht, PLHashEnumerator f, void *arg);
+
+/* General-purpose C string hash function. */
+PR_EXTERN(PLHashNumber)
+PL_HashString(const void *key);
+
+/* Compare strings using strcmp(), return true if equal. */
+PR_EXTERN(PRIntn)
+PL_CompareStrings(const void *v1, const void *v2);
+
+/* Stub function just returns v1 == v2 */
+PR_EXTERN(PRIntn)
+PL_CompareValues(const void *v1, const void *v2);
+
+/* Low level access methods */
+PR_EXTERN(PLHashEntry **)
+PL_HashTableRawLookup(PLHashTable *ht, PLHashNumber keyHash, const void *key);
+
+PR_EXTERN(PLHashEntry **)
+PL_HashTableRawLookupConst(PLHashTable *ht, PLHashNumber keyHash,
+                           const void *key);
+
+PR_EXTERN(PLHashEntry *)
+PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep, PLHashNumber keyHash,
+                   const void *key, void *value);
+
+PR_EXTERN(void)
+PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he);
+
+/* This can be trivially implemented using PL_HashTableEnumerateEntries. */
+PR_EXTERN(PRIntn)
+PL_HashTableDump(PLHashTable *ht, PLHashEnumerator dump, FILE *fp);
+
+PR_END_EXTERN_C
+
+#endif /* plhash_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/ds/plvrsion.c b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plvrsion.c
new file mode 100644
index 0000000..486a6cb
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/ds/plvrsion.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prvrsion.h"
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+#include "_pl_bld.h"
+#if !defined(_BUILD_TIME)
+#ifdef HAVE_LONG_LONG
+#define _BUILD_TIME 0
+#else
+#define _BUILD_TIME {0, 0}
+#endif
+#endif
+#if !defined(_BUILD_STRING)
+#define _BUILD_STRING ""
+#endif
+#if !defined(_PRODUCTION)
+#define _PRODUCTION ""
+#endif
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * 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 */
+#if defined(DEBUG)
+    /* debug            */  PR_TRUE,            /* a debug build */
+#else
+    /* debug            */  PR_FALSE,           /* an optomized build */
+#endif
+    /* special          */  PR_FALSE,           /* they're all special, but ... */
+    /* filename         */  _PRODUCTION,        /* the produced library name */
+    /* description      */ "Portable runtime",  /* what we are */
+    /* security         */ "N/A",               /* not applicable here */
+    /* copywrite        */  "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved",
+    /* comment          */  "http://www.mozilla.org/MPL/",
+    /* specialString    */ ""
+};
+
+#ifdef XP_UNIX
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING
+        "  " _BUILD_STRING " $";
+static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
+        "  " _BUILD_STRING;
+
+#endif /* XP_UNIX */
+
+PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
+{
+#ifdef XP_UNIX
+    /*
+     * 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 &VERSION_DESC_NAME;
+}  /* versionEntryPointType */
+
+/* plvrsion.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/libc/Makefile.in
new file mode 100644
index 0000000..9755225
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/Makefile.in
@@ -0,0 +1,56 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+export NSPR20=1
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = include src
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/README b/nspr-4.8.6/mozilla/nsprpub/lib/libc/README
new file mode 100644
index 0000000..74f2469
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/README
@@ -0,0 +1,20 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains various libc-types of functions. All functions in
+this directory are platform independent, thread friendly (both safe and
+efficient). They are contributed from various sources, though the contri-
+butions are monitored by the NSPR group (mailto:freier).
+
+All API items exported by these functions will contain the same three
+character prefix, "PL_" (Portable Library). Internal function names
+that are not exported (static) are of little concern, though some caution
+must be used on those elements that are 'extern' but not really intended
+to be part of the API. Those should all have a prefix of "_PL_" (is that
+legal?).
+
+The responsibility for contributions in this area are distributed among
+all interested parties.
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/Makefile.in
new file mode 100644
index 0000000..a64a66c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/Makefile.in
@@ -0,0 +1,56 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/config.mk
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(HEADERS)
+	$(INSTALL) -m 444 $(HEADERS) $(dist_includedir)
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/README b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/README
new file mode 100644
index 0000000..2b85218
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/README
@@ -0,0 +1,7 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains the API for various libc-types of functions.
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plbase64.h b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plbase64.h
new file mode 100644
index 0000000..d21ff5d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plbase64.h
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _plbase64_h
+#define _plbase64_h
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+ * PL_Base64Encode
+ *
+ * This routine encodes the data pointed to by the "src" parameter using the
+ * base64 algorithm, and returns a pointer to the result.  If the "srclen"
+ * parameter is not zero, it specifies the length of the source data.  If it
+ * is zero, the source data is assumed to be null-terminated, and PL_strlen
+ * is used to determine the source length.  If the "dest" parameter is not
+ * null, it is assumed to point to a buffer of sufficient size (which may be
+ * calculated: ((srclen + 2)/3)*4) into which the encoded data is placed 
+ * (without any termination).  If the "dest" parameter is null, a buffer is
+ * allocated from the heap to hold the encoded data, and the result *will*
+ * be terminated with an extra null character.  It is the caller's 
+ * responsibility to free the result when it is allocated.  A null is returned 
+ * if the allocation fails.
+ *
+ * NOTE: when calculating ((srclen + 2)/3)*4), first ensure that
+ *     srclen <= (PR_UINT32_MAX/4) * 3
+ * to avoid PRUint32 overflow.
+ */
+
+PR_EXTERN(char *)
+PL_Base64Encode
+(
+    const char *src,
+    PRUint32    srclen,
+    char       *dest
+);
+
+/*
+ * PL_Base64Decode
+ *
+ * This routine decodes the data pointed to by the "src" parameter using
+ * the base64 algorithm, and returns a pointer to the result.  The source
+ * may either include or exclude any trailing '=' characters.  If the
+ * "srclen" parameter is not zero, it specifies the length of the source
+ * data.  If it is zero, PL_strlen will be used to determine the source
+ * length.  If the "dest" parameter is not null, it is assumed to point to
+ * a buffer of sufficient size (which may be calculated: (srclen * 3)/4
+ * when srclen includes the '=' characters) into which the decoded data
+ * is placed (without any termination).  If the "dest" parameter is null,
+ * a buffer is allocated from the heap to hold the decoded data, and the
+ * result *will* be terminated with an extra null character.  It is the
+ * caller's responsibility to free the result when it is allocated.  A null
+ * is retuned if the allocation fails, or if the source is not well-coded.
+ *
+ * NOTE: when calculating (srclen * 3)/4, first ensure that 
+ *     srclen <= PR_UINT32_MAX/3
+ * to avoid PRUint32 overflow.  Alternatively, calculate
+ *     (srclen/4) * 3 + ((srclen%4) * 3)/4
+ * which is equivalent but doesn't overflow for any value of srclen.
+ */
+
+PR_EXTERN(char *)
+PL_Base64Decode
+(
+    const char *src,
+    PRUint32    srclen,
+    char       *dest
+);
+
+PR_END_EXTERN_C
+
+#endif /* _plbase64_h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plerror.h b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plerror.h
new file mode 100644
index 0000000..a2b8d0b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plerror.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        plerror.h
+** Description: Simple routine to print translate the calling thread's
+**              error numbers and print them.
+*/
+
+#if defined(PLERROR_H)
+#else
+#define PLERROR_H
+
+#include "prio.h"
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+/*
+** Print the messages to "syserr" prepending 'msg' if not NULL.
+*/
+PR_EXTERN(void) PL_PrintError(const char *msg);
+
+/*
+** Print the messages to specified output file prepending 'msg' if not NULL.
+*/
+PR_EXTERN(void) PL_FPrintError(PRFileDesc *output, const char *msg);
+
+PR_END_EXTERN_C
+
+#endif /* defined(PLERROR_H) */
+
+/* plerror.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plgetopt.h b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plgetopt.h
new file mode 100644
index 0000000..c59fabd
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plgetopt.h
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:          plgetopt.h
+** Description:   utilities to parse argc/argv
+*/
+
+#if defined(PLGETOPT_H_)
+#else
+#define PLGETOPT_H_
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLOptionInternal PLOptionInternal; 
+
+typedef enum
+{
+        PL_OPT_OK,              /* all's well with the option */
+        PL_OPT_EOL,             /* end of options list */
+        PL_OPT_BAD              /* invalid option (and value) */
+} PLOptStatus;
+
+typedef struct PLLongOpt
+{
+    const char * longOptName;   /* long option name string                  */
+    PRIntn       longOption;    /* value put in PLOptState for this option. */
+    PRBool       valueRequired; /* If option name not followed by '=',      */
+                                /* value is the next argument from argv.    */
+} PLLongOpt;
+
+typedef struct PLOptState
+{
+    char option;                /* the name of the option */
+    const char *value;          /* the value of that option | NULL */
+
+    PLOptionInternal *internal; /* private processing state */
+
+    PRIntn   longOption;        /* value from PLLongOpt put here */
+    PRIntn   longOptIndex;      /* index into caller's array of PLLongOpts */
+} PLOptState;
+
+/*
+ * PL_CreateOptState
+ *
+ * The argument "options" points to a string of single-character option 
+ * names.  Option names that may have an option argument value must be 
+ * followed immediately by a ':' character.  
+ */
+PR_EXTERN(PLOptState*) PL_CreateOptState(
+        PRIntn argc, char **argv, const char *options);
+
+/* 
+ * PL_CreateLongOptState
+ *
+ * Alternative to PL_CreateOptState.  
+ * Allows caller to specify BOTH a string of single-character option names, 
+ * AND an array of structures describing "long" (keyword) option names.  
+ * The array is terminated by a structure in which longOptName is NULL.  
+ * Long option values (arguments) may always be given as "--name=value".
+ * If PLLongOpt.valueRequired is not PR_FALSE, and the option name was not 
+ * followed by '=' then the next argument from argv is taken as the value.  
+ */
+PR_EXTERN(PLOptState*) PL_CreateLongOptState(
+        PRIntn argc, char **argv, const char *options, 
+        const PLLongOpt *longOpts);
+/*
+ * PL_DestroyOptState
+ *
+ * Call this to destroy the PLOptState returned from PL_CreateOptState or
+ * PL_CreateLongOptState.
+ */
+PR_EXTERN(void) PL_DestroyOptState(PLOptState *opt);
+
+/*
+ * PL_GetNextOpt
+ *
+ * When this function returns PL_OPT_OK, 
+ * - opt->option will hold the single-character option name that was parsed, 
+ *   or zero.  
+ * When opt->option is zero, the token parsed was either a "long" (keyword) 
+ *   option or a positional parameter.  
+ * For a positional parameter, 
+ * - opt->longOptIndex will contain -1, and
+ * - opt->value will point to the positional parameter string.
+ * For a long option name, 
+ * - opt->longOptIndex will contain the non-negative index of the 
+ *   PLLongOpt structure in the caller's array of PLLongOpt structures 
+ *   corresponding to the long option name, and 
+ * For a single-character or long option, 
+ * - opt->longOption will contain the value of the single-character option
+ *   name, or the value of the longOption from the PLLongOpt structure
+ *   for that long option.  See notes below.
+ * - opt->value will point to the argument option string, or will
+ *   be NULL if option does not require argument.  If option requires
+ *   argument but it is not provided, PL_OPT_BAD is returned.
+ * When opt->option is non-zero, 
+ * - opt->longOptIndex will be -1
+ * When this function returns PL_OPT_EOL, or PL_OPT_BAD, the contents of
+ *   opt are undefined.
+ *
+ * Notes: It is possible to ignore opt->option, and always look at 
+ *   opt->longOption instead.  opt->longOption will contain the same value
+ *   as opt->option for single-character option names, and will contain the
+ *   value of longOption from the PLLongOpt structure for long option names.
+ * This means that it is possible to equivalence long option names to 
+ *   single character names by giving the longOption in the PLLongOpt struct
+ *   the same value as the single-character option name.  
+ * For long options that are NOT intended to be equivalent to any single-
+ *   character option, the longOption value should be chosen to not match 
+ *   any possible single character name.  It might be advisable to choose
+ *   longOption values greater than 0xff for such long options.
+ */
+PR_EXTERN(PLOptStatus) PL_GetNextOpt(PLOptState *opt);
+
+PR_END_EXTERN_C
+
+#endif /* defined(PLGETOPT_H_) */
+
+/* plgetopt.h */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plstr.h b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plstr.h
new file mode 100644
index 0000000..4d21cc4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/include/plstr.h
@@ -0,0 +1,470 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Roland Mainz <roland mainz@informatik.med.uni-giessen.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _plstr_h
+#define _plstr_h
+
+/*
+ * plstr.h
+ *
+ * This header file exports the API to the NSPR portable library or string-
+ * handling functions.  
+ * 
+ * This API was not designed as an "optimal" or "ideal" string library; it 
+ * was based on the good ol' unix string.3 functions, and was written to
+ *
+ *  1) replace the libc functions, for cross-platform consistency, 
+ *  2) complete the API on platforms lacking common functions (e.g., 
+ *     strcase*), and
+ *  3) to implement some obvious "closure" functions that I've seen
+ *     people hacking around in our code.
+ *
+ * Point number three largely means that most functions have an "strn"
+ * limited-length version, and all comparison routines have a non-case-
+ * sensitive version available.
+ */
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+/*
+ * PL_strlen
+ *
+ * Returns the length of the provided string, not including the trailing '\0'.
+ */
+
+PR_EXTERN(PRUint32)
+PL_strlen(const char *str);
+
+/*
+ * PL_strnlen
+ *
+ * Returns the length of the provided string, not including the trailing '\0',
+ * up to the indicated maximum.  The string will not be examined beyond the
+ * maximum; if no terminating '\0' is found, the maximum will be returned.
+ */
+
+PR_EXTERN(PRUint32)
+PL_strnlen(const char *str, PRUint32 max);
+
+/*
+ * PL_strcpy
+ *
+ * Copies the source string, up to and including the trailing '\0', into the
+ * destination buffer.  It does not (can not) verify that the destination
+ * buffer is large enough.  It returns the "dest" argument.
+ */
+
+PR_EXTERN(char *)
+PL_strcpy(char *dest, const char *src);
+
+/*
+ * PL_strncpy
+ *
+ * Copies the source string into the destination buffer, up to and including
+ * the trailing '\0' or up to and including the max'th character, whichever
+ * comes first.  It does not (can not) verify that the destination buffer is
+ * large enough.  If the source string is longer than the maximum length,
+ * the result will *not* be null-terminated (JLRU).
+ */
+
+PR_EXTERN(char *)
+PL_strncpy(char *dest, const char *src, PRUint32 max);
+
+/*
+ * PL_strncpyz
+ *
+ * Copies the source string into the destination buffer, up to and including 
+ * the trailing '\0' or up but not including the max'th character, whichever 
+ * comes first.  It does not (can not) verify that the destination buffer is
+ * large enough.  The destination string is always terminated with a '\0',
+ * unlike the traditional libc implementation.  It returns the "dest" argument.
+ *
+ * NOTE: If you call this with a source "abcdefg" and a max of 5, the 
+ * destination will end up with "abcd\0" (i.e., its strlen length will be 4)!
+ *
+ * This means you can do this:
+ *
+ *     char buffer[ SOME_SIZE ];
+ *     PL_strncpyz(buffer, src, sizeof(buffer));
+ *
+ * and the result will be properly terminated.
+ */
+
+PR_EXTERN(char *)
+PL_strncpyz(char *dest, const char *src, PRUint32 max);
+
+/*
+ * PL_strdup
+ *
+ * Returns a pointer to a malloc'd extent of memory containing a duplicate
+ * of the argument string.  The size of the allocated extent is one greater
+ * than the length of the argument string, because of the terminator.  A
+ * null argument, like a zero-length argument, will result in a pointer to
+ * a one-byte extent containing the null value.  This routine returns null
+ * upon malloc failure.
+ */
+
+PR_EXTERN(char *)
+PL_strdup(const char *s);
+
+/*
+ * PL_strfree
+ *
+ * Free memory allocated by PL_strdup
+ */
+
+PR_EXTERN(void)
+PL_strfree(char *s);
+
+/*
+ * PL_strndup
+ *
+ * Returns a pointer to a malloc'd extent of memory containing a duplicate
+ * of the argument string, up to the maximum specified.  If the argument
+ * string has a length greater than the value of the specified maximum, the
+ * return value will be a pointer to an extent of memory of length one
+ * greater than the maximum specified.  A null string, a zero-length string,
+ * or a zero maximum will all result in a pointer to a one-byte extent
+ * containing the null value.  This routine returns null upon malloc failure.
+ */
+
+PR_EXTERN(char *)
+PL_strndup(const char *s, PRUint32 max);
+
+/*
+ * PL_strcat
+ *
+ * Appends a copy of the string pointed to by the second argument to the
+ * end of the string pointed to by the first.  The destination buffer is
+ * not (can not be) checked for sufficient size.  A null destination
+ * argument returns null; otherwise, the first argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strcat(char *dst, const char *src);
+
+/*
+ * PL_strncat
+ *
+ * Appends a copy of the string pointed to by the second argument, up to
+ * the maximum size specified, to the end of the string pointed to by the
+ * first.  The destination buffer is not (can not be) checked for sufficient
+ * size.  A null destination argument returns null; otherwise, the first 
+ * argument is returned.  If the maximum size limits the copy, then the
+ * result will *not* be null-terminated (JLRU).  A null destination
+ * returns null; otherwise, the destination argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strncat(char *dst, const char *src, PRUint32 max);
+
+/*
+ * PL_strcatn
+ *
+ * Appends a copy of the string pointed to by the third argument, to the
+ * end of the string pointed to by the first.  The second argument specifies
+ * the maximum size of the destination buffer, including the null termination.
+ * If the existing string in dst is longer than the max, no action is taken.
+ * The resulting string will be null-terminated.  A null destination returns
+ * null; otherwise, the destination argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strcatn(char *dst, PRUint32 max, const char *src);
+
+/*
+ * PL_strcmp
+ *
+ * Returns an integer, the sign of which -- positive, zero, or negative --
+ * reflects the lexical sorting order of the two strings indicated.  The
+ * result is positive if the first string comes after the second.  The
+ * NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strcmp(const char *a, const char *b);
+
+/*
+ * PL_strncmp
+ * 
+ * Returns an integer, the sign of which -- positive, zero, or negative --
+ * reflects the lexical sorting order of the two strings indicated, up to
+ * the maximum specified.  The result is positive if the first string comes 
+ * after the second.  The NSPR implementation is not i18n.  If the maximum
+ * is zero, only the existance or non-existance (pointer is null) of the
+ * strings is compared.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strncmp(const char *a, const char *b, PRUint32 max);
+
+/*
+ * PL_strcasecmp
+ *
+ * Returns an integer, the sign of which -- positive, zero or negative --
+ * reflects the case-insensitive lexical sorting order of the two strings
+ * indicated.  The result is positive if the first string comes after the 
+ * second.  The NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strcasecmp(const char *a, const char *b);
+
+/*
+ * PL_strncasecmp
+ *
+ * Returns an integer, the sign of which -- positive, zero or negative --
+ * reflects the case-insensitive lexical sorting order of the first n characters
+ * of the two strings indicated.  The result is positive if the first string comes 
+ * after the second.  The NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strncasecmp(const char *a, const char *b, PRUint32 max);
+
+/*
+ * PL_strchr
+ *
+ * Returns a pointer to the first instance of the specified character in the
+ * provided string.  It returns null if the character is not found, or if the
+ * provided string is null.  The character may be the null character.
+ */
+
+PR_EXTERN(char *)
+PL_strchr(const char *s, char c);
+
+/*
+ * PL_strrchr
+ *
+ * Returns a pointer to the last instance of the specified character in the
+ * provided string.  It returns null if the character is not found, or if the
+ * provided string is null.  The character may be the null character.
+ */
+
+PR_EXTERN(char *)
+PL_strrchr(const char *s, char c);
+
+/*
+ * PL_strnchr
+ * 
+ * Returns a pointer to the first instance of the specified character within the
+ * first n characters of the provided string.  It returns null if the character
+ * is not found, or if the provided string is null.  The character may be the
+ * null character.
+ */
+
+PR_EXTERN(char *)
+PL_strnchr(const char *s, char c, PRUint32 n);
+
+/*
+ * PL_strnrchr
+ *
+ * Returns a pointer to the last instance of the specified character within the
+ * first n characters of the provided string.  It returns null if the character is
+ * not found, or if the provided string is null.  The character may be the null
+ * character.
+ */
+
+PR_EXTERN(char *)
+PL_strnrchr(const char *s, char c, PRUint32 n);
+
+/*
+ * NOTE: Looking for strcasechr, strcaserchr, strncasechr, or strncaserchr?
+ * Use strpbrk, strprbrk, strnpbrk or strnprbrk.
+ */
+
+/*
+ * PL_strpbrk
+ *
+ * Returns a pointer to the first instance in the first string of any character
+ * (not including the terminating null character) of the second string.  It returns
+ * null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strpbrk(const char *s, const char *list);
+
+/*
+ * PL_strprbrk
+ *
+ * Returns a pointer to the last instance in the first string of any character
+ * (not including the terminating null character) of the second string.  It returns
+ * null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strprbrk(const char *s, const char *list);
+
+/*
+ * PL_strnpbrk
+ *
+ * Returns a pointer to the first instance (within the first n characters) of any
+ * character (not including the terminating null character) of the second string.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strnpbrk(const char *s, const char *list, PRUint32 n);
+
+/*
+ * PL_strnprbrk
+ *
+ * Returns a pointer to the last instance (within the first n characters) of any
+ * character (not including the terminating null character) of the second string.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strnprbrk(const char *s, const char *list, PRUint32 n);
+
+/*
+ * PL_strstr
+ *
+ * Returns a pointer to the first instance of the little string within the
+ * big one.  It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strstr(const char *big, const char *little);
+
+/*
+ * PL_strrstr
+ *
+ * Returns a pointer to the last instance of the little string within the big one.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strrstr(const char *big, const char *little);
+
+/*
+ * PL_strnstr
+ *
+ * Returns a pointer to the first instance of the little string within the first
+ * n characters of the big one.  It returns null if either string is null.  It
+ * returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strnstr(const char *big, const char *little, PRUint32 n);
+
+/*
+ * PL_strnrstr
+ *
+ * Returns a pointer to the last instance of the little string within the first
+ * n characters of the big one.  It returns null if either string is null.  It
+ * returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strnrstr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strcasestr
+ *
+ * Returns a pointer to the first instance of the little string within the big one,
+ * ignoring case.  It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strcasestr(const char *big, const char *little);
+
+/*
+ * PL_strcaserstr
+ *
+ * Returns a pointer to the last instance of the little string within the big one,
+ * ignoring case.  It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strcaserstr(const char *big, const char *little);
+
+/*
+ * PL_strncasestr
+ *
+ * Returns a pointer to the first instance of the little string within the first
+ * n characters of the big one, ignoring case.  It returns null if either string is 
+ * null.  It returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strncasestr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strncaserstr
+ *
+ * Returns a pointer to the last instance of the little string within the first
+ * n characters of the big one, ignoring case.  It returns null if either string is
+ * null.  It returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strncaserstr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strtok_r
+ *
+ * Splits the string s1 into tokens, separated by one or more characters
+ * from the separator string s2.  The argument lasts points to a
+ * user-supplied char * pointer in which PL_strtok_r stores information
+ * for it to continue scanning the same string.
+ *
+ * In the first call to PL_strtok_r, s1 points to a string and the value
+ * of *lasts is ignored.  PL_strtok_r returns a pointer to the first
+ * token, writes '\0' into the character following the first token, and
+ * updates *lasts.
+ *
+ * In subsequent calls, s1 is null and lasts must stay unchanged from the
+ * previous call.  The separator string s2 may be different from call to
+ * call.  PL_strtok_r returns a pointer to the next token in s1.  When no
+ * token remains in s1, PL_strtok_r returns null.
+ */
+
+PR_EXTERN(char *)
+PL_strtok_r(char *s1, const char *s2, char **lasts);
+
+/*
+ * Things not (yet?) included: strspn/strcspn, strsep.
+ * memchr, memcmp, memcpy, memccpy, index, rindex, bcmp, bcopy, bzero.
+ * Any and all i18n/l10n stuff.
+ */
+
+PR_END_EXTERN_C
+
+#endif /* _plstr_h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/Makefile.in
new file mode 100644
index 0000000..2cafb1a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/Makefile.in
@@ -0,0 +1,187 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+INCLUDES = -I$(dist_includedir)
+
+CSRCS =\
+	plvrsion.c  \
+	strlen.c  \
+	strcpy.c  \
+	strdup.c  \
+	strcase.c \
+	strcat.c  \
+	strcmp.c  \
+	strchr.c  \
+	strpbrk.c \
+	strstr.c  \
+	strtok.c  \
+	base64.c \
+	plerror.c \
+	plgetopt.c \
+	$(NULL)
+
+LIBRARY_NAME	= plc
+LIBRARY_VERSION	= $(MOD_MAJOR_VERSION)
+
+RELEASE_LIBS = $(TARGETS)
+
+ifeq ($(OS_ARCH),WINNT)
+RES=$(OBJDIR)/plc.res
+RESNAME=plc.rc
+endif # WINNT
+
+ifeq ($(OS_ARCH), AIX)
+ifeq ($(CLASSIC_NSPR),1)
+OS_LIBS = -lc
+else
+OS_LIBS = -lc_r
+endif
+endif
+
+ifeq ($(OS_ARCH),IRIX)
+OS_LIBS = -lc
+endif
+
+ifeq ($(OS_ARCH),SunOS)
+OS_LIBS = -lc
+MAPFILE = $(OBJDIR)/plcmap.sun
+GARBAGE += $(MAPFILE)
+ifdef NS_USE_GCC
+ifdef GCC_USE_GNU_LD
+MKSHLIB += -Wl,--version-script,$(MAPFILE)
+else
+MKSHLIB += -Wl,-M,$(MAPFILE)
+endif
+else
+MKSHLIB += -M $(MAPFILE)
+endif
+# The -R '$ORIGIN' linker option instructs this library to search for its
+# dependencies in the same directory where it resides.
+MKSHLIB += -R '$$ORIGIN'
+endif
+
+ifeq ($(OS_ARCH),OS2)
+MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def
+GARBAGE += $(MAPFILE)
+MKSHLIB += $(MAPFILE)
+endif
+
+EXTRA_LIBS = $(LIBNSPR)
+
+# On NCR and SCOOS, we can't link with extra libraries when
+# we build a shared library.  If we do so, the linker doesn't
+# complain, but we would run into weird problems at run-time.
+# Therefore on these platforms, we link just the .o files.
+ifeq ($(OS_ARCH),NCR)
+EXTRA_LIBS =
+endif
+ifeq ($(OS_ARCH),SCOOS)
+EXTRA_LIBS =
+endif
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+TINC = $(OBJDIR)/_pl_bld.h
+PROD = $(notdir $(SHARED_LIBRARY))
+NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
+SH_DATE = $(shell date "+%Y-%m-%d %T")
+SH_NOW = $(shell $(NOW))
+
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	SUF = i64
+else
+	SUF = LL
+endif
+
+GARBAGE += $(TINC)
+
+$(TINC):
+	@$(MAKE_OBJDIR)
+	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+	@if test ! -z "$(SH_NOW)"; then \
+	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+	else \
+	    true; \
+	fi
+	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
+
+
+$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+	$(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+endif
+#
+# Version information generation (end)
+#
+
+#
+# The Client build wants the shared libraries in $(dist_bindir),
+# so we also install them there.
+#
+
+export:: $(TARGETS)
+	$(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifdef SHARED_LIBRARY
+ifeq ($(OS_ARCH),HP-UX)
+	$(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir)
+	$(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir)
+else
+	$(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir)
+endif
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/README b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/README
new file mode 100644
index 0000000..74f2469
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/README
@@ -0,0 +1,20 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains various libc-types of functions. All functions in
+this directory are platform independent, thread friendly (both safe and
+efficient). They are contributed from various sources, though the contri-
+butions are monitored by the NSPR group (mailto:freier).
+
+All API items exported by these functions will contain the same three
+character prefix, "PL_" (Portable Library). Internal function names
+that are not exported (static) are of little concern, though some caution
+must be used on those elements that are 'extern' but not really intended
+to be part of the API. Those should all have a prefix of "_PL_" (is that
+legal?).
+
+The responsibility for contributions in this area are distributed among
+all interested parties.
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/base64.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/base64.c
new file mode 100644
index 0000000..e3fd80d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/base64.c
@@ -0,0 +1,448 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plbase64.h"
+#include "prlog.h" /* For PR_NOT_REACHED */
+#include "prmem.h" /* for malloc / PR_MALLOC */
+
+#include <string.h> /* for strlen */
+
+static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static void
+encode3to4
+(
+    const unsigned char    *src,
+    unsigned char          *dest
+)
+{
+    PRUint32 b32 = (PRUint32)0;
+    PRIntn i, j = 18;
+
+    for( i = 0; i < 3; i++ )
+    {
+        b32 <<= 8;
+        b32 |= (PRUint32)src[i];
+    }
+
+    for( i = 0; i < 4; i++ )
+    {
+        dest[i] = base[ (PRUint32)((b32>>j) & 0x3F) ];
+        j -= 6;
+    }
+
+    return;
+}
+
+static void
+encode2to4
+(
+    const unsigned char    *src,
+    unsigned char          *dest
+)
+{
+    dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ];
+    dest[1] = base[ (PRUint32)(((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)) ];
+    dest[2] = base[ (PRUint32)((src[1] & 0x0F) << 2) ];
+    dest[3] = (unsigned char)'=';
+    return;
+}
+
+static void
+encode1to4
+(
+    const unsigned char    *src,
+    unsigned char          *dest
+)
+{
+    dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ];
+    dest[1] = base[ (PRUint32)((src[0] & 0x03) << 4) ];
+    dest[2] = (unsigned char)'=';
+    dest[3] = (unsigned char)'=';
+    return;
+}
+
+static void
+encode
+(
+    const unsigned char    *src,
+    PRUint32                srclen,
+    unsigned char          *dest
+)
+{
+    while( srclen >= 3 )
+    {
+        encode3to4(src, dest);
+        src += 3;
+        dest += 4;
+        srclen -= 3;
+    }
+
+    switch( srclen )
+    {
+        case 2:
+            encode2to4(src, dest);
+            break;
+        case 1:
+            encode1to4(src, dest);
+            break;
+        case 0:
+            break;
+        default:
+            PR_NOT_REACHED("coding error");
+    }
+
+    return;
+}
+
+/*
+ * PL_Base64Encode
+ *
+ * If the destination argument is NULL, a return buffer is 
+ * allocated, and the data therein will be null-terminated.  
+ * If the destination argument is not NULL, it is assumed to
+ * be of sufficient size, and the contents will not be null-
+ * terminated by this routine.
+ *
+ * Returns null if the allocation fails.
+ */
+
+PR_IMPLEMENT(char *)
+PL_Base64Encode
+(
+    const char *src,
+    PRUint32    srclen,
+    char       *dest
+)
+{
+    if( 0 == srclen )
+    {
+        size_t len = strlen(src);
+        srclen = len;
+        /* Detect truncation. */
+        if( srclen != len )
+        {
+            return (char *)0;
+        }
+    }
+
+    if( (char *)0 == dest )
+    {
+        PRUint32 destlen;
+        /* Ensure all PRUint32 values stay within range. */
+        if( srclen > (PR_UINT32_MAX/4) * 3 )
+        {
+            return (char *)0;
+        }
+        destlen = ((srclen + 2)/3) * 4;
+        dest = (char *)PR_MALLOC(destlen + 1);
+        if( (char *)0 == dest )
+        {
+            return (char *)0;
+        }
+        dest[ destlen ] = (char)0; /* null terminate */
+    }
+
+    encode((const unsigned char *)src, srclen, (unsigned char *)dest);
+    return dest;
+}
+
+static PRInt32
+codetovalue
+(
+    unsigned char c
+)
+{
+    if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') )
+    {
+        return (PRInt32)(c - (unsigned char)'A');
+    }
+    else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') )
+    {
+        return ((PRInt32)(c - (unsigned char)'a') +26);
+    }
+    else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') )
+    {
+        return ((PRInt32)(c - (unsigned char)'0') +52);
+    }
+    else if( (unsigned char)'+' == c )
+    {
+        return (PRInt32)62;
+    }
+    else if( (unsigned char)'/' == c )
+    {
+        return (PRInt32)63;
+    }
+    else
+    {
+        return -1;
+    }
+}
+
+static PRStatus
+decode4to3
+(
+    const unsigned char    *src,
+    unsigned char          *dest
+)
+{
+    PRUint32 b32 = (PRUint32)0;
+    PRInt32 bits;
+    PRIntn i;
+
+    for( i = 0; i < 4; i++ )
+    {
+        bits = codetovalue(src[i]);
+        if( bits < 0 )
+        {
+            return PR_FAILURE;
+        }
+
+        b32 <<= 6;
+        b32 |= bits;
+    }
+
+    dest[0] = (unsigned char)((b32 >> 16) & 0xFF);
+    dest[1] = (unsigned char)((b32 >>  8) & 0xFF);
+    dest[2] = (unsigned char)((b32      ) & 0xFF);
+
+    return PR_SUCCESS;
+}
+
+static PRStatus
+decode3to2
+(
+    const unsigned char    *src,
+    unsigned char          *dest
+)
+{
+    PRUint32 b32 = (PRUint32)0;
+    PRInt32 bits;
+    PRUint32 ubits;
+
+    bits = codetovalue(src[0]);
+    if( bits < 0 )
+    {
+        return PR_FAILURE;
+    }
+
+    b32 = (PRUint32)bits;
+    b32 <<= 6;
+
+    bits = codetovalue(src[1]);
+    if( bits < 0 )
+    {
+        return PR_FAILURE;
+    }
+
+    b32 |= (PRUint32)bits;
+    b32 <<= 4;
+
+    bits = codetovalue(src[2]);
+    if( bits < 0 )
+    {
+        return PR_FAILURE;
+    }
+
+    ubits = (PRUint32)bits;
+    b32 |= (ubits >> 2);
+
+    dest[0] = (unsigned char)((b32 >> 8) & 0xFF);
+    dest[1] = (unsigned char)((b32     ) & 0xFF);
+
+    return PR_SUCCESS;
+}
+
+static PRStatus
+decode2to1
+(
+    const unsigned char    *src,
+    unsigned char          *dest
+)
+{
+    PRUint32 b32;
+    PRUint32 ubits;
+    PRInt32 bits;
+
+    bits = codetovalue(src[0]);
+    if( bits < 0 )
+    {
+        return PR_FAILURE;
+    }
+
+    ubits = (PRUint32)bits;
+    b32 = (ubits << 2);
+
+    bits = codetovalue(src[1]);
+    if( bits < 0 )
+    {
+        return PR_FAILURE;
+    }
+
+    ubits = (PRUint32)bits;
+    b32 |= (ubits >> 4);
+
+    dest[0] = (unsigned char)b32;
+
+    return PR_SUCCESS;
+}
+
+static PRStatus
+decode
+(
+    const unsigned char    *src,
+    PRUint32                srclen,
+    unsigned char          *dest
+)
+{
+    PRStatus rv;
+
+    while( srclen >= 4 )
+    {
+        rv = decode4to3(src, dest);
+        if( PR_SUCCESS != rv )
+        {
+            return PR_FAILURE;
+        }
+
+        src += 4;
+        dest += 3;
+        srclen -= 4;
+    }
+
+    switch( srclen )
+    {
+        case 3:
+            rv = decode3to2(src, dest);
+            break;
+        case 2:
+            rv = decode2to1(src, dest);
+            break;
+        case 1:
+            rv = PR_FAILURE;
+            break;
+        case 0:
+            rv = PR_SUCCESS;
+            break;
+        default:
+            PR_NOT_REACHED("coding error");
+    }
+
+    return rv;
+}
+
+/*
+ * PL_Base64Decode
+ *
+ * If the destination argument is NULL, a return buffer is
+ * allocated and the data therein will be null-terminated.
+ * If the destination argument is not null, it is assumed
+ * to be of sufficient size, and the data will not be null-
+ * terminated by this routine.
+ * 
+ * Returns null if the allocation fails, or if the source string is 
+ * not well-formed.
+ */
+
+PR_IMPLEMENT(char *)
+PL_Base64Decode
+(
+    const char *src,
+    PRUint32    srclen,
+    char       *dest
+)
+{
+    PRStatus status;
+    PRBool allocated = PR_FALSE;
+
+    if( (char *)0 == src )
+    {
+        return (char *)0;
+    }
+
+    if( 0 == srclen )
+    {
+        size_t len = strlen(src);
+        srclen = len;
+        /* Detect truncation. */
+        if( srclen != len )
+        {
+            return (char *)0;
+        }
+    }
+
+    if( srclen && (0 == (srclen & 3)) )
+    {
+        if( (char)'=' == src[ srclen-1 ] )
+        {
+            if( (char)'=' == src[ srclen-2 ] )
+            {
+                srclen -= 2;
+            }
+            else
+            {
+                srclen -= 1;
+            }
+        }
+    }
+
+    if( (char *)0 == dest )
+    {
+        /* The following computes ((srclen * 3) / 4) without overflow. */
+        PRUint32 destlen = (srclen / 4) * 3 + ((srclen % 4) * 3) / 4;
+        dest = (char *)PR_MALLOC(destlen + 1);
+        if( (char *)0 == dest )
+        {
+            return (char *)0;
+        }
+        dest[ destlen ] = (char)0; /* null terminate */
+        allocated = PR_TRUE;
+    }
+
+    status = decode((const unsigned char *)src, srclen, (unsigned char *)dest);
+    if( PR_SUCCESS != status )
+    {
+        if( PR_TRUE == allocated )
+        {
+            PR_DELETE(dest);
+        }
+
+        return (char *)0;
+    }
+
+    return dest;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plc.def b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plc.def
new file mode 100644
index 0000000..bb996a1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plc.def
@@ -0,0 +1,104 @@
+;+#
+;+# ***** BEGIN LICENSE BLOCK *****
+;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+;+#
+;+# The contents of this file are subject to the Mozilla Public License Version
+;+# 1.1 (the "License"); you may not use this file except in compliance with
+;+# the License. You may obtain a copy of the License at
+;+# http://www.mozilla.org/MPL/
+;+#
+;+# Software distributed under the License is distributed on an "AS IS" basis,
+;+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+;+# for the specific language governing rights and limitations under the
+;+# License.
+;+#
+;+# The Original Code is the Netscape Portable Runtime (NSPR).
+;+#
+;+# The Initial Developer of the Original Code is
+;+# Netscape Communications Corporation.
+;+# Portions created by the Initial Developer are Copyright (C) 2002-2003
+;+# the Initial Developer. All Rights Reserved.
+;+#
+;+# Contributor(s):
+;+#
+;+# Alternatively, the contents of this file may be used under the terms of
+;+# either the GNU General Public License Version 2 or later (the "GPL"), or
+;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+;+# in which case the provisions of the GPL or the LGPL are applicable instead
+;+# of those above. If you wish to allow use of your version of this file only
+;+# under the terms of either the GPL or the LGPL, and not to allow others to
+;+# use your version of this file under the terms of the MPL, indicate your
+;+# decision by deleting the provisions above and replace them with the notice
+;+# and other provisions required by the GPL or the LGPL. If you do not delete
+;+# the provisions above, a recipient may use your version of this file under
+;+# the terms of any one of the MPL, the GPL or the LGPL.
+;+#
+;+# ***** END LICENSE BLOCK *****
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS
+;+#   1. For all unix platforms, the string ";-"  means "remove this line"
+;+#   2. For all unix platforms, the string " DATA " will be removed from any 
+;+#     line on which it occurs.
+;+#   3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+#      On AIX, lines containing ";+" will be removed.
+;+#   4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+#   5. For all unix platforms, after the above processing has taken place,
+;+#    all characters after the first ";" on the line will be removed.
+;+#    And for AIX, the first ";" will also be removed.
+;+#  This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+#   directives are hidden behind ";", ";+", and ";-"
+;+NSPR_4.0 {
+;+    global:
+LIBRARY plc4 ;-
+EXPORTS ;-
+PL_Base64Decode;
+PL_Base64Encode;
+PL_CreateOptState;
+PL_DestroyOptState;
+PL_FPrintError;
+PL_GetNextOpt;
+PL_PrintError;
+PL_strcasecmp;
+PL_strcaserstr;
+PL_strcasestr;
+PL_strcat;
+PL_strcatn;
+PL_strchr;
+PL_strcmp;
+PL_strcpy;
+PL_strdup;
+PL_strfree;
+PL_strlen;
+PL_strncasecmp;
+PL_strncaserstr;
+PL_strncasestr;
+PL_strncat;
+PL_strnchr;
+PL_strncmp;
+PL_strncpy;
+PL_strncpyz;
+PL_strndup;
+PL_strnlen;
+PL_strnpbrk;
+PL_strnprbrk;
+PL_strnrchr;
+PL_strnrstr;
+PL_strnstr;
+PL_strpbrk;
+PL_strprbrk;
+PL_strrchr;
+PL_strrstr;
+PL_strstr;
+libVersionPoint;
+;+    local: *;
+;+};
+;+
+;+NSPR_4.2 {
+;+    global:
+PL_strtok_r;
+;+} NSPR_4.0;
+;+
+;+NSPR_4.7 {
+;+    global:
+PL_CreateLongOptState;
+;+} NSPR_4.2;
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plc.rc b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plc.rc
new file mode 100644
index 0000000..c20df27
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plc.rc
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#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
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+        BEGIN
+            VALUE "CompanyName", "Mozilla Foundation\0"
+            VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+            VALUE "FileVersion", PR_VERSION "\0"
+            VALUE "InternalName", MY_INTERNAL_NAME "\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
+    END
+END
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plerror.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plerror.c
new file mode 100644
index 0000000..90b713a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plerror.c
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:plerror.c
+** Description: Simple routine to print translate the calling thread's
+**  error numbers and print them to "syserr".
+*/
+
+#include "plerror.h"
+
+#include "prprf.h"
+#include "prerror.h"
+
+PR_IMPLEMENT(void) PL_FPrintError(PRFileDesc *fd, const char *msg)
+{
+PRErrorCode error = PR_GetError();
+PRInt32 oserror = PR_GetOSError();
+const char *name = PR_ErrorToName(error);
+
+	if (NULL != msg) PR_fprintf(fd, "%s: ", msg);
+    if (NULL == name)
+        PR_fprintf(
+			fd, " (%d)OUT OF RANGE, oserror = %d\n", error, oserror);
+    else
+        PR_fprintf(
+            fd, "%s(%d), oserror = %d\n",
+            name, error, oserror);
+}  /* PL_FPrintError */
+
+PR_IMPLEMENT(void) PL_PrintError(const char *msg)
+{
+	static PRFileDesc *fd = NULL;
+	if (NULL == fd) fd = PR_GetSpecialFD(PR_StandardError);
+	PL_FPrintError(fd, msg);
+}  /* PL_PrintError */
+
+/* plerror.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plgetopt.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plgetopt.c
new file mode 100644
index 0000000..2cd4896
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plgetopt.c
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:          plgetopt.c
+** Description:   utilities to parse argc/argv
+*/
+
+#include "prmem.h"
+#include "prlog.h"
+#include "prerror.h"
+#include "plstr.h"
+#include "plgetopt.h"
+
+#include <string.h>
+
+static char static_Nul = 0;
+
+struct PLOptionInternal
+{
+    const char *options;        /* client options list specification */
+    PRIntn argc;                /* original number of arguments */
+    char **argv;                /* vector of pointers to arguments */
+    PRIntn xargc;               /* which one we're processing now */
+    const char *xargv;          /* where within *argv[xargc] */
+    PRIntn minus;               /* do we already have the '-'? */
+    const PLLongOpt *longOpts;  /* Caller's array */
+    PRBool endOfOpts;           /* have reached a "--" argument */
+    PRIntn optionsLen;          /* is strlen(options) */
+};
+
+/*
+** Create the state in which to parse the tokens.
+**
+** argc        the sum of the number of options and their values
+** argv        the options and their values
+** options    vector of single character options w/ | w/o ':
+*/
+PR_IMPLEMENT(PLOptState*) PL_CreateOptState(
+    PRIntn argc, char **argv, const char *options)
+{
+    return PL_CreateLongOptState( argc, argv, options, NULL);
+}  /* PL_CreateOptState */
+
+PR_IMPLEMENT(PLOptState*) PL_CreateLongOptState(
+    PRIntn argc, char **argv, const char *options, 
+    const PLLongOpt *longOpts)
+{
+    PLOptState *opt = NULL;
+    PLOptionInternal *internal;
+
+    if (NULL == options) 
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return opt;
+    }
+
+    opt = PR_NEWZAP(PLOptState);
+    if (NULL == opt) 
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return opt;
+    }
+
+    internal = PR_NEW(PLOptionInternal);
+    if (NULL == internal)
+    {
+        PR_DELETE(opt);
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    opt->option = 0;
+    opt->value = NULL;
+    opt->internal = internal;
+    opt->longOption   =  0;
+    opt->longOptIndex = -1;
+
+    internal->argc = argc;
+    internal->argv = argv;
+    internal->xargc = 0;
+    internal->xargv = &static_Nul;
+    internal->minus = 0;
+    internal->options = options;
+    internal->longOpts = longOpts;
+    internal->endOfOpts = PR_FALSE;
+    internal->optionsLen = PL_strlen(options);
+
+    return opt;
+}  /* PL_CreateLongOptState */
+
+/*
+** Destroy object created by CreateOptState()
+*/
+PR_IMPLEMENT(void) PL_DestroyOptState(PLOptState *opt)
+{
+    PR_DELETE(opt->internal);
+    PR_DELETE(opt);
+}  /* PL_DestroyOptState */
+
+PR_IMPLEMENT(PLOptStatus) PL_GetNextOpt(PLOptState *opt)
+{
+    PLOptionInternal *internal = opt->internal;
+
+    opt->longOption   =  0;
+    opt->longOptIndex = -1;
+    /*
+    ** If the current xarg points to nul, advance to the next
+    ** element of the argv vector. If the vector index is equal
+    ** to argc, we're out of arguments, so return an EOL.
+    ** Note whether the first character of the new argument is
+    ** a '-' and skip by it if it is.
+    */
+    while (0 == *internal->xargv)
+    {
+        internal->xargc += 1;
+        if (internal->xargc >= internal->argc)
+        {
+            opt->option = 0;
+            opt->value = NULL;
+            return PL_OPT_EOL;
+        }
+        internal->xargv = internal->argv[internal->xargc];
+        internal->minus = 0;
+        if (!internal->endOfOpts && ('-' == *internal->xargv)) 
+        {
+            internal->minus++;
+            internal->xargv++;  /* and consume */
+            if ('-' == *internal->xargv && internal->longOpts) 
+            {
+                internal->minus++;
+                internal->xargv++;
+                if (0 == *internal->xargv) 
+                {
+                    internal->endOfOpts = PR_TRUE;
+                }
+            }
+        }
+    }
+
+    /*
+    ** If we already have a '-' or '--' in hand, xargv points to the next
+    ** option. See if we can find a match in the list of possible
+    ** options supplied.
+    */
+    if (internal->minus == 2) 
+    {
+        char * foundEqual = strchr(internal->xargv,'=');
+        PRIntn optNameLen = foundEqual ? (foundEqual - internal->xargv) :
+                            strlen(internal->xargv);
+        const PLLongOpt *longOpt = internal->longOpts;
+        PLOptStatus result = PL_OPT_BAD;
+
+        opt->option = 0;
+        opt->value  = NULL;
+
+        for (; longOpt->longOptName; ++longOpt) 
+        {
+            if (strncmp(longOpt->longOptName, internal->xargv, optNameLen))
+                continue;  /* not a possible match */
+            if (strlen(longOpt->longOptName) != optNameLen)
+                continue;  /* not a match */
+            /* option name match */
+            opt->longOptIndex = longOpt - internal->longOpts;
+            opt->longOption   = longOpt->longOption;
+            /* value is part of the current argv[] element if = was found */
+            /* note: this sets value even for long options that do not
+             * require option if specified as --long=value */
+            if (foundEqual) 
+            {
+                opt->value = foundEqual + 1;
+            }
+            else if (longOpt->valueRequired)
+            {
+                /* value is the next argv[] element, if any */
+                if (internal->xargc + 1 < internal->argc)
+                {
+                    opt->value = internal->argv[++(internal->xargc)];
+                }
+                /* missing value */
+                else
+                {
+                    break; /* return PL_OPT_BAD */
+                }
+            }
+            result = PL_OPT_OK;
+            break;
+        }
+        internal->xargv = &static_Nul; /* consume this */
+        return result;
+    }
+    if (internal->minus)
+    {
+        PRIntn cop;
+        PRIntn eoo = internal->optionsLen;
+        for (cop = 0; cop < eoo; ++cop)
+        {
+            if (internal->options[cop] == *internal->xargv)
+            {
+                opt->option = *internal->xargv++;
+                opt->longOption = opt->option & 0xff;
+                /*
+                ** if options indicates that there's an associated
+                ** value, it must be provided, either as part of this
+                ** argv[] element or as the next one
+                */
+                if (':' == internal->options[cop + 1])
+                {
+                    /* value is part of the current argv[] element */
+                    if (0 != *internal->xargv)
+                    {
+                        opt->value = internal->xargv;
+                    }
+                    /* value is the next argv[] element, if any */
+                    else if (internal->xargc + 1 < internal->argc)
+                    {
+                        opt->value = internal->argv[++(internal->xargc)];
+                    }
+                    /* missing value */
+                    else
+                    {
+                        return PL_OPT_BAD;
+                    }
+
+                    internal->xargv = &static_Nul;
+                    internal->minus = 0;
+                }
+                else 
+                    opt->value = NULL; 
+                return PL_OPT_OK;
+            }
+        }
+        internal->xargv += 1;  /* consume that option */
+        return PL_OPT_BAD;
+    }
+
+    /*
+    ** No '-', so it must be a standalone value. The option is nul.
+    */
+    opt->value = internal->argv[internal->xargc];
+    internal->xargv = &static_Nul;
+    opt->option = 0;
+    return PL_OPT_OK;
+}  /* PL_GetNextOpt */
+
+/* plgetopt.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plvrsion.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plvrsion.c
new file mode 100644
index 0000000..e9903cb
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/plvrsion.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prvrsion.h"
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+#include "_pl_bld.h"
+#if !defined(_BUILD_TIME)
+#ifdef HAVE_LONG_LONG
+#define _BUILD_TIME 0
+#else
+#define _BUILD_TIME {0, 0}
+#endif
+#endif
+#if !defined(_BUILD_STRING)
+#define _BUILD_STRING ""
+#endif
+#if !defined(_PRODUCTION)
+#define _PRODUCTION ""
+#endif
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * 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 */
+#if defined(DEBUG)
+    /* debug            */  PR_TRUE,            /* a debug build */
+#else
+    /* debug            */  PR_FALSE,           /* an optomized build */
+#endif
+    /* special          */  PR_FALSE,           /* they're all special, but ... */
+    /* filename         */  _PRODUCTION,        /* the produced library name */
+    /* description      */ "Portable runtime",  /* what we are */
+    /* security         */ "N/A",               /* not applicable here */
+    /* copywrite        */  "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved",
+    /* comment          */  "http://www.mozilla.org/MPL/",
+    /* specialString    */ ""
+};
+
+#ifdef XP_UNIX
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING
+        "  " _BUILD_STRING " $";
+static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
+        "  " _BUILD_STRING;
+
+#endif /* XP_UNIX */
+
+PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
+{
+#ifdef XP_UNIX
+    /*
+     * 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 &VERSION_DESC_NAME;
+}  /* versionEntryPointType */
+
+/* plvrsion.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcase.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcase.c
new file mode 100644
index 0000000..7e280aa
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcase.c
@@ -0,0 +1,202 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+static const unsigned char uc[] =
+{
+    '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+    '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+    '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+    '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+    ' ',    '!',    '"',    '#',    '$',    '%',    '&',    '\'',
+    '(',    ')',    '*',    '+',    ',',    '-',    '.',    '/',
+    '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',
+    '8',    '9',    ':',    ';',    '<',    '=',    '>',    '?',
+    '@',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
+    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
+    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
+    'X',    'Y',    'Z',    '[',    '\\',   ']',    '^',    '_',
+    '`',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
+    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
+    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
+    'X',    'Y',    'Z',    '{',    '|',    '}',    '~',    '\177',
+    0200,   0201,   0202,   0203,   0204,   0205,   0206,   0207,
+    0210,   0211,   0212,   0213,   0214,   0215,   0216,   0217,
+    0220,   0221,   0222,   0223,   0224,   0225,   0226,   0227,
+    0230,   0231,   0232,   0233,   0234,   0235,   0236,   0237,
+    0240,   0241,   0242,   0243,   0244,   0245,   0246,   0247,
+    0250,   0251,   0252,   0253,   0254,   0255,   0256,   0257,
+    0260,   0261,   0262,   0263,   0264,   0265,   0266,   0267,
+    0270,   0271,   0272,   0273,   0274,   0275,   0276,   0277,
+    0300,   0301,   0302,   0303,   0304,   0305,   0306,   0307,
+    0310,   0311,   0312,   0313,   0314,   0315,   0316,   0317,
+    0320,   0321,   0322,   0323,   0324,   0325,   0326,   0327,
+    0330,   0331,   0332,   0333,   0334,   0335,   0336,   0337,
+    0340,   0341,   0342,   0343,   0344,   0345,   0346,   0347,
+    0350,   0351,   0352,   0353,   0354,   0355,   0356,   0357,
+    0360,   0361,   0362,   0363,   0364,   0365,   0366,   0367,
+    0370,   0371,   0372,   0373,   0374,   0375,   0376,   0377
+};
+
+PR_IMPLEMENT(PRIntn)
+PL_strcasecmp(const char *a, const char *b)
+{
+    const unsigned char *ua = (const unsigned char *)a;
+    const unsigned char *ub = (const unsigned char *)b;
+
+    if( ((const char *)0 == a) || (const char *)0 == b ) 
+        return (PRIntn)(a-b);
+
+    while( (uc[*ua] == uc[*ub]) && ('\0' != *a) )
+    {
+        a++;
+        ua++;
+        ub++;
+    }
+
+    return (PRIntn)(uc[*ua] - uc[*ub]);
+}
+
+PR_IMPLEMENT(PRIntn)
+PL_strncasecmp(const char *a, const char *b, PRUint32 max)
+{
+    const unsigned char *ua = (const unsigned char *)a;
+    const unsigned char *ub = (const unsigned char *)b;
+
+    if( ((const char *)0 == a) || (const char *)0 == b ) 
+        return (PRIntn)(a-b);
+
+    while( max && (uc[*ua] == uc[*ub]) && ('\0' != *a) )
+    {
+        a++;
+        ua++;
+        ub++;
+        max--;
+    }
+
+    if( 0 == max ) return (PRIntn)0;
+
+    return (PRIntn)(uc[*ua] - uc[*ub]);
+}
+
+PR_IMPLEMENT(char *)
+PL_strcasestr(const char *big, const char *little)
+{
+    PRUint32 ll;
+
+    if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+    if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+    ll = strlen(little);
+
+    for( ; *big; big++ )
+        /* obvious improvement available here */
+            if( 0 == PL_strncasecmp(big, little, ll) )
+                return (char *)big;
+
+    return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strcaserstr(const char *big, const char *little)
+{
+    const char *p;
+    PRUint32 bl, ll;
+
+    if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+    if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+    bl = strlen(big);
+    ll = strlen(little);
+    if( bl < ll ) return (char *)0;
+    p = &big[ bl - ll ];
+
+    for( ; p >= big; p-- )
+        /* obvious improvement available here */
+            if( 0 == PL_strncasecmp(p, little, ll) )
+                return (char *)p;
+
+    return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncasestr(const char *big, const char *little, PRUint32 max)
+{
+    PRUint32 ll;
+
+    if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+    if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+    ll = strlen(little);
+    if( ll > max ) return (char *)0;
+    max -= ll;
+    max++;
+
+    for( ; max && *big; big++, max-- )
+        /* obvious improvement available here */
+            if( 0 == PL_strncasecmp(big, little, ll) )
+                return (char *)big;
+
+    return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncaserstr(const char *big, const char *little, PRUint32 max)
+{
+    const char *p;
+    PRUint32 ll;
+
+    if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+    if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+    ll = strlen(little);
+
+    for( p = big; max && *p; p++, max-- )
+        ;
+
+    p -= ll;
+    if( p < big ) return (char *)0;
+
+    for( ; p >= big; p-- )
+        /* obvious improvement available here */
+            if( 0 == PL_strncasecmp(p, little, ll) )
+                return (char *)p;
+
+    return (char *)0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcat.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcat.c
new file mode 100644
index 0000000..f71b097
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcat.c
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strcat(char *dest, const char *src)
+{
+    if( ((char *)0 == dest) || ((const char *)0 == src) )
+        return dest;
+
+    return strcat(dest, src);
+}
+
+PR_IMPLEMENT(char *)
+PL_strncat(char *dest, const char *src, PRUint32 max)
+{
+    char *rv;
+
+    if( ((char *)0 == dest) || ((const char *)0 == src) || (0 == max) )
+        return dest;
+
+    for( rv = dest; *dest; dest++ )
+        ;
+
+    (void)PL_strncpy(dest, src, max);
+    return rv;
+}
+
+PR_IMPLEMENT(char *)
+PL_strcatn(char *dest, PRUint32 max, const char *src)
+{
+    char *rv;
+    PRUint32 dl;
+
+    if( ((char *)0 == dest) || ((const char *)0 == src) )
+        return dest;
+
+    for( rv = dest, dl = 0; *dest; dest++, dl++ )
+        ;
+
+    if( max <= dl ) return rv;
+    (void)PL_strncpyz(dest, src, max-dl);
+
+    return rv;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strchr.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strchr.c
new file mode 100644
index 0000000..35ccedc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strchr.c
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strchr(const char *s, char c)
+{
+    if( (const char *)0 == s ) return (char *)0;
+
+    return strchr(s, c);
+}
+
+PR_IMPLEMENT(char *)
+PL_strrchr(const char *s, char c)
+{
+    if( (const char *)0 == s ) return (char *)0;
+
+    return strrchr(s, c);
+}
+
+PR_IMPLEMENT(char *)
+PL_strnchr(const char *s, char c, PRUint32 n)
+{
+    if( (const char *)0 == s ) return (char *)0;
+
+    for( ; n && *s; s++, n-- )
+        if( *s == c )
+            return (char *)s;
+
+    if( ((char)0 == c) && (n > 0) && ((char)0 == *s) ) return (char *)s;
+
+    return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnrchr(const char *s, char c, PRUint32 n)
+{
+    const char *p;
+
+    if( (const char *)0 == s ) return (char *)0;
+
+    for( p = s; n && *p; p++, n-- )
+        ;
+
+    if( ((char)0 == c) && (n > 0) && ((char)0 == *p) ) return (char *)p;
+
+    for( p--; p >= s; p-- )
+        if( *p == c )
+            return (char *)p;
+
+    return (char *)0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcmp.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcmp.c
new file mode 100644
index 0000000..095e178
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcmp.c
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(PRIntn)
+PL_strcmp(const char *a, const char *b)
+{
+    if( ((const char *)0 == a) || (const char *)0 == b ) 
+        return (PRIntn)(a-b);
+
+    return (PRIntn)strcmp(a, b);
+}
+
+PR_IMPLEMENT(PRIntn)
+PL_strncmp(const char *a, const char *b, PRUint32 max)
+{
+    if( ((const char *)0 == a) || (const char *)0 == b ) 
+        return (PRIntn)(a-b);
+
+    return (PRIntn)strncmp(a, b, (size_t)max);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcpy.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcpy.c
new file mode 100644
index 0000000..b576b67
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strcpy.c
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strcpy(char *dest, const char *src)
+{
+    if( ((char *)0 == dest) || ((const char *)0 == src) ) return (char *)0;
+
+    return strcpy(dest, src);
+}
+
+PR_IMPLEMENT(char *)
+PL_strncpy(char *dest, const char *src, PRUint32 max)
+{
+    char *rv;
+    
+    if( (char *)0 == dest ) return (char *)0;
+    if( (const char *)0 == src ) return (char *)0;
+
+    for( rv = dest; max && ((*dest = *src) != 0); dest++, src++, max-- )
+        ;
+
+#ifdef JLRU
+    /* XXX I (wtc) think the -- and ++ operators should be postfix. */
+    while( --max )
+        *++dest = '\0';
+#endif /* JLRU */
+
+    return rv;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncpyz(char *dest, const char *src, PRUint32 max)
+{
+    char *rv;
+    
+    if( (char *)0 == dest ) return (char *)0;
+    if( (const char *)0 == src ) return (char *)0;
+    if( 0 == max ) return (char *)0;
+
+    for( rv = dest, max--; max && ((*dest = *src) != 0); dest++, src++, max-- )
+        ;
+
+    *dest = '\0';
+
+    return rv;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strdup.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strdup.c
new file mode 100644
index 0000000..27a553c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strdup.c
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include "prmem.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strdup(const char *s)
+{
+    char *rv;
+    size_t n;
+
+    if( (const char *)0 == s )
+        s = "";
+
+    n = strlen(s) + 1;
+
+    rv = (char *)malloc(n);
+    if( (char *)0 == rv ) return rv;
+
+    (void)memcpy(rv, s, n);
+
+    return rv;
+}
+
+PR_IMPLEMENT(void)
+PL_strfree(char *s)
+{
+    free(s);
+}
+
+PR_IMPLEMENT(char *)
+PL_strndup(const char *s, PRUint32 max)
+{
+    char *rv;
+    size_t l;
+
+    if( (const char *)0 == s )
+        s = "";
+
+    l = PL_strnlen(s, max);
+
+    rv = (char *)malloc(l+1);
+    if( (char *)0 == rv ) return rv;
+
+    (void)memcpy(rv, s, l);
+    rv[l] = '\0';
+
+    return rv;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strlen.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strlen.c
new file mode 100644
index 0000000..e03f7d2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strlen.c
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include "prtypes.h"
+#include "prlog.h"
+#include <string.h>
+
+PR_IMPLEMENT(PRUint32)
+PL_strlen(const char *str)
+{
+    size_t l;
+
+    if( (const char *)0 == str ) return 0;
+
+    l = strlen(str);
+
+    /* error checking in case we have a 64-bit platform -- make sure
+     * we don't have ultra long strings that overflow an int32
+     */ 
+    if( sizeof(PRUint32) < sizeof(size_t) )
+    {
+        if( l > PR_INT32_MAX )
+            PR_Assert("l <= PR_INT32_MAX", __FILE__, __LINE__);
+    }
+
+    return (PRUint32)l;
+}
+
+PR_IMPLEMENT(PRUint32)
+PL_strnlen(const char *str, PRUint32 max)
+{
+    register const char *s;
+
+    if( (const char *)0 == str ) return 0;
+    for( s = str; max && *s; s++, max-- )
+        ;
+
+    return (PRUint32)(s - str);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strpbrk.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strpbrk.c
new file mode 100644
index 0000000..afcb4f5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strpbrk.c
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strpbrk(const char *s, const char *list)
+{
+    if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0;
+
+    return strpbrk(s, list);
+}
+
+PR_IMPLEMENT(char *)
+PL_strprbrk(const char *s, const char *list)
+{
+    const char *p;
+    const char *r;
+
+    if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0;
+
+    for( r = s; *r; r++ )
+        ;
+
+    for( r--; r >= s; r-- )
+        for( p = list; *p; p++ )
+            if( *r == *p )
+                return (char *)r;
+
+    return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnpbrk(const char *s, const char *list, PRUint32 max)
+{
+    const char *p;
+
+    if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0;
+
+    for( ; max && *s; s++, max-- )
+        for( p = list; *p; p++ )
+            if( *s == *p )
+                return (char *)s;
+
+    return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnprbrk(const char *s, const char *list, PRUint32 max)
+{
+    const char *p;
+    const char *r;
+
+    if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0;
+
+    for( r = s; max && *r; r++, max-- )
+        ;
+
+    for( r--; r >= s; r-- )
+        for( p = list; *p; p++ )
+            if( *r == *p )
+                return (char *)r;
+
+    return (char *)0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strstr.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strstr.c
new file mode 100644
index 0000000..6bc03d3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strstr.c
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strstr(const char *big, const char *little)
+{
+    if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+    if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+    return strstr(big, little);
+}
+
+PR_IMPLEMENT(char *)
+PL_strrstr(const char *big, const char *little)
+{
+    const char *p;
+    size_t ll;
+    size_t bl;
+
+    if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+    if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+    ll = strlen(little);
+    bl = strlen(big);
+    if( bl < ll ) return (char *)0;
+    p = &big[ bl - ll ];
+
+    for( ; p >= big; p-- )
+        if( *little == *p )
+            if( 0 == strncmp(p, little, ll) )
+                return (char *)p;
+
+    return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnstr(const char *big, const char *little, PRUint32 max)
+{
+    size_t ll;
+
+    if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+    if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+    ll = strlen(little);
+    if( ll > (size_t)max ) return (char *)0;
+    max -= (PRUint32)ll;
+    max++;
+
+    for( ; max && *big; big++, max-- )
+        if( *little == *big )
+            if( 0 == strncmp(big, little, ll) )
+                return (char *)big;
+
+    return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnrstr(const char *big, const char *little, PRUint32 max)
+{
+    const char *p;
+    size_t ll;
+
+    if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+    if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+    ll = strlen(little);
+
+    for( p = big; max && *p; p++, max-- )
+        ;
+
+    p -= ll;
+    if( p < big ) return (char *)0;
+
+    for( ; p >= big; p-- )
+        if( *little == *p )
+            if( 0 == strncmp(p, little, ll) )
+                return (char *)p;
+
+    return (char *)0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strtok.c b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strtok.c
new file mode 100644
index 0000000..400e9a4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/libc/src/strtok.c
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Roland Mainz <roland mainz@informatik.med.uni-giessen.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+
+PR_IMPLEMENT(char *)
+PL_strtok_r(char *s1, const char *s2, char **lasts)
+{
+    const char *sepp;
+    int         c, sc;
+    char       *tok;
+
+    if( s1 == NULL )
+    {
+        if( *lasts == NULL )
+            return NULL;
+
+        s1 = *lasts;
+    }
+  
+    for( ; (c = *s1) != 0; s1++ )
+    {
+        for( sepp = s2 ; (sc = *sepp) != 0 ; sepp++ )
+        {
+            if( c == sc )
+                break;
+        }
+        if( sc == 0 )
+            break; 
+    }
+
+    if( c == 0 )
+    {
+        *lasts = NULL;
+        return NULL;
+    }
+  
+    tok = s1++;
+
+    for( ; (c = *s1) != 0; s1++ )
+    {
+        for( sepp = s2; (sc = *sepp) != 0; sepp++ )
+        {
+            if( c == sc )
+            {
+                *s1++ = '\0';
+                *lasts = s1;
+                return tok;
+            }
+        }
+    }
+    *lasts = NULL;
+    return tok;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/Makefile.in
new file mode 100644
index 0000000..d7299b2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/Makefile.in
@@ -0,0 +1,52 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+MOD_DEPTH	= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = include src tests
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/Makefile.in
new file mode 100644
index 0000000..86e152a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/Makefile.in
@@ -0,0 +1,57 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/config.mk
+
+EXPORT_HEADERS = prgc.h
+HEADERS = $(EXPORT_HEADERS) gcint.h
+
+RELEASE_HEADERS = $(EXPORT_HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(EXPORT_HEADERS)
+	$(INSTALL) -m 444 $(EXPORT_HEADERS) $(dist_includedir)
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/gcint.h b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/gcint.h
new file mode 100644
index 0000000..10048f0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/gcint.h
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef gcint_h___
+#define gcint_h___
+
+#include "prmon.h"
+#include "prgc.h"
+
+extern PRLogModuleInfo *_pr_msgc_lm;
+extern GCInfo _pr_gcData;
+
+#if defined(_WIN32) && !defined(DEBUG)
+#undef INLINE_LOCK
+#endif
+
+#ifdef INLINE_LOCK
+#define LOCK_GC()       EnterCriticalSection(&_pr_gcData.lock->mutexHandle)
+#define UNLOCK_GC()     LeaveCriticalSection(&_pr_gcData.lock->mutexHandle)
+#else
+#define LOCK_GC()       PR_EnterMonitor(_pr_gcData.lock)
+#define UNLOCK_GC()     PR_ExitMonitor (_pr_gcData.lock)
+#define GC_IS_LOCKED()  (PR_GetMonitorEntryCount(_pr_gcData.lock)!=0)
+#endif
+
+#ifdef DEBUG
+#define _GCTRACE(x, y) if (_pr_gcData.flags & x) GCTrace y
+#else
+#define _GCTRACE(x, y)
+#endif
+
+extern GCBeginGCHook *_pr_beginGCHook;
+extern void *_pr_beginGCHookArg;
+extern GCBeginGCHook *_pr_endGCHook;
+extern void *_pr_endGCHookArg;
+
+extern GCBeginFinalizeHook *_pr_beginFinalizeHook;
+extern void *_pr_beginFinalizeHookArg;
+extern GCBeginFinalizeHook *_pr_endFinalizeHook;
+extern void *_pr_endFinalizeHookArg;
+
+extern int _pr_do_a_dump;
+extern FILE *_pr_dump_file;
+
+extern PRLogModuleInfo *_pr_gc_lm;
+
+/*
+** Root finders. Root finders are used by the GC to find pointers into
+** the GC heap that are not contained in the GC heap.
+*/
+typedef struct RootFinderStr RootFinder;
+
+struct RootFinderStr {
+    RootFinder *next;
+    GCRootFinder *func;
+    char *name;
+    void *arg;
+};
+extern RootFinder *_pr_rootFinders;
+
+typedef struct CollectorTypeStr {
+    GCType gctype;
+    PRUint32 flags;
+} CollectorType;
+
+#define GC_MAX_TYPES	256
+extern CollectorType *_pr_collectorTypes;
+
+#define _GC_TYPE_BUSY   0x1
+#define _GC_TYPE_FINAL  0x2
+#define _GC_TYPE_WEAK   0x4
+
+/* Slot in _pr_gcTypes used for free memory */
+#define FREE_MEMORY_TYPEIX 255
+
+extern void _PR_InitGC(PRWord flags);
+extern void _MD_InitGC(void);
+extern void PR_CALLBACK _PR_ScanFinalQueue(void *notused);
+
+/*
+** Grow the GC Heap.
+*/
+extern void *_MD_GrowGCHeap(PRUint32 *sizep);
+
+/*
+** Extend the GC Heap.
+*/
+extern PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize);
+
+/*
+** Free a GC segment.
+*/
+extern void _MD_FreeGCSegment(void *base, PRInt32 len);
+
+#endif /* gcint_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/prgc.h b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/prgc.h
new file mode 100644
index 0000000..859f7b1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/include/prgc.h
@@ -0,0 +1,419 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prgc_h___
+#define prgc_h___
+
+/*
+** API to NSPR gc memory system.
+*/
+#include "prtypes.h"
+#include "prmon.h"
+#include "prthread.h"
+#include <stdio.h>
+
+#if defined(WIN16)
+#define GCPTR __far
+#else
+#define GCPTR
+#endif
+
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Initialize the garbage collector.
+**     "flags" is the trace flags (see below).
+**     "initialHeapSize" is the initial size of the heap and may be zero
+**        if the default is desired.
+**    "segmentSize" is the size of each segment of memory added to the
+**       heap when the heap is grown.
+*/
+PR_EXTERN(void) PR_InitGC(
+    PRWord flags, PRInt32 initialHeapSize, PRInt32 segmentSize, PRThreadScope scope);
+
+/*
+** Shuts down gc and frees up all memory associated with it. 
+*/
+PR_EXTERN(void) PR_ShutdownGC(PRBool finalizeOnExit);
+
+/*
+** This walk function will be called for every gc object in the
+** heap as it is walked. If it returns non-zero, the walk is terminated.
+*/
+typedef PRInt32 (*PRWalkFun)(void GCPTR* obj, void* data);
+
+/*
+** GC Type record. This defines all of the GC operations used on a
+** particular object type. These structures are passed to
+** PR_RegisterType.
+*/
+typedef struct GCType {
+    /*
+    ** Scan an object that is in the GC heap and call GCInfo.livePointer
+    ** on all of the pointers in it. If this slot is null then the object
+    ** won't be scanned (i.e. it has no embedded pointers).
+    */
+    void (PR_CALLBACK *scan)(void GCPTR *obj);
+
+    /*
+    ** Finalize an object that has no references. This is called by the
+    ** GC after it has determined where the object debris is but before
+    ** it has moved the debris to the logical "free list". The object is
+    ** marked alive for this call and removed from the list of objects
+    ** that need finalization (finalization only happens once for an
+    ** object). If this slot is null then the object doesn't need
+    ** finalization.
+    */
+    void (PR_CALLBACK *finalize)(void GCPTR *obj);
+
+    /*
+    ** Dump out an object during a PR_DumpGCHeap(). This is used as a
+    ** debugging tool.
+    */
+    void (PR_CALLBACK *dump)(FILE *out, void GCPTR *obj, PRBool detailed, PRIntn indentLevel);
+
+    /*
+    ** Add object to summary table.
+    */
+    void (PR_CALLBACK *summarize)(void GCPTR *obj, PRUint32 bytes);
+
+    /*
+    ** Free hook called by GC when the object is being freed.
+    */
+    void (PR_CALLBACK *free)(void *obj);
+
+    /* Weak pointer support: If the object has a weak pointer (Note:
+       at most one), this function is used to get the weak link's
+       offset from the start of the body of a gc object */
+    PRUint32 (PR_CALLBACK *getWeakLinkOffset)(void *obj);
+
+    /* Descriptive character for dumping this GCType */
+    char kindChar;
+
+    /*
+    ** Walker routine. This routine should apply fun(obj->ptr, data)
+    ** for every gc pointer within the object.
+    */
+    PRInt32 (PR_CALLBACK *walk)(void GCPTR *obj, PRWalkFun fun, void* data);
+} GCType;
+
+/*
+** This data structure must be added as the hash table passed to 
+** the summarize method of GCType.
+*/ 
+typedef struct PRSummaryEntry {
+    void* clazz;
+    PRInt32 instancesCount;
+    PRInt32 totalSize;
+} PRSummaryEntry;
+
+/*
+** This function pointer must be registered by users of nspr
+** to produce the finally summary after all object in the
+** heap have been visited.
+*/
+typedef void (PR_CALLBACK *PRSummaryPrinter)(FILE *out, void* closure);
+
+PR_EXTERN(void) PR_CALLBACK PR_RegisterSummaryPrinter(PRSummaryPrinter fun, void* closure);
+
+typedef void PR_CALLBACK GCRootFinder(void *arg);
+typedef void PR_CALLBACK GCBeginFinalizeHook(void *arg);
+typedef void PR_CALLBACK GCEndFinalizeHook(void *arg);
+typedef void PR_CALLBACK GCBeginGCHook(void *arg);
+typedef void PR_CALLBACK GCEndGCHook(void *arg);
+
+typedef enum { PR_GCBEGIN, PR_GCEND } GCLockHookArg;
+
+typedef void PR_CALLBACK GCLockHookFunc(GCLockHookArg arg1, void *arg2);
+
+typedef struct GCLockHook GCLockHook;
+
+struct GCLockHook {
+  GCLockHookFunc* func;
+  void* arg;
+  GCLockHook* next;
+  GCLockHook* prev;
+};
+
+
+/*
+** Hooks which are called at the beginning and end of the GC process.
+** The begin hooks are called before the root finding step. The hooks are
+** called with threading disabled, so it is now allowed to re-enter the
+** kernel. The end hooks are called after the gc has finished but before
+** the finalizer has run.
+*/
+PR_EXTERN(void) PR_CALLBACK PR_SetBeginGCHook(GCBeginGCHook *hook, void *arg);
+PR_EXTERN(void) PR_CALLBACK PR_GetBeginGCHook(GCBeginGCHook **hook, void **arg);
+PR_EXTERN(void) PR_CALLBACK PR_SetEndGCHook(GCBeginGCHook *hook, void *arg);
+PR_EXTERN(void) PR_CALLBACK PR_GetEndGCHook(GCEndGCHook **hook, void **arg);
+
+/*
+** Called before SuspendAll is called by dogc, so that GC thread can hold
+** all the locks before hand to avoid any deadlocks
+*/
+
+/*
+PR_EXTERN(void) PR_SetGCLockHook(GCLockHook *hook, void *arg);
+PR_EXTERN(void) PR_GetGCLockHook(GCLockHook **hook, void **arg);
+*/
+
+PR_EXTERN(int) PR_RegisterGCLockHook(GCLockHookFunc *hook, void *arg);
+
+/*
+** Hooks which are called at the beginning and end of the GC finalization
+** process. After the GC has identified all of the dead objects in the
+** heap, it looks for objects that need finalization. Before it calls the
+** first finalization proc (see the GCType structure above) it calls the
+** begin hook. When it has finalized the last object it calls the end
+** hook.
+*/
+PR_EXTERN(void) PR_SetBeginFinalizeHook(GCBeginFinalizeHook *hook, void *arg);
+PR_EXTERN(void) PR_GetBeginFinalizeHook(GCBeginFinalizeHook **hook, void **arg);
+PR_EXTERN(void) PR_SetEndFinalizeHook(GCBeginFinalizeHook *hook, void *arg);
+PR_EXTERN(void) PR_GetEndFinalizeHook(GCEndFinalizeHook **hook, void **arg);
+
+/*
+** Register a GC type. Return's the index into the GC internal type
+** table. The returned value is passed to PR_AllocMemory. After the call,
+** the "type" memory belongs to the GC (the caller must not free it or
+** change it).
+*/
+PR_EXTERN(PRInt32) PR_RegisterType(GCType *type);
+
+/*
+** Register a root finder with the collector. The collector will call
+** these functions to identify all of the roots before collection
+** proceeds. "arg" is passed to the function when it is called.
+*/
+PR_EXTERN(PRStatus) PR_RegisterRootFinder(GCRootFinder func, char *name, void *arg);
+
+/*
+** Allocate some GC'able memory. The object must be at least bytes in
+** size. The type index function for the object is specified. "flags"
+** specifies some control flags. If PR_ALLOC_CLEAN is set then the memory
+** is zero'd before being returned. If PR_ALLOC_DOUBLE is set then the
+** allocated memory is double aligned.
+**
+** Any memory cell that you store a pointer to something allocated by
+** this call must be findable by the GC. Use the PR_RegisterRootFinder to
+** register new places where the GC will look for pointers into the heap.
+** The GC already knows how to scan any NSPR threads or monitors.
+*/
+PR_EXTERN(PRWord GCPTR *)PR_AllocMemory(
+    PRWord bytes, PRInt32 typeIndex, PRWord flags);
+PR_EXTERN(PRWord GCPTR *)PR_AllocSimpleMemory(
+    PRWord bytes, PRInt32 typeIndex);
+
+/*
+** This function can be used to cause PR_AllocMemory to always return
+** NULL. This may be useful in low memory situations when we're trying to
+** shutdown applets.
+*/
+PR_EXTERN(void) PR_EnableAllocation(PRBool yesOrNo);
+
+/* flags bits */
+#define PR_ALLOC_CLEAN 0x1
+#define PR_ALLOC_DOUBLE 0x2
+#define PR_ALLOC_ZERO_HANDLE 0x4              /* XXX yes, it's a hack */
+
+/*
+** Force a garbage collection right now. Return when it completes.
+*/
+PR_EXTERN(void) PR_GC(void);
+
+/*
+** Force a finalization right now. Return when finalization has
+** completed. Finalization completes when there are no more objects
+** pending finalization. This does not mean there are no objects in the
+** gc heap that will need finalization should a collection be done after
+** this call.
+*/
+PR_EXTERN(void) PR_ForceFinalize(void);
+
+/*
+** Dump the GC heap out to the given file. This will stop the system dead
+** in its tracks while it is occuring.
+*/
+PR_EXTERN(void) PR_DumpGCHeap(FILE *out, PRBool detailed);
+
+/*
+** Wrapper for PR_DumpGCHeap
+*/
+PR_EXTERN(void) PR_DumpMemory(PRBool detailed);
+
+/*
+** Dump summary of objects allocated.
+*/
+PR_EXTERN(void) PR_DumpMemorySummary(void);
+
+/*
+** Dump the application heaps.
+*/
+PR_EXTERN(void) PR_DumpApplicationHeaps(void);
+
+/*
+** Helper function used by dump routines to do the indentation in a
+** consistent fashion.
+*/
+PR_EXTERN(void) PR_DumpIndent(FILE *out, PRIntn indent);
+
+/*
+** The GCInfo structure contains all of the GC state...
+**
+** busyMemory:
+**    The amount of GC heap memory that is busy at this instant. Busy
+**    doesn't mean alive, it just means that it has been
+**    allocated. Immediately after a collection busy means how much is
+**    alive.
+**
+** freeMemory:
+**    The amount of GC heap memory that is as yet unallocated.
+**
+** allocMemory:
+**    The sum of free and busy memory in the GC heap.
+**
+** maxMemory:
+**    The maximum size that the GC heap is allowed to grow.
+**
+** lowSeg:
+**    The lowest segment currently used in the GC heap.
+**
+** highSeg:
+**    The highest segment currently used in the GC heap.  
+**    The lowSeg and highSeg members are used for a "quick test" of whether 
+**    a pointer falls within the GC heap. [ see GC_IN_HEAP(...) ]
+**
+** lock:
+**    Monitor used for synchronization within the GC.
+**
+** finalizer:
+**    Thread in which the GC finalizer is running.
+**
+** liveBlock:
+**    Object scanning functions call through this function pointer to
+**    register a potential block of pointers with the collector. (This is
+**    currently not at all different than processRoot.)
+**
+** livePointer:
+**    Object scanning functions call through this function pointer to
+**    register a single pointer with the collector.
+**
+** processRootBlock:
+**    When a root finder identifies a root it should call through this
+**    function pointer so that the GC can process the root. The call takes
+**    a base address and count which the gc will examine for valid heap
+**    pointers.
+**
+** processRootPointer:
+**    When a root finder identifies a root it should call through this
+**    function pointer so that the GC can process the root. The call takes
+**    a single pointer value.
+*/
+typedef struct GCInfoStr {
+    PRWord  flags;         /* trace flags (see below)               */
+    PRWord  busyMemory;    /* memory in use right now               */
+    PRWord  freeMemory;    /* memory free right now                 */
+    PRWord  allocMemory;   /* sum of busy & free memory             */
+    PRWord  maxMemory;     /* max memory we are allowed to allocate */
+    PRWord *lowSeg;        /* lowest segment in the GC heap         */
+    PRWord *highSeg;       /* highest segment in the GC heap         */
+
+    PRMonitor *lock;
+    PRThread  *finalizer;
+
+    void (PR_CALLBACK *liveBlock)(void **base, PRInt32 count);
+    void (PR_CALLBACK *livePointer)(void *ptr);
+    void (PR_CALLBACK *processRootBlock)(void **base, PRInt32 count);
+    void (PR_CALLBACK *processRootPointer)(void *ptr);
+    FILE* dumpOutput;
+#ifdef GCTIMINGHOOK
+    void (*gcTimingHook)(int32 gcTime);
+#endif
+} GCInfo;
+
+PR_EXTERN(GCInfo *) PR_GetGCInfo(void);
+PR_EXTERN(PRBool) PR_GC_In_Heap(void GCPTR *object);
+
+/*
+** Simple bounds check to see if a pointer is anywhere near the GC heap.
+** Used to avoid calls to PR_ProcessRoot and GCInfo.livePointer by object
+** scanning code.
+*/
+#if !defined(XP_PC) || defined(_WIN32)
+#define GC_IN_HEAP(_info, _p) (((PRWord*)(_p) >= (_info)->lowSeg) && \
+                               ((PRWord*)(_p) <  (_info)->highSeg))
+#else
+/*
+** The simple bounds check, above, doesn't work in Win16, because we don't
+** maintain: lowSeg == MIN(all segments) and highSeg == MAX(all segments).
+** So we have to do a little better.
+*/
+#define GC_IN_HEAP(_info, _p) PR_GC_In_Heap(_p)
+#endif
+
+PR_EXTERN(PRWord) PR_GetObjectHeader(void *ptr);
+
+PR_EXTERN(PRWord) PR_SetObjectHeader(void *ptr, PRWord newUserBits);
+
+/************************************************************************/
+
+/* Trace flags (passed to PR_InitGC or in environment GCLOG) */
+#define GC_TRACE    0x0001
+#define GC_ROOTS    0x0002
+#define GC_LIVE     0x0004
+#define GC_ALLOC    0x0008
+#define GC_MARK     0x0010
+#define GC_SWEEP    0x0020
+#define GC_DEBUG    0x0040
+#define GC_FINAL    0x0080
+
+#if defined(DEBUG_kipp) || defined(DEBUG_warren)
+#define GC_CHECK    0x0100
+#endif
+
+#ifdef DEBUG
+#define GCTRACE(x, y) if (PR_GetGCInfo()->flags & x) GCTrace y
+PR_EXTERN(void) GCTrace(char *fmt, ...);
+#else
+#define GCTRACE(x, y)
+#endif
+
+PR_END_EXTERN_C
+
+#endif /* prgc_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/Makefile.in
new file mode 100644
index 0000000..bcc5862
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/Makefile.in
@@ -0,0 +1,93 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+INCLUDES = -I$(dist_includedir) -I../include
+
+CSRCS = prgcapi.c prmsgc.c
+
+ifeq ($(OS_ARCH),WINNT)
+CSRCS += win32gc.c
+else
+ifeq ($(OS_ARCH),OS2)
+CSRCS += os2gc.c
+else
+CSRCS += unixgc.c
+endif
+endif
+
+NSPR_VERSION = $(MOD_MAJOR_VERSION)
+
+EXTRA_LIBS = $(LIBNSPR)
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+ifeq ($(OS_ARCH), WINNT)
+#RES=$(OBJDIR)/ds.res
+#RESNAME=$(MOD_DEPTH)/pr/src/nspr.rc
+#OS_LIBS = user32.lib
+endif # WINNT
+
+LIBRARY_NAME = msgc
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_LIBS = $(TARGETS)
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# The Client build wants the shared libraries in $(dist_bindir),
+# so we also install them there.
+#
+
+export:: $(TARGETS)
+	$(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifdef SHARED_LIBRARY
+	$(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir)
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/os2gc.c b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/os2gc.c
new file mode 100644
index 0000000..f99bb67
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/os2gc.c
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * GC related routines
+ *
+ */
+#include "prlog.h"
+
+#include <stdlib.h>
+
+/* Leave a bit of room for any malloc header bytes... */
+#define MAX_SEGMENT_SIZE    (65536L - 4096L)
+
+/************************************************************************/
+/*
+** Machine dependent GC Heap management routines:
+**    _MD_GrowGCHeap
+*/
+/************************************************************************/
+void _MD_InitGC() {}
+
+void *_MD_GrowGCHeap(PRUint32 *sizep)
+{
+    void *addr;
+
+    if ( *sizep > MAX_SEGMENT_SIZE )
+    {
+        *sizep = MAX_SEGMENT_SIZE;
+    }
+
+    addr = malloc((size_t)*sizep);
+    return addr;
+}
+
+
+PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize) {
+  /* Not sure about this.  Todd?  */
+  return PR_FALSE;
+}
+
+
+void _MD_FreeGCSegment(void *base, PRInt32 len)
+{
+   if (base)
+   {
+       free(base);
+   }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/prgcapi.c b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/prgcapi.c
new file mode 100644
index 0000000..324ac7b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/prgcapi.c
@@ -0,0 +1,330 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include "prenv.h"
+#include "prmem.h"
+#include "prmon.h"
+#include "prlog.h"
+#include "prthread.h"
+#include "private/pprthred.h"
+#include "gcint.h"
+
+/*
+** Generic GC implementation independent code for the NSPR GC
+*/
+
+RootFinder *_pr_rootFinders;
+
+CollectorType *_pr_collectorTypes;
+
+/* GC State information */
+GCInfo _pr_gcData;
+
+GCBeginGCHook *_pr_beginGCHook;
+void *_pr_beginGCHookArg;
+GCBeginGCHook *_pr_endGCHook;
+void *_pr_endGCHookArg;
+
+GCBeginFinalizeHook *_pr_beginFinalizeHook;
+void *_pr_beginFinalizeHookArg;
+GCBeginFinalizeHook *_pr_endFinalizeHook;
+void *_pr_endFinalizeHookArg;
+
+FILE *_pr_dump_file;
+int _pr_do_a_dump;
+GCLockHook *_pr_GCLockHook;
+
+extern PRLogModuleInfo *_pr_msgc_lm;
+
+/************************************************************************/
+
+static PRStatus PR_CALLBACK
+pr_ScanOneThread(PRThread* t, void** addr, PRUword count, void* closure)
+{
+    _pr_gcData.processRootBlock(addr, count);
+    return PR_SUCCESS;
+}
+
+/*
+** Scan all of the threads C stack's and registers, looking for "root"
+** pointers into the GC heap. These are the objects that the GC cannot
+** move and are considered "live" by the GC. Caller has stopped all of
+** the threads from running.
+*/
+static void PR_CALLBACK ScanThreads(void *arg)
+{
+    PR_ScanStackPointers(pr_ScanOneThread, arg);
+}
+
+/************************************************************************/
+
+PR_IMPLEMENT(GCInfo *) PR_GetGCInfo(void)
+{
+    return &_pr_gcData;
+}
+
+
+PR_IMPLEMENT(PRInt32) PR_RegisterType(GCType *t)
+{
+    CollectorType *ct, *ect;
+    int rv = -1;
+
+    LOCK_GC();
+    ct = &_pr_collectorTypes[0];
+    ect = &_pr_collectorTypes[FREE_MEMORY_TYPEIX];
+    for (; ct < ect; ct++) {
+	if (ct->flags == 0) {
+	    ct->gctype = *t;
+	    ct->flags = _GC_TYPE_BUSY;
+	    if (0 != ct->gctype.finalize) {
+		ct->flags |= _GC_TYPE_FINAL;
+	    }
+	    if (0 != ct->gctype.getWeakLinkOffset) {
+		ct->flags |= _GC_TYPE_WEAK;
+	    }
+	    rv = ct - &_pr_collectorTypes[0];
+	    break;
+	}
+    }
+    UNLOCK_GC();
+    return rv;
+}
+
+PR_IMPLEMENT(PRStatus) PR_RegisterRootFinder(
+    GCRootFinder f, char *name, void *arg)
+{
+    RootFinder *rf = PR_NEWZAP(RootFinder);
+    if (rf) {
+	    rf->func = f;
+	    rf->name = name;
+	    rf->arg = arg;
+
+	    LOCK_GC();
+	    rf->next = _pr_rootFinders;
+	    _pr_rootFinders = rf;
+	    UNLOCK_GC();
+	    return PR_SUCCESS;
+    }
+    return PR_FAILURE;
+}
+
+
+PR_IMPLEMENT(int) PR_RegisterGCLockHook(GCLockHookFunc* f, void *arg)
+{
+
+    GCLockHook *rf = 0;
+
+    rf = (GCLockHook*) calloc(1, sizeof(GCLockHook));
+    if (rf) {
+	rf->func = f;
+	rf->arg = arg;
+
+	LOCK_GC();
+        /* first dummy node */
+        if (! _pr_GCLockHook) {
+          _pr_GCLockHook = (GCLockHook*) calloc(1, sizeof(GCLockHook));
+          _pr_GCLockHook->next = _pr_GCLockHook;
+          _pr_GCLockHook->prev = _pr_GCLockHook;
+        }
+
+        rf->next = _pr_GCLockHook;
+        rf->prev = _pr_GCLockHook->prev;
+        _pr_GCLockHook->prev->next = rf;
+        _pr_GCLockHook->prev = rf;
+	UNLOCK_GC();
+	return 0;
+    }
+    return -1;
+}
+
+/*
+PR_IMPLEMENT(void) PR_SetGCLockHook(GCLockHook *hook, void *arg)
+{
+    LOCK_GC();
+    _pr_GCLockHook = hook;
+    _pr_GCLockHookArg2 = arg;
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetGCLockHook(GCLockHook **hook, void **arg)
+{
+    LOCK_GC();
+    *hook = _pr_GCLockHook;
+    *arg = _pr_GCLockHookArg2;
+    UNLOCK_GC();
+}
+*/
+
+  
+PR_IMPLEMENT(void) PR_SetBeginGCHook(GCBeginGCHook *hook, void *arg)
+{
+    LOCK_GC();
+    _pr_beginGCHook = hook;
+    _pr_beginGCHookArg = arg;
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetBeginGCHook(GCBeginGCHook **hook, void **arg)
+{
+    LOCK_GC();
+    *hook = _pr_beginGCHook;
+    *arg = _pr_beginGCHookArg;
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_SetEndGCHook(GCEndGCHook *hook, void *arg)
+{
+    LOCK_GC();
+    _pr_endGCHook = hook;
+    _pr_endGCHookArg = arg;
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetEndGCHook(GCEndGCHook **hook, void **arg)
+{
+    LOCK_GC();
+    *hook = _pr_endGCHook;
+    *arg = _pr_endGCHookArg;
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_SetBeginFinalizeHook(GCBeginFinalizeHook *hook, void *arg)
+{
+    LOCK_GC();
+    _pr_beginFinalizeHook = hook;
+    _pr_beginFinalizeHookArg = arg;
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetBeginFinalizeHook(GCBeginFinalizeHook **hook, 
+                                           void **arg)
+{
+    LOCK_GC();
+    *hook = _pr_beginFinalizeHook;
+    *arg = _pr_beginFinalizeHookArg;
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_SetEndFinalizeHook(GCEndFinalizeHook *hook, void *arg)
+{
+    LOCK_GC();
+    _pr_endFinalizeHook = hook;
+    _pr_endFinalizeHookArg = arg;
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetEndFinalizeHook(GCEndFinalizeHook **hook, void **arg)
+{
+    LOCK_GC();
+    *hook = _pr_endFinalizeHook;
+    *arg = _pr_endFinalizeHookArg;
+    UNLOCK_GC();
+}
+
+#ifdef DEBUG
+#include "prprf.h"
+
+PR_IMPLEMENT(void) GCTrace(char *fmt, ...)
+{	
+    va_list ap;
+    char buf[400];
+
+    va_start(ap, fmt);
+    PR_vsnprintf(buf, sizeof(buf), fmt, ap);
+    va_end(ap);
+    PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("%s", buf));
+}
+#endif
+
+void _PR_InitGC(PRWord flags)
+{
+    static char firstTime = 1;
+
+    if (!firstTime) return;
+    firstTime = 0;
+
+    _MD_InitGC();
+
+    if (flags == 0) {
+	char *ev = PR_GetEnv("GCLOG");
+	if (ev && ev[0]) {
+	    flags = atoi(ev);
+	}
+    }
+    _pr_gcData.flags = flags;
+
+    _pr_gcData.lock = PR_NewMonitor();
+
+    _pr_collectorTypes = (CollectorType*) PR_CALLOC(256 * sizeof(CollectorType));
+
+    PR_RegisterRootFinder(ScanThreads, "scan threads", 0);
+    PR_RegisterRootFinder(_PR_ScanFinalQueue, "scan final queue", 0);
+}
+
+extern void pr_FinalizeOnExit(void);
+
+#ifdef DEBUG
+#ifdef GC_STATS
+PR_PUBLIC_API(void) PR_PrintGCAllocStats(void);
+#endif 
+#endif 
+  
+PR_IMPLEMENT(void) 
+PR_ShutdownGC(PRBool finalizeOnExit)
+{
+    /* first finalize all the objects in the heap */
+    if (finalizeOnExit) {
+        pr_FinalizeOnExit();
+    }
+
+#ifdef DEBUG
+#ifdef GC_STATS
+    PR_PrintGCAllocStats();
+#endif /* GC_STATS */
+#endif /* DEBUG */
+
+    /* then the chance for any future allocations */
+
+    /* finally delete the gc heap */
+
+    /* write me */
+}
+
+/******************************************************************************/
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/prmsgc.c b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/prmsgc.c
new file mode 100644
index 0000000..2c1e853
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/prmsgc.c
@@ -0,0 +1,3320 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <string.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <time.h>
+
+#ifdef WIN32
+#include <windef.h>
+#include <winbase.h>
+#endif
+
+#include "prclist.h"
+#include "prbit.h"
+
+#include "prtypes.h"
+#include "prenv.h"
+#include "prgc.h"
+#include "prthread.h"
+#include "prlog.h"
+#include "prlong.h"
+#include "prinrval.h"
+#include "prprf.h"
+#include "gcint.h"
+
+#include "private/pprthred.h"
+
+typedef void (*PRFileDumper)(FILE *out, PRBool detailed);
+
+PR_EXTERN(void)
+PR_DumpToFile(char* filename, char* msg, PRFileDumper dump, PRBool detailed);
+
+/*
+** Mark&sweep garbage collector. Supports objects that require
+** finalization, objects that can have a single weak link, and special
+** objects that require care during sweeping.
+*/
+
+PRLogModuleInfo *_pr_msgc_lm;
+PRLogModuleInfo* GC;
+
+static PRInt32 _pr_pageShift;
+static PRInt32 _pr_pageSize;
+
+#ifdef DEBUG
+#define GCMETER
+#endif
+#ifdef DEBUG_jwz
+# undef GCMETER
+#endif /* 1 */
+
+#ifdef GCMETER
+#define METER(x) x
+#else
+#define METER(x)
+#endif
+
+/*
+** Make this constant bigger to reduce the amount of recursion during
+** garbage collection.
+*/
+#define MAX_SCAN_Q    100L
+
+#if defined(XP_PC) && !defined(WIN32)
+#define MAX_SEGS            400L
+#define MAX_SEGMENT_SIZE    (65536L - 4096L)
+#define SEGMENT_SIZE        (65536L - 4096L)
+#define MAX_ALLOC_SIZE      (65536L - 4096L)
+#else
+#define MAX_SEGS                    400L
+#define MAX_SEGMENT_SIZE            (2L * 256L * 1024L)
+#define SEGMENT_SIZE                (1L * 256L * 1024L)
+#define MAX_ALLOC_SIZE              (4L * 1024L * 1024L)
+#endif  
+
+/* 
+ * The highest value that can fit into a signed integer. This
+ * is used to prevent overflow of allocation size in alloc routines.
+ */
+ 
+#define MAX_INT ((1UL << (PR_BITS_PER_INT - 1)) - 1)
+
+/* 
+ * On 32-bit machines, only 22 bits are used in the cibx integer to
+ * store size since 8 bits of the integer are used to store type, and
+ * of the remainder, 2 are user defined. Max allocation size = 2^22 -1
+ */
+
+#define MAX_ALLOC ( (1L << (PR_BYTES_PER_WORD_LOG2 + WORDS_BITS )) -1)
+
+/* The minimum percentage of free heap space after a collection. If
+   the amount of free space doesn't meet this criteria then we will
+   attempt to grow the heap */
+#define MIN_FREE_THRESHOLD_AFTER_GC 20L
+
+static PRInt32 segmentSize = SEGMENT_SIZE;
+
+static PRInt32 collectorCleanupNeeded;
+
+#ifdef GCMETER
+PRUint32 _pr_gcMeter;
+
+#define _GC_METER_STATS         0x01L
+#define _GC_METER_GROWTH        0x02L
+#define _GC_METER_FREE_LIST     0x04L
+#endif
+
+/************************************************************************/
+
+#define LINEAR_BIN_EXPONENT 5
+#define NUM_LINEAR_BINS ((PRUint32)1 << LINEAR_BIN_EXPONENT)
+#define FIRST_LOG_BIN (NUM_LINEAR_BINS - LINEAR_BIN_EXPONENT)
+
+/* Each free list bin holds a chunk of memory sized from
+   2^n to (2^(n+1))-1 inclusive. */
+#define NUM_BINS        (FIRST_LOG_BIN + 32)
+
+/*
+ * Find the bin number for a given size (in bytes). This does not round up as
+ * values from 2^n to (2^(n+1))-1 share the same bin.
+ */
+#define InlineBinNumber(_bin,_bytes)  \
+{  \
+    PRUint32 _t, _n = (PRUint32) _bytes / 4;  \
+    if (_n < NUM_LINEAR_BINS) {  \
+        _bin = _n;  \
+    } else {  \
+        _bin = FIRST_LOG_BIN;  \
+        if ((_t = (_n >> 16)) != 0) { _bin += 16; _n = _t; }  \
+        if ((_t = (_n >> 8)) != 0)  { _bin += 8; _n = _t; }  \
+        if ((_t = (_n >> 4)) != 0)  { _bin += 4; _n = _t; }  \
+        if ((_t = (_n >> 2)) != 0) { _bin += 2; _n = _t; }  \
+        if ((_n >> 1) != 0) _bin++;  \
+    }  \
+}
+
+#define BIG_ALLOC       16384L
+
+#define MIN_FREE_CHUNK_BYTES    ((PRInt32)sizeof(GCFreeChunk))
+
+/* Note: fix code in PR_AllocMemory if you change the size of GCFreeChunk
+   so that it zeros the right number of words */
+typedef struct GCFreeChunk {
+    struct GCFreeChunk *next;
+    struct GCSeg *segment;
+    PRInt32 chunkSize;
+} GCFreeChunk;
+
+typedef struct GCSegInfo {
+    struct GCSegInfo *next;
+    char *base;
+    char *limit;
+    PRWord *hbits;
+    int fromMalloc;
+} GCSegInfo;
+    
+typedef struct GCSeg {
+    char *base;
+    char *limit;
+    PRWord *hbits;
+    GCSegInfo *info;
+} GCSeg;
+
+#ifdef GCMETER
+typedef struct GCMeter {
+    PRInt32 allocBytes;
+    PRInt32 wastedBytes;
+    PRInt32 numFreeChunks;
+    PRInt32 skippedFreeChunks;
+} GCMeter;
+static GCMeter meter;
+#endif
+
+/*
+** There is one of these for each segment of GC'able memory.
+*/
+static GCSeg segs[MAX_SEGS];
+static GCSegInfo *freeSegs;
+static GCSeg* lastInHeap;
+static int nsegs;
+
+static GCFreeChunk *bins[NUM_BINS];
+static PRInt32 minBin;
+static PRInt32 maxBin;
+
+/*
+** Scan Q used to avoid deep recursion when scanning live objects for
+** heap pointers
+*/
+typedef struct GCScanQStr {
+    PRWord *q[MAX_SCAN_Q];
+    int queued;
+} GCScanQ;
+
+static GCScanQ *pScanQ;
+
+#ifdef GCMETER
+PRInt32 _pr_maxScanDepth;
+PRInt32 _pr_scanDepth;
+#endif
+
+/*
+** Keeps track of the number of bytes allocated via the BigAlloc() 
+** allocator.  When the number of bytes allocated, exceeds the 
+** BIG_ALLOC_GC_SIZE, then a GC will occur before the next allocation
+** is done...
+*/
+#define BIG_ALLOC_GC_SIZE       (4*SEGMENT_SIZE)
+static PRWord bigAllocBytes = 0;
+
+/*
+** There is one GC header word in front of each GC allocated object.  We
+** use it to contain information about the object (what TYPEIX to use for
+** scanning it, how big it is, it's mark status, and if it's a root).
+*/
+#define TYPEIX_BITS    8L
+#define WORDS_BITS    20L
+#define MAX_CBS        (1L << GC_TYPEIX_BITS)
+#define MAX_WORDS    (1L << GC_WORDS_BITS)
+#define TYPEIX_SHIFT    24L
+#define MAX_TYPEIX    ((1L << TYPEIX_BITS) - 1L)
+#define TYPEIX_MASK    PR_BITMASK(TYPEIX_BITS)
+#define WORDS_SHIFT    2L
+#define WORDS_MASK    PR_BITMASK(WORDS_BITS)
+#define MARK_BIT    1L
+#define FINAL_BIT    2L
+
+/* Two bits per object header are reserved for the user of the memory
+   system to store information into. */
+#define GC_USER_BITS_SHIFT 22L
+#define GC_USER_BITS    0x00c00000L
+
+#define MAKE_HEADER(_cbix,_words)              \
+    ((PRWord) (((unsigned long)(_cbix) << TYPEIX_SHIFT) \
+         | ((unsigned long)(_words) << WORDS_SHIFT)))
+
+#define GET_TYPEIX(_h) \
+    (((PRUword)(_h) >> TYPEIX_SHIFT) & 0xff)
+
+#define MARK(_sp,_p) \
+    (((PRWord *)(_p))[0] |= MARK_BIT)
+#define IS_MARKED(_sp,_p) \
+    (((PRWord *)(_p))[0] & MARK_BIT)
+#define OBJ_BYTES(_h) \
+    (((PRInt32) (_h) & 0x003ffffcL) << (PR_BYTES_PER_WORD_LOG2-2L))
+
+#define GC_GET_USER_BITS(_h) (((_h) & GC_USER_BITS) >> GC_USER_BITS_SHIFT)
+
+/************************************************************************/
+
+/*
+** Mark the start of an object in a segment. Note that we mark the header
+** word (which we always have), not the data word (which we may not have
+** for empty objects).
+** XXX tune: put subtract of _sp->base into _sp->hbits pointer?
+*/
+#define SET_HBIT(_sp,_ph) \
+    SET_BIT((_sp)->hbits, (((PRWord*)(_ph)) - ((PRWord*) (_sp)->base)))
+
+#define CLEAR_HBIT(_sp,_ph) \
+    CLEAR_BIT((_sp)->hbits, (((PRWord*)(_ph)) - ((PRWord*) (_sp)->base)))
+
+#define IS_HBIT(_sp,_ph) \
+    TEST_BIT((_sp)->hbits, (((PRWord*)(_ph)) - ((PRWord*) (_sp)->base)))
+
+/*
+** Given a pointer into this segment, back it up until we are at the
+** start of the object the pointer points into. Each heap segment has a
+** bitmap that has one bit for each word of the objects it contains.  The
+** bit's are set for the firstword of an object, and clear for it's other
+** words.
+*/
+static PRWord *FindObject(GCSeg *sp, PRWord *p)
+{
+    PRWord *base;
+    
+    /* Align p to it's proper boundary before we start fiddling with it */
+    p = (PRWord*) ((PRWord)p & ~(PR_BYTES_PER_WORD-1L));
+
+    base = (PRWord *) sp->base;
+    do {
+    if (IS_HBIT(sp, p)) {
+        return (p);
+    }
+    p--;
+    } while ( p >= base );
+
+    /* Heap is corrupted! */
+    _GCTRACE(GC_TRACE, ("ERROR: The heap is corrupted!!! aborting now!"));
+    abort();
+    return NULL;
+}
+
+/************************************************************************/
+#if !defined(XP_PC) || defined(XP_OS2)
+#define OutputDebugString(msg)
+#endif 
+
+#define IN_SEGMENT(_sp, _p)             \
+    ((((char *)(_p)) >= (_sp)->base) &&    \
+     (((char *)(_p)) < (_sp)->limit))
+
+static GCSeg *InHeap(void *p)
+{
+    GCSeg *sp, *esp;
+
+    if (lastInHeap && IN_SEGMENT(lastInHeap, p)) {
+    return lastInHeap;
+    }
+
+    sp = segs;
+    esp = segs + nsegs;
+    for (; sp < esp; sp++) {
+    if (IN_SEGMENT(sp, p)) {
+        lastInHeap = sp;
+        return sp;
+    }
+    }
+    return 0;
+}
+
+/*
+** Grow the heap by allocating another segment. Fudge the requestedSize
+** value to try to pre-account for the HBITS.
+*/
+static GCSeg* DoGrowHeap(PRInt32 requestedSize, PRBool exactly)
+{
+    GCSeg *sp;
+    GCSegInfo *segInfo;
+    GCFreeChunk *cp;
+    char *base;
+    PRWord *hbits;
+    PRInt32 nhbytes, nhbits;
+    PRUint32 allocSize;
+
+    if (nsegs == MAX_SEGS) {
+    /* No room for more segments */
+    return 0;
+    }
+
+    segInfo = (GCSegInfo*) PR_MALLOC(sizeof(GCSegInfo));
+#ifdef DEBUG
+    {
+    char str[256];
+    sprintf(str, "[1] Allocated %ld bytes at %p\n",
+        (long) sizeof(GCSegInfo), segInfo);
+    OutputDebugString(str);
+    }
+#endif
+    if (!segInfo) {
+    return 0;
+    }
+
+    /* Get more memory from the OS */
+    if (exactly) {
+    allocSize = requestedSize;
+    base = (char *) PR_MALLOC(requestedSize);
+    } else {
+    allocSize = requestedSize;
+    allocSize = (allocSize + _pr_pageSize - 1L) >> _pr_pageShift;
+    allocSize <<= _pr_pageShift;
+    base = (char*)_MD_GrowGCHeap(&allocSize);
+    }
+    if (!base) {
+    PR_DELETE(segInfo);
+    return 0;
+    }
+
+    nhbits = (PRInt32)(
+        (allocSize + PR_BYTES_PER_WORD - 1L) >> PR_BYTES_PER_WORD_LOG2);
+    nhbytes = ((nhbits + PR_BITS_PER_WORD - 1L) >> PR_BITS_PER_WORD_LOG2)
+    * sizeof(PRWord);
+
+    /* Get bitmap memory from malloc heap */
+    hbits = (PRWord *) PR_CALLOC((PRUint32)nhbytes);
+    if (!hbits) {
+    /* Loser! */
+    PR_DELETE(segInfo);
+    if (exactly) {
+        PR_DELETE(base);
+    } else {
+      /* XXX do something about this */
+      /* _MD_FreeGCSegment(base, allocSize); */
+    }
+    return 0;
+    }
+
+    /*
+    ** Setup new segment.
+    */
+    sp = &segs[nsegs++];
+    segInfo->base = sp->base = base;
+    segInfo->limit = sp->limit = base + allocSize;
+    segInfo->hbits = sp->hbits = hbits;
+    sp->info = segInfo;
+    segInfo->fromMalloc = exactly;
+    memset(base, 0, allocSize);
+
+#ifdef GCMETER
+    if (_pr_gcMeter & _GC_METER_GROWTH) {
+        fprintf(stderr, "[GC: new segment base=%p size=%ld]\n",
+                sp->base, (long) allocSize);
+    }
+#endif    
+
+    _pr_gcData.allocMemory += allocSize;
+    _pr_gcData.freeMemory  += allocSize;
+
+    if (!exactly) {
+    PRInt32 bin;
+
+        /* Put free memory into a freelist bin */
+        cp = (GCFreeChunk *) base;
+        cp->segment = sp;
+        cp->chunkSize = allocSize;
+        InlineBinNumber(bin, allocSize)
+        cp->next = bins[bin];
+        bins[bin] = cp;
+    if (bin < minBin) minBin = bin;
+    if (bin > maxBin) maxBin = bin;
+    } else {
+        /*
+        ** When exactly allocating the entire segment is given over to a
+        ** single object to prevent fragmentation
+        */
+    }
+
+    if (!_pr_gcData.lowSeg) {
+    _pr_gcData.lowSeg  = (PRWord*) sp->base;
+    _pr_gcData.highSeg = (PRWord*) sp->limit;
+    } else {
+    if ((PRWord*)sp->base < _pr_gcData.lowSeg) {
+        _pr_gcData.lowSeg = (PRWord*) sp->base;
+    }
+    if ((PRWord*)sp->limit > _pr_gcData.highSeg) {
+        _pr_gcData.highSeg = (PRWord*) sp->limit;
+    }
+    }
+
+    /* 
+    ** Get rid of the GC pointer in case it shows up in some uninitialized
+    ** local stack variable later (while scanning the C stack looking for
+    ** roots).
+    */ 
+    memset(&base, 0, sizeof(base));  /* optimizers beware */
+
+    PR_LOG(_pr_msgc_lm, PR_LOG_WARNING, ("grow heap: total gc memory now %d",
+                      _pr_gcData.allocMemory));
+
+    return sp;
+}
+
+#ifdef USE_EXTEND_HEAP
+static PRBool ExtendHeap(PRInt32 requestedSize) {
+  GCSeg* sp;
+  PRUint32 allocSize;
+  PRInt32 oldSize, newSize;
+  PRInt32 newHBits, newHBytes;
+  PRInt32 oldHBits, oldHBytes;
+  PRWord* hbits;
+  GCFreeChunk* cp;
+  PRInt32 bin;
+
+  /* Can't extend nothing */
+  if (nsegs == 0) return PR_FALSE;
+
+  /* Round up requested size to the size of a page */
+  allocSize = (PRUint32) requestedSize;
+  allocSize = (allocSize + _pr_pageSize - 1L) >> _pr_pageShift;
+  allocSize <<= _pr_pageShift;
+
+  /* Malloc some memory for the new hbits array */
+  sp = segs;
+  oldSize = sp->limit - sp->base;
+  newSize = oldSize + allocSize;
+  newHBits = (newSize + PR_BYTES_PER_WORD - 1L) >> PR_BYTES_PER_WORD_LOG2;
+  newHBytes = ((newHBits + PR_BITS_PER_WORD - 1L) >> PR_BITS_PER_WORD_LOG2)
+    * sizeof(PRWord);
+  hbits = (PRWord*) PR_MALLOC(newHBytes);
+  if (0 == hbits) return PR_FALSE;
+
+  /* Attempt to extend the last segment by the desired amount */
+  if (_MD_ExtendGCHeap(sp->base, oldSize, newSize)) {
+    oldHBits = (oldSize + PR_BYTES_PER_WORD - 1L) >> PR_BYTES_PER_WORD_LOG2;
+    oldHBytes = ((oldHBits + PR_BITS_PER_WORD - 1L) >> PR_BITS_PER_WORD_LOG2)
+      * sizeof(PRWord);
+
+    /* Copy hbits from old memory into new memory */
+    memset(hbits, 0, newHBytes);
+    memcpy(hbits, sp->hbits, oldHBytes);
+    PR_DELETE(sp->hbits);
+    memset(sp->base + oldSize, 0, allocSize);
+
+    /* Adjust segment state */
+    sp->limit += allocSize;
+    sp->hbits = hbits;
+    sp->info->limit = sp->limit;
+    sp->info->hbits = hbits;
+
+    /* Put free memory into a freelist bin */
+    cp = (GCFreeChunk *) (sp->base + oldSize);
+    cp->segment = sp;
+    cp->chunkSize = allocSize;
+    InlineBinNumber(bin, allocSize)
+    cp->next = bins[bin];
+    bins[bin] = cp;
+    if (bin < minBin) minBin = bin;
+    if (bin > maxBin) maxBin = bin;
+
+    /* Prevent a pointer that points to the free memory from showing
+       up on the call stack later on */
+    memset(&cp, 0, sizeof(cp));
+
+    /* Update heap brackets and counters */
+    if ((PRWord*)sp->limit > _pr_gcData.highSeg) {
+      _pr_gcData.highSeg = (PRWord*) sp->limit;
+    }
+    _pr_gcData.allocMemory += allocSize;
+    _pr_gcData.freeMemory  += allocSize;
+
+    return PR_TRUE;
+  }
+  PR_DELETE(hbits);
+  return PR_FALSE;
+}
+#endif /* USE_EXTEND_HEAP */
+
+static GCSeg *GrowHeapExactly(PRInt32 requestedSize)
+{
+    GCSeg *sp = DoGrowHeap(requestedSize, PR_TRUE);
+    return sp;
+}
+
+static PRBool GrowHeap(PRInt32 requestedSize)
+{
+  void *p;
+#ifdef USE_EXTEND_HEAP
+  if (ExtendHeap(requestedSize)) {
+    return PR_TRUE;
+  }
+#endif
+  p = DoGrowHeap(requestedSize, PR_FALSE);
+  return (p != NULL ? PR_TRUE : PR_FALSE);
+}
+
+/*
+** Release a segment when it is entirely free.
+*/
+static void ShrinkGCHeap(GCSeg *sp)
+{
+#ifdef GCMETER
+    if (_pr_gcMeter & _GC_METER_GROWTH) {
+        fprintf(stderr, "[GC: free segment base=%p size=%ld]\n",
+                sp->base, (long) (sp->limit - sp->base));
+    }
+#endif    
+
+    /*
+     * Put segment onto free seginfo list (we can't call free right now
+     * because we have the GC lock and all of the other threads are
+     * suspended; if one of them has the malloc lock we would deadlock)
+     */
+    sp->info->next = freeSegs;
+    freeSegs = sp->info;
+    collectorCleanupNeeded = 1;
+    _pr_gcData.allocMemory -= sp->limit - sp->base;
+    if (sp == lastInHeap) lastInHeap = 0;
+
+    /* Squish out disappearing segment from segment table */
+    --nsegs;
+    if ((sp - segs) != nsegs) {
+        *sp = segs[nsegs];
+    } else {
+        sp->base = 0;
+        sp->limit = 0;
+        sp->hbits = 0;
+    sp->info = 0;
+    }
+
+    /* Recalculate the lowSeg and highSeg values */
+    _pr_gcData.lowSeg  = (PRWord*) segs[0].base;
+    _pr_gcData.highSeg = (PRWord*) segs[0].limit;
+    for (sp = segs; sp < &segs[nsegs]; sp++) {
+    if ((PRWord*)sp->base < _pr_gcData.lowSeg) {
+        _pr_gcData.lowSeg = (PRWord*) sp->base;
+    }
+    if ((PRWord*)sp->limit > _pr_gcData.highSeg) {
+        _pr_gcData.highSeg = (PRWord*) sp->limit;
+    }
+    }
+}
+
+static void FreeSegments(void)
+{
+    GCSegInfo *si;
+
+    while (0 != freeSegs) {
+    LOCK_GC();
+    si = freeSegs;
+    if (si) {
+        freeSegs = si->next;
+    }
+    UNLOCK_GC();
+
+    if (!si) {
+        break;
+    }
+    PR_DELETE(si->base);
+    PR_DELETE(si->hbits);
+    PR_DELETE(si);
+    }
+}
+
+/************************************************************************/
+
+void ScanScanQ(GCScanQ *iscan)
+{
+    PRWord *p;
+    PRWord **pp;
+    PRWord **epp;
+    GCScanQ nextQ, *scan, *next, *temp;
+    CollectorType *ct;
+
+    if (!iscan->queued) return;
+
+    _GCTRACE(GC_MARK, ("begin scanQ @ 0x%x (%d)", iscan, iscan->queued));
+    scan = iscan;
+    next = &nextQ;
+    while (scan->queued) {
+	_GCTRACE(GC_MARK, ("continue scanQ @ 0x%x (%d)", scan, scan->queued));
+    /*
+     * Set pointer to current scanQ so that _pr_gcData.livePointer
+     * can find it.
+     */
+    pScanQ = next;
+    next->queued = 0;
+
+    /* Now scan the scan Q */
+    pp = scan->q;
+    epp = &scan->q[scan->queued];
+    scan->queued = 0;
+    while (pp < epp) {
+        p = *pp++;
+        ct = &_pr_collectorTypes[GET_TYPEIX(p[0])];
+        PR_ASSERT(0 != ct->gctype.scan);
+        /* Scan object ... */
+        (*ct->gctype.scan)(p + 1);
+    }
+
+    /* Exchange pointers so that we scan next */
+    temp = scan;
+    scan = next;
+    next = temp;
+    }
+
+    pScanQ = iscan;
+    PR_ASSERT(nextQ.queued == 0);
+    PR_ASSERT(iscan->queued == 0);
+}
+
+/*
+** Called during root finding step to identify "root" pointers into the
+** GC heap. First validate if it is a real heap pointer and then mark the
+** object being pointed to and add it to the scan Q for eventual
+** scanning.
+*/
+static void PR_CALLBACK ProcessRootBlock(void **base, PRInt32 count)
+{
+    GCSeg *sp;
+    PRWord *p0, *p, h, tix, *low, *high, *segBase;
+    CollectorType *ct;
+#ifdef DEBUG
+    void **base0 = base;
+#endif
+
+    low = _pr_gcData.lowSeg;
+    high = _pr_gcData.highSeg;
+    while (--count >= 0) {
+        p0 = (PRWord*) *base++;
+        if (p0 < low) continue;                  /* below gc heap */
+        if (p0 >= high) continue;                /* above gc heap */
+        /* NOTE: inline expansion of InHeap */
+        /* Find segment */
+    sp = lastInHeap;
+        if (!sp || !IN_SEGMENT(sp,p0)) {
+            GCSeg *esp;
+            sp = segs;
+        esp = segs + nsegs;
+            for (; sp < esp; sp++) {
+                if (IN_SEGMENT(sp, p0)) {
+                    lastInHeap = sp;
+                    goto find_object;
+                }
+            }
+            continue;
+        }
+
+      find_object:
+        /* NOTE: Inline expansion of FindObject */
+        /* Align p to it's proper boundary before we start fiddling with it */
+        p = (PRWord*) ((PRWord)p0 & ~(PR_BYTES_PER_WORD-1L));
+        segBase = (PRWord *) sp->base;
+        do {
+            if (IS_HBIT(sp, p)) {
+                goto winner;
+            }
+            p--;
+        } while (p >= segBase);
+
+        /*
+        ** We have a pointer into the heap, but it has no header
+        ** bit. This means that somehow the very first object in the heap
+        ** doesn't have a header. This is impossible so when debugging
+        ** lets abort.
+        */
+#ifdef DEBUG
+        PR_Abort();
+#endif
+
+      winner:
+        h = p[0];
+        if ((h & MARK_BIT) == 0) {
+#ifdef DEBUG
+            _GCTRACE(GC_ROOTS,
+            ("root 0x%p (%d) base0=%p off=%d",
+             p, OBJ_BYTES(h), base0, (base-1) - base0));
+#endif
+
+            /* Mark the root we just found */
+            p[0] = h | MARK_BIT;
+
+            /*
+         * See if object we just found needs scanning. It must
+         * have a scan function to be placed on the scanQ.
+         */
+            tix = (PRWord)GET_TYPEIX(h);
+        ct = &_pr_collectorTypes[tix];
+        if (0 == ct->gctype.scan) {
+        continue;
+        }
+
+            /*
+            ** Put a pointer onto the scan Q. We use the scan Q to avoid
+            ** deep recursion on the C call stack. Objects are added to
+            ** the scan Q until the scan Q fills up. At that point we
+            ** make a call to ScanScanQ which proceeds to scan each of
+            ** the objects in the Q. This limits the recursion level by a
+            ** large amount though the stack frames get larger to hold
+            ** the GCScanQ's.
+            */
+            pScanQ->q[pScanQ->queued++] = p;
+            if (pScanQ->queued == MAX_SCAN_Q) {
+                METER(_pr_scanDepth++);
+                ScanScanQ(pScanQ);
+            }
+        }
+    }
+}
+
+static void PR_CALLBACK ProcessRootPointer(void *ptr)
+{
+  PRWord *p0, *p, h, tix, *segBase;
+  GCSeg* sp;
+  CollectorType *ct;
+
+  p0 = (PRWord*) ptr;
+
+  if (p0 < _pr_gcData.lowSeg) return;                  /* below gc heap */
+  if (p0 >= _pr_gcData.highSeg) return;                /* above gc heap */
+
+  /* NOTE: inline expansion of InHeap */
+  /* Find segment */
+  sp = lastInHeap;
+  if (!sp || !IN_SEGMENT(sp,p0)) {
+    GCSeg *esp;
+    sp = segs;
+    esp = segs + nsegs;
+    for (; sp < esp; sp++) {
+      if (IN_SEGMENT(sp, p0)) {
+    lastInHeap = sp;
+    goto find_object;
+      }
+    }
+    return;
+  }
+
+ find_object:
+  /* NOTE: Inline expansion of FindObject */
+  /* Align p to it's proper boundary before we start fiddling with it */
+    p = (PRWord*) ((PRWord)p0 & ~(BYTES_PER_WORD-1L));
+    segBase = (PRWord *) sp->base;
+    do {
+      if (IS_HBIT(sp, p)) {
+    goto winner;
+      }
+      p--;
+    } while (p >= segBase);
+
+    /*
+    ** We have a pointer into the heap, but it has no header
+    ** bit. This means that somehow the very first object in the heap
+    ** doesn't have a header. This is impossible so when debugging
+    ** lets abort.
+    */
+#ifdef DEBUG
+    PR_Abort();
+#endif
+
+ winner:
+  h = p[0];
+  if ((h & MARK_BIT) == 0) {
+#ifdef DEBUG
+    _GCTRACE(GC_ROOTS, ("root 0x%p (%d)", p, OBJ_BYTES(h)));
+#endif
+
+    /* Mark the root we just found */
+    p[0] = h | MARK_BIT;
+
+    /*
+     * See if object we just found needs scanning. It must
+     * have a scan function to be placed on the scanQ.
+     */
+    tix = (PRWord)GET_TYPEIX(h);
+    ct = &_pr_collectorTypes[tix];
+    if (0 == ct->gctype.scan) {
+      return;
+    }
+
+    /*
+    ** Put a pointer onto the scan Q. We use the scan Q to avoid
+    ** deep recursion on the C call stack. Objects are added to
+    ** the scan Q until the scan Q fills up. At that point we
+    ** make a call to ScanScanQ which proceeds to scan each of
+    ** the objects in the Q. This limits the recursion level by a
+    ** large amount though the stack frames get larger to hold
+    ** the GCScanQ's.
+    */
+    pScanQ->q[pScanQ->queued++] = p;
+    if (pScanQ->queued == MAX_SCAN_Q) {
+      METER(_pr_scanDepth++);
+      ScanScanQ(pScanQ);
+    }
+  }
+}
+
+/************************************************************************/
+
+/*
+** Empty the freelist for each segment. This is done to make sure that
+** the root finding step works properly (otherwise, if we had a pointer
+** into a free section, we might not find its header word and abort in
+** FindObject)
+*/
+static void EmptyFreelists(void)
+{
+    GCFreeChunk *cp;
+    GCFreeChunk *next;
+    GCSeg *sp;
+    PRWord *p;
+    PRInt32 chunkSize;
+    PRInt32 bin;
+
+    /*
+    ** Run over the freelist and make all of the free chunks look like
+    ** object debris.
+    */
+    for (bin = 0; bin <= NUM_BINS-1; bin++) {
+        cp = bins[bin];
+        while (cp) {
+            next = cp->next;
+            sp = cp->segment;
+            chunkSize = cp->chunkSize >> BYTES_PER_WORD_LOG2;
+            p = (PRWord*) cp;
+            PR_ASSERT(chunkSize != 0);
+            p[0] = MAKE_HEADER(FREE_MEMORY_TYPEIX, chunkSize);
+            SET_HBIT(sp, p);
+            cp = next;
+        }
+        bins[bin] = 0;
+    }
+    minBin = NUM_BINS - 1;
+    maxBin = 0;
+}
+
+typedef struct GCBlockEnd {
+    PRInt32	check;
+#ifdef GC_CHECK
+    PRInt32	requestedBytes;
+#endif
+#ifdef GC_STATS
+    PRInt32	bin;
+    PRInt64	allocTime; 
+#endif
+#ifdef GC_TRACEROOTS
+    PRInt32	traceGeneration;	
+#endif
+} GCBlockEnd;
+
+#define PR_BLOCK_END	0xDEADBEEF
+
+/************************************************************************/
+
+#ifdef GC_STATS
+
+typedef struct GCStat {
+    PRInt32	nallocs;
+    double	allocTime;
+    double	allocTimeVariance;
+    PRInt32	nfrees;
+    double	lifetime;
+    double	lifetimeVariance;
+} GCStat;
+
+#define GCSTAT_BINS	NUM_BINS
+
+GCStat gcstats[GCSTAT_BINS];
+
+#define GCLTFREQ_BINS	NUM_BINS
+
+PRInt32 gcltfreq[GCSTAT_BINS][GCLTFREQ_BINS];
+
+#include <math.h>
+
+static char* 
+pr_GetSizeString(PRUint32 size)
+{
+    char* sizeStr;
+    if (size < 1024)
+	sizeStr = PR_smprintf("<= %ld", size);
+    else if (size < 1024 * 1024)
+	sizeStr = PR_smprintf("<= %ldk", size / 1024);
+    else 
+	sizeStr = PR_smprintf("<= %ldM", size / (1024 * 1024));
+    return sizeStr;
+}
+
+static void
+pr_FreeSizeString(char *sizestr)
+{
+	PR_smprintf_free(sizestr);
+}
+
+
+static void
+pr_PrintGCAllocStats(FILE* out)
+{
+    PRInt32 i, j;
+    _PR_DebugPrint(out, "\n--Allocation-Stats-----------------------------------------------------------");
+    _PR_DebugPrint(out, "\n--Obj-Size----Count-----Avg-Alloc-Time-----------Avg-Lifetime---------%%Freed-\n");
+    for (i = 0; i < GCSTAT_BINS; i++) {
+	GCStat stat = gcstats[i];
+	double allocTimeMean = 0.0, allocTimeVariance = 0.0, lifetimeMean = 0.0, lifetimeVariance = 0.0;
+	PRUint32 maxSize = (1 << i);
+	char* sizeStr;
+	if (stat.nallocs != 0.0) {
+	    allocTimeMean = stat.allocTime / stat.nallocs;
+	    allocTimeVariance = fabs(stat.allocTimeVariance / stat.nallocs - allocTimeMean * allocTimeMean);
+	}
+	if (stat.nfrees != 0.0) {
+	    lifetimeMean = stat.lifetime / stat.nfrees;
+	    lifetimeVariance = fabs(stat.lifetimeVariance / stat.nfrees - lifetimeMean * lifetimeMean);
+	}
+	sizeStr = pr_GetSizeString(maxSize);
+	_PR_DebugPrint(out, "%10s %8lu %10.3f +- %10.3f %10.3f +- %10.3f (%2ld%%)\n",
+		       sizeStr, stat.nallocs,
+		       allocTimeMean, sqrt(allocTimeVariance),
+		       lifetimeMean, sqrt(lifetimeVariance),
+		       (stat.nallocs ? (stat.nfrees * 100 / stat.nallocs) : 0));
+	pr_FreeSizeString(sizeStr);
+    }
+    _PR_DebugPrint(out, "--Lifetime-Frequency-Counts----------------------------------------------------\n");
+    _PR_DebugPrint(out, "size\\cnt");
+    for (j = 0; j < GCLTFREQ_BINS; j++) {
+	_PR_DebugPrint(out, "\t%lu", j);
+    }
+    _PR_DebugPrint(out, "\n");
+    for (i = 0; i < GCSTAT_BINS; i++) {
+	PRInt32* freqs = gcltfreq[i];
+	_PR_DebugPrint(out, "%lu", (1 << i));
+	for (j = 0; j < GCLTFREQ_BINS; j++) {
+	    _PR_DebugPrint(out, "\t%lu", freqs[j]);
+	}
+	_PR_DebugPrint(out, "\n");
+    }
+    _PR_DebugPrint(out, "-------------------------------------------------------------------------------\n");
+}
+
+PR_PUBLIC_API(void)
+PR_PrintGCAllocStats(void)
+{
+    pr_PrintGCAllocStats(stderr);
+}
+
+#endif /* GC_STATS */
+
+/************************************************************************/
+
+/*
+** Sweep a segment, cleaning up all of the debris. Coallese the debris
+** into GCFreeChunk's which are added to the freelist bins.
+*/
+static PRBool SweepSegment(GCSeg *sp)
+{
+    PRWord h, tix;
+    PRWord *p;
+    PRWord *np;
+    PRWord *limit;
+    GCFreeChunk *cp;
+    PRInt32 bytes, chunkSize, segmentSize, totalFree;
+    CollectorType *ct;
+    PRInt32 bin;
+
+    /*
+    ** Now scan over the segment's memory in memory order, coallescing
+    ** all of the debris into a FreeChunk list.
+    */
+    totalFree = 0;
+    segmentSize = sp->limit - sp->base;
+    p = (PRWord *) sp->base;
+    limit = (PRWord *) sp->limit;
+    PR_ASSERT(segmentSize > 0);
+    while (p < limit) {
+    chunkSize = 0;
+    cp = (GCFreeChunk *) p;
+
+    /* Attempt to coallesce any neighboring free objects */
+    for (;;) {
+        PR_ASSERT(IS_HBIT(sp, p) != 0);
+        h = p[0];
+        bytes = OBJ_BYTES(h);
+        PR_ASSERT(bytes != 0);
+        np = (PRWord *) ((char *)p + bytes);
+        tix = (PRWord)GET_TYPEIX(h);
+        if ((h & MARK_BIT) && (tix != FREE_MEMORY_TYPEIX)) {
+#ifdef DEBUG
+        if (tix != FREE_MEMORY_TYPEIX) {
+            PR_ASSERT(_pr_collectorTypes[tix].flags != 0);
+        }
+#endif
+        p[0] = h & ~(MARK_BIT|FINAL_BIT);
+		_GCTRACE(GC_SWEEP, ("busy 0x%x (%d)", p, bytes));
+		break;
+	    }
+	    _GCTRACE(GC_SWEEP, ("free 0x%x (%d)", p, bytes));
+
+	    /* Found a free object */
+#ifdef GC_STATS
+	    {
+		PRInt32 userSize = bytes - sizeof(GCBlockEnd);
+		GCBlockEnd* end = (GCBlockEnd*)((char*)p + userSize);
+		if (userSize >= 0 && end->check == PR_BLOCK_END) {
+		    PRInt64 now = PR_Now();
+		    double nowd, delta;
+		    PRInt32 freq;
+		    LL_L2D(nowd, now);
+		    delta = nowd - end->allocTime;
+		    gcstats[end->bin].nfrees++;
+		    gcstats[end->bin].lifetime += delta;
+		    gcstats[end->bin].lifetimeVariance += delta * delta;
+
+		    InlineBinNumber(freq, delta);
+		    gcltfreq[end->bin][freq]++;
+
+		    end->check = 0;
+		}
+	    }
+#endif
+        CLEAR_HBIT(sp, p);
+        ct = &_pr_collectorTypes[tix];
+        if (0 != ct->gctype.free) {
+                (*ct->gctype.free)(p + 1);
+            }
+        chunkSize = chunkSize + bytes;
+        if (np == limit) {
+        /* Found the end of heap */
+        break;
+        }
+        PR_ASSERT(np < limit);
+        p = np;
+    }
+
+    if (chunkSize) {
+        _GCTRACE(GC_SWEEP, ("free chunk 0x%p to 0x%p (%d)",
+                   cp, (char*)cp + chunkSize - 1, chunkSize));
+        if (chunkSize < MIN_FREE_CHUNK_BYTES) {
+        /* Lost a tiny fragment until (maybe) next time */
+                METER(meter.wastedBytes += chunkSize);
+        p = (PRWord *) cp;
+        chunkSize >>= BYTES_PER_WORD_LOG2;
+        PR_ASSERT(chunkSize != 0);
+        p[0] = MAKE_HEADER(FREE_MEMORY_TYPEIX, chunkSize);
+        SET_HBIT(sp, p);
+        } else {
+                /* See if the chunk constitutes the entire segment */
+                if (chunkSize == segmentSize) {
+                    /* Free up the segment right now */
+            if (sp->info->fromMalloc) {
+                    ShrinkGCHeap(sp);
+                    return PR_TRUE;
+                }
+                }
+
+                /* Put free chunk into the appropriate bin */
+                cp->segment = sp;
+        cp->chunkSize = chunkSize;
+                InlineBinNumber(bin, chunkSize)
+                cp->next = bins[bin];
+                bins[bin] = cp;
+        if (bin < minBin) minBin = bin;
+        if (bin > maxBin) maxBin = bin;
+
+        /* Zero swept memory now */
+        memset(cp+1, 0, chunkSize - sizeof(*cp));
+                METER(meter.numFreeChunks++);
+        totalFree += chunkSize;
+        }
+    }
+
+    /* Advance to next object */
+    p = np;
+    }
+
+    PR_ASSERT(totalFree <= segmentSize);
+
+    _pr_gcData.freeMemory += totalFree;
+    _pr_gcData.busyMemory += (sp->limit - sp->base) - totalFree;
+    return PR_FALSE;
+}
+
+/************************************************************************/
+
+/* This is a list of all the objects that are finalizable. This is not
+   the list of objects that are awaiting finalization because they
+   have been collected. */
+PRCList _pr_finalizeableObjects;
+
+/* This is the list of objects that are awaiting finalization because
+   they have been collected. */
+PRCList _pr_finalQueue;
+
+/* Each object that requires finalization has one of these objects
+   allocated as well. The GCFinal objects are put on the
+   _pr_finalizeableObjects list until the object is collected at which
+   point the GCFinal object is moved to the _pr_finalQueue */
+typedef struct GCFinalStr {
+    PRCList links;
+    PRWord *object;
+} GCFinal;
+
+/* Find pointer to GCFinal struct from the list linkaged embedded in it */
+#define FinalPtr(_qp) \
+    ((GCFinal*) ((char*) (_qp) - offsetof(GCFinal,links)))
+
+static GCFinal *AllocFinalNode(void)
+{
+    return PR_NEWZAP(GCFinal);
+}
+
+static void FreeFinalNode(GCFinal *node)
+{
+    PR_DELETE(node);
+}
+
+/*
+** Prepare for finalization. At this point in the GC cycle we have
+** identified all of the live objects. For each object on the
+** _pr_finalizeableObjects list see if the object is alive or dead. If
+** it's dead, resurrect it and move it from the _pr_finalizeableObjects
+** list to the _pr_finalQueue (object's only get finalized once).
+**
+** Once _pr_finalizeableObjects has been processed we can finish the
+** GC and free up memory and release the threading lock. After that we
+** can invoke the finalization procs for each object that is on the
+** _pr_finalQueue.
+*/
+static void PrepareFinalize(void)
+{
+    PRCList *qp;
+    GCFinal *fp;
+    PRWord h;
+    PRWord *p;
+    void (PR_CALLBACK *livePointer)(void *ptr);
+#ifdef DEBUG
+    CollectorType *ct;
+#endif
+
+    /* This must be done under the same lock that the finalizer uses */
+    PR_ASSERT( GC_IS_LOCKED() );
+
+    /* cache this ptr */
+    livePointer = _pr_gcData.livePointer;
+
+    /*
+     * Pass #1: Identify objects that are to be finalized, set their
+     * FINAL_BIT.
+     */
+    qp = _pr_finalizeableObjects.next;
+    while (qp != &_pr_finalizeableObjects) {
+    fp = FinalPtr(qp);
+    qp = qp->next;
+    h = fp->object[0];        /* Grab header word */
+    if (h & MARK_BIT) {
+        /* Object is already alive */
+        continue;
+    }
+
+#ifdef DEBUG
+    ct = &_pr_collectorTypes[GET_TYPEIX(h)];
+    PR_ASSERT((0 != ct->flags) && (0 != ct->gctype.finalize));
+#endif
+    fp->object[0] |= FINAL_BIT;
+    _GCTRACE(GC_FINAL, ("moving %p (%d) to finalQueue",
+               fp->object, OBJ_BYTES(h)));
+    }
+
+    /*
+     * Pass #2: For each object that is going to be finalized, move it to
+     * the finalization queue and resurrect it
+     */
+    qp = _pr_finalizeableObjects.next;
+    while (qp != &_pr_finalizeableObjects) {
+    fp = FinalPtr(qp);
+    qp = qp->next;
+    h = fp->object[0];        /* Grab header word */
+    if ((h & FINAL_BIT) == 0) {
+        continue;
+    }
+
+    /* Resurrect the object and any objects it refers to */
+        p = &fp->object[1];
+    (*livePointer)(p);
+    PR_REMOVE_LINK(&fp->links);
+    PR_APPEND_LINK(&fp->links, &_pr_finalQueue);
+    }
+}
+
+/*
+** Scan the finalQ, marking each and every object on it live.  This is
+** necessary because we might do a GC before objects that are on the
+** final queue get finalized. Since there are no other references
+** (otherwise they would be on the final queue), we have to scan them.
+** This really only does work if we call the GC before the finalizer
+** has a chance to do its job.
+*/
+extern void PR_CALLBACK _PR_ScanFinalQueue(void *notused)
+{
+    PRCList *qp;
+    GCFinal *fp;
+    PRWord *p;
+    void ( PR_CALLBACK *livePointer)(void *ptr);
+
+    livePointer = _pr_gcData.livePointer;
+    qp = _pr_finalQueue.next;
+    while (qp != &_pr_finalQueue) {
+    fp = FinalPtr(qp);
+	_GCTRACE(GC_FINAL, ("marking 0x%x (on final queue)", fp->object));
+        p = &fp->object[1];
+    (*livePointer)(p);
+    qp = qp->next;
+    }
+}
+
+void PR_CALLBACK FinalizerLoop(void* unused)
+{
+    GCFinal *fp;
+    PRWord *p;
+    PRWord h, tix;
+    CollectorType *ct;
+
+    LOCK_GC();
+    for (;;) {
+	p = 0; h = 0;		/* don't let the gc find these pointers */
+    while (PR_CLIST_IS_EMPTY(&_pr_finalQueue))
+        PR_Wait(_pr_gcData.lock, PR_INTERVAL_NO_TIMEOUT);
+
+    _GCTRACE(GC_FINAL, ("begin finalization"));
+    while (_pr_finalQueue.next != &_pr_finalQueue) {
+        fp = FinalPtr(_pr_finalQueue.next);
+        PR_REMOVE_LINK(&fp->links);
+        p = fp->object;
+
+        h = p[0];        /* Grab header word */
+        tix = (PRWord)GET_TYPEIX(h);
+        ct = &_pr_collectorTypes[tix];
+	    _GCTRACE(GC_FINAL, ("finalize 0x%x (%d)", p, OBJ_BYTES(h)));
+
+        /*
+        ** Give up the GC lock so that other threads can allocate memory
+        ** while this finalization method is running. Get it back
+        ** afterwards so that the list remains thread safe.
+        */
+        UNLOCK_GC();
+        FreeFinalNode(fp);
+        PR_ASSERT(ct->gctype.finalize != 0);
+        (*ct->gctype.finalize)(p + 1);
+        LOCK_GC();
+    }
+    _GCTRACE(GC_FINAL, ("end finalization"));
+    PR_Notify(_pr_gcData.lock);
+    }
+}
+
+static void NotifyFinalizer(void)
+{
+    if (!PR_CLIST_IS_EMPTY(&_pr_finalQueue)) {
+    PR_ASSERT( GC_IS_LOCKED() );
+    PR_Notify(_pr_gcData.lock);
+    }
+}
+
+void _PR_CreateFinalizer(PRThreadScope scope)
+{
+    if (!_pr_gcData.finalizer) {
+    _pr_gcData.finalizer = PR_CreateThreadGCAble(PR_SYSTEM_THREAD,
+                                        FinalizerLoop, 0,
+                                        PR_PRIORITY_LOW, scope,
+                                        PR_UNJOINABLE_THREAD, 0);
+    
+    if (_pr_gcData.finalizer == NULL)
+        /* We are doomed if we can't start the finalizer */
+        PR_Abort();
+
+    }
+}
+
+void pr_FinalizeOnExit(void)
+{
+#ifdef DEBUG_warren
+    OutputDebugString("### Doing finalize-on-exit pass\n");
+#endif
+    PR_ForceFinalize();
+#ifdef DEBUG_warren
+    OutputDebugString("### Finalize-on-exit complete. Dumping object left to memory.out\n");
+    PR_DumpMemorySummary();
+    PR_DumpMemory(PR_TRUE);
+#endif
+}
+
+PR_IMPLEMENT(void) PR_ForceFinalize()
+{
+    LOCK_GC();
+    NotifyFinalizer();
+    while (!PR_CLIST_IS_EMPTY(&_pr_finalQueue)) {
+    PR_ASSERT( GC_IS_LOCKED() );
+    (void) PR_Wait(_pr_gcData.lock, PR_INTERVAL_NO_TIMEOUT);
+    }
+    UNLOCK_GC();
+
+    /* XXX I don't know how to make it wait (yet) */
+}
+
+/************************************************************************/
+
+typedef struct GCWeakStr {
+    PRCList links;
+    PRWord *object;
+} GCWeak;
+
+/*
+** Find pointer to GCWeak struct from the list linkaged embedded in it
+*/
+#define WeakPtr(_qp) \
+    ((GCWeak*) ((char*) (_qp) - offsetof(GCWeak,links)))
+
+PRCList _pr_weakLinks = PR_INIT_STATIC_CLIST(&_pr_weakLinks);
+PRCList _pr_freeWeakLinks = PR_INIT_STATIC_CLIST(&_pr_freeWeakLinks);
+
+#define WEAK_FREELIST_ISEMPTY() (_pr_freeWeakLinks.next == &_pr_freeWeakLinks)
+
+/*
+ * Keep objects referred to by weak free list alive until they can be
+ * freed
+ */
+static void PR_CALLBACK ScanWeakFreeList(void *notused) {
+    PRCList *qp = _pr_freeWeakLinks.next;
+    while (qp != &_pr_freeWeakLinks) {
+    GCWeak *wp = WeakPtr(qp);
+    qp = qp->next;
+    ProcessRootPointer(wp->object);
+    }
+}
+
+/*
+ * Empty the list of weak objects. Note that we can't call malloc/free
+ * under the cover of the GC's lock (we might deadlock), so transfer the
+ * list of free objects to a local list under the cover of the lock, then
+ * release the lock and free up the memory.
+ */
+static void EmptyWeakFreeList(void) {
+    if (!WEAK_FREELIST_ISEMPTY()) {
+    PRCList *qp, freeLinks;
+
+    PR_INIT_CLIST(&freeLinks);
+
+    /*
+     * Transfer list of free weak links from the global list to a
+     * local list.
+     */
+    LOCK_GC();
+    qp = _pr_freeWeakLinks.next;
+    while (qp != &_pr_freeWeakLinks) {
+        GCWeak *wp = WeakPtr(qp);
+        qp = qp->next;
+        PR_REMOVE_LINK(&wp->links);
+        PR_APPEND_LINK(&wp->links, &freeLinks);
+    }
+    UNLOCK_GC();
+
+    /* Free up storage now */
+    qp = freeLinks.next;
+    while (qp != &freeLinks) {
+        GCWeak *wp = WeakPtr(qp);
+        qp = qp->next;
+        PR_DELETE(wp);
+    }
+    }
+}
+
+/*
+ * Allocate a new weak node in the weak objects list
+ */
+static GCWeak *AllocWeakNode(void)
+{
+    EmptyWeakFreeList();
+    return PR_NEWZAP(GCWeak);
+}
+
+static void FreeWeakNode(GCWeak *node)
+{
+    PR_DELETE(node);
+}
+
+/*
+ * Check the weak links for validity. Note that the list of weak links is
+ * itself weak (otherwise we would keep the objects with weak links in
+ * them alive forever). As we scan the list check the weak link object
+ * itself and if it's not marked then remove it from the weak link list
+ */
+static void CheckWeakLinks(void) {
+    PRCList *qp;
+    GCWeak *wp;
+    PRWord *p, h, tix, **weakPtrAddress;
+    CollectorType *ct;
+    PRUint32 offset;
+
+    qp = _pr_weakLinks.next;
+    while (qp != &_pr_weakLinks) {
+    wp = WeakPtr(qp);
+    qp = qp->next;
+    if ((p = wp->object) != 0) {
+        h = p[0];        /* Grab header word */
+        if ((h & MARK_BIT) == 0) {
+        /*
+         * The object that has a weak link is no longer being
+         * referenced; remove it from the chain and let it get
+         * swept away by the GC. Transfer it to the list of
+         * free weak links for later freeing.
+         */
+        PR_REMOVE_LINK(&wp->links);
+        PR_APPEND_LINK(&wp->links, &_pr_freeWeakLinks);
+        collectorCleanupNeeded = 1;
+        continue;
+        }
+        
+	    /* Examine a live object that contains weak links */
+        tix = GET_TYPEIX(h);
+        ct = &_pr_collectorTypes[tix];
+        PR_ASSERT((ct->flags != 0) && (ct->gctype.getWeakLinkOffset != 0));
+        if (0 == ct->gctype.getWeakLinkOffset) {
+        /* Heap is probably corrupted */
+        continue;
+        }
+
+        /* Get offset into the object of where the weak pointer is */
+        offset = (*ct->gctype.getWeakLinkOffset)(p + 1);
+
+        /* Check the weak pointer */
+        weakPtrAddress = (PRWord**)((char*)(p + 1) + offset);
+        p = *weakPtrAddress;
+        if (p != 0) {
+        h = p[-1];    /* Grab header word for pointed to object */
+        if (h & MARK_BIT) {
+            /* Object can't be dead */
+            continue;
+        }
+        /* Break weak link to an object that is about to be swept */
+        *weakPtrAddress = 0;
+        }
+    }
+    }
+}
+
+/************************************************************************/
+
+/*
+** Perform a complete garbage collection
+*/
+
+extern GCLockHook *_pr_GCLockHook;
+
+static void dogc(void)
+{
+    RootFinder *rf;
+    GCLockHook* lhook;
+
+    GCScanQ scanQ;
+    GCSeg *sp, *esp;
+    PRInt64 start, end, diff;
+
+#if defined(GCMETER) || defined(GCTIMINGHOOK)
+    start = PR_Now();
+#endif
+
+    /*
+    ** Stop all of the other threads. This also promises to capture the
+    ** register state of each and every thread
+    */
+
+    /* 
+    ** Get all the locks that will be need during GC after SuspendAll. We 
+    ** cannot make any locking/library calls after SuspendAll.
+    */
+    if (_pr_GCLockHook) {
+        for (lhook = _pr_GCLockHook->next; lhook != _pr_GCLockHook; 
+          lhook = lhook->next) {
+          (*lhook->func)(PR_GCBEGIN, lhook->arg);
+        }
+    }
+
+    PR_SuspendAll();
+
+#ifdef GCMETER
+    /* Reset meter info */
+    if (_pr_gcMeter & _GC_METER_STATS) {
+        fprintf(stderr,
+                "[GCSTATS: busy:%ld skipped:%ld, alloced:%ld+wasted:%ld+free:%ld = total:%ld]\n",
+                (long) _pr_gcData.busyMemory,
+                (long) meter.skippedFreeChunks,
+                (long) meter.allocBytes,
+                (long) meter.wastedBytes,
+                (long) _pr_gcData.freeMemory,
+                (long) _pr_gcData.allocMemory);
+    }        
+    memset(&meter, 0, sizeof(meter));
+#endif
+
+    PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("begin mark phase; busy=%d free=%d total=%d",
+                     _pr_gcData.busyMemory, _pr_gcData.freeMemory,
+                     _pr_gcData.allocMemory));
+
+    if (_pr_beginGCHook) {
+    (*_pr_beginGCHook)(_pr_beginGCHookArg);
+    }
+
+    /*
+    ** Initialize scanQ to all zero's so that root finder doesn't walk
+    ** over it...
+    */
+    memset(&scanQ, 0, sizeof(scanQ));
+    pScanQ = &scanQ;
+
+    /******************************************/
+    /* MARK PHASE */
+
+    EmptyFreelists();
+
+    /* Find root's */
+    PR_LOG(_pr_msgc_lm, PR_LOG_WARNING,
+           ("begin mark phase; busy=%d free=%d total=%d",
+        _pr_gcData.busyMemory, _pr_gcData.freeMemory,
+            _pr_gcData.allocMemory));
+    METER(_pr_scanDepth = 0);
+    rf = _pr_rootFinders;
+    while (rf) {
+    _GCTRACE(GC_ROOTS, ("finding roots in %s", rf->name));
+    (*rf->func)(rf->arg);
+    rf = rf->next;
+    }
+    _GCTRACE(GC_ROOTS, ("done finding roots"));
+
+    /* Scan remaining object's that need scanning */
+    ScanScanQ(&scanQ);
+    PR_ASSERT(pScanQ == &scanQ);
+    PR_ASSERT(scanQ.queued == 0);
+    METER({
+    if (_pr_scanDepth > _pr_maxScanDepth) {
+        _pr_maxScanDepth = _pr_scanDepth;
+    }
+    });
+
+    /******************************************/
+    /* FINALIZATION PHASE */
+
+    METER(_pr_scanDepth = 0);
+    PrepareFinalize();
+
+    /* Scan any resurrected objects found during finalization */
+    ScanScanQ(&scanQ);
+    PR_ASSERT(pScanQ == &scanQ);
+    PR_ASSERT(scanQ.queued == 0);
+    METER({
+    if (_pr_scanDepth > _pr_maxScanDepth) {
+        _pr_maxScanDepth = _pr_scanDepth;
+    }
+    });
+    pScanQ = 0;
+
+    /******************************************/
+    /* SWEEP PHASE */
+
+    /*
+    ** Sweep each segment clean. While we are at it, figure out which
+    ** segment has the most free space and make that the current segment.
+    */
+    CheckWeakLinks();
+    _GCTRACE(GC_SWEEP, ("begin sweep phase"));
+    _pr_gcData.freeMemory = 0;
+    _pr_gcData.busyMemory = 0;
+    sp = segs;
+    esp = sp + nsegs;
+    while (sp < esp) {
+        if (SweepSegment(sp)) {
+            /*
+            ** Segment is now free and has been replaced with a different
+            ** segment object.
+            */
+            esp--;
+            continue;
+        }
+        sp++;
+    }
+
+#if defined(GCMETER) || defined(GCTIMINGHOOK)
+    end = PR_Now();
+#endif
+#ifdef GCMETER
+    LL_SUB(diff, end, start);
+    PR_LOG(GC, PR_LOG_ALWAYS,
+	   ("done; busy=%d free=%d chunks=%d total=%d time=%lldms",
+	    _pr_gcData.busyMemory, _pr_gcData.freeMemory,
+	    meter.numFreeChunks, _pr_gcData.allocMemory, diff));
+    if (_pr_gcMeter & _GC_METER_FREE_LIST) {
+        PRIntn bin;
+        fprintf(stderr, "Freelist bins:\n");
+        for (bin = 0; bin < NUM_BINS; bin++) {
+            GCFreeChunk *cp = bins[bin];
+            while (cp != NULL) {
+                fprintf(stderr, "%3d: %p %8ld\n",
+                        bin, cp, (long) cp->chunkSize);
+                cp = cp->next;
+            }
+        }
+    }
+#endif
+
+    if (_pr_endGCHook) {
+    (*_pr_endGCHook)(_pr_endGCHookArg);
+    }
+
+    /* clear the running total of the bytes allocated via BigAlloc() */
+    bigAllocBytes = 0;
+
+    /* And resume multi-threading */
+    PR_ResumeAll();
+
+    if (_pr_GCLockHook) {
+        for (lhook = _pr_GCLockHook->prev; lhook != _pr_GCLockHook; 
+          lhook = lhook->prev) {
+          (*lhook->func)(PR_GCEND, lhook->arg);
+        }
+    }
+
+    /* Kick finalizer */
+    NotifyFinalizer();
+#ifdef GCTIMINGHOOK
+    if (_pr_gcData.gcTimingHook) {
+	PRInt32 time;
+	LL_SUB(diff, end, start);
+	LL_L2I(time, diff);
+	_pr_gcData.gcTimingHook(time);
+    }
+#endif
+}
+
+PR_IMPLEMENT(void) PR_GC(void)
+{
+    LOCK_GC();
+    dogc();
+    UNLOCK_GC();
+
+    EmptyWeakFreeList();
+}
+
+/*******************************************************************************
+ * Heap Walker
+ ******************************************************************************/
+
+/*
+** This is yet another disgusting copy of the body of ProcessRootPointer
+** (the other being ProcessRootBlock), but we're not leveraging a single
+** function in their cases in interest of performance (avoiding the function
+** call).
+*/
+static PRInt32 PR_CALLBACK
+pr_ConservativeWalkPointer(void* ptr, PRWalkFun walkRootPointer, void* data)
+{
+  PRWord *p0, *p, *segBase;
+  GCSeg* sp;
+
+  p0 = (PRWord*) ptr;
+
+  if (p0 < _pr_gcData.lowSeg) return 0;                  /* below gc heap */
+  if (p0 >= _pr_gcData.highSeg) return 0;                /* above gc heap */
+
+  /* NOTE: inline expansion of InHeap */
+  /* Find segment */
+  sp = lastInHeap;
+  if (!sp || !IN_SEGMENT(sp,p0)) {
+    GCSeg *esp;
+    sp = segs;
+    esp = segs + nsegs;
+    for (; sp < esp; sp++) {
+      if (IN_SEGMENT(sp, p0)) {
+	lastInHeap = sp;
+	goto find_object;
+      }
+    }
+    return 0;
+  }
+
+  find_object:
+    /* NOTE: Inline expansion of FindObject */
+    /* Align p to it's proper boundary before we start fiddling with it */
+    p = (PRWord*) ((PRWord)p0 & ~(BYTES_PER_WORD-1L));
+    segBase = (PRWord *) sp->base;
+    do {
+        if (IS_HBIT(sp, p)) {
+            goto winner;
+        }
+        p--;
+    } while (p >= segBase);
+
+    /*
+    ** We have a pointer into the heap, but it has no header
+    ** bit. This means that somehow the very first object in the heap
+    ** doesn't have a header. This is impossible so when debugging
+    ** lets abort.
+    */
+#ifdef DEBUG
+    PR_Abort();
+#endif
+    return 0;
+
+ winner:
+    return walkRootPointer(p, data);
+}
+
+static PRInt32 PR_CALLBACK
+pr_ConservativeWalkBlock(void **base, PRInt32 count,
+			 PRWalkFun walkRootPointer, void* data)
+{
+    PRWord *p0;
+    while (--count >= 0) {
+	PRInt32 status;
+        p0 = (PRWord*) *base++;
+	status = pr_ConservativeWalkPointer(p0, walkRootPointer, data);
+	if (status) return status;
+    }
+    return 0;
+}
+
+/******************************************************************************/
+
+typedef void (*WalkObject_t)(FILE *out, GCType* tp, PRWord *obj,
+			     size_t bytes, PRBool detailed);
+typedef void (*WalkUnknown_t)(FILE *out, GCType* tp, PRWord tix, PRWord *p,
+			      size_t bytes, PRBool detailed);
+typedef void (*WalkFree_t)(FILE *out, PRWord *p, size_t size, PRBool detailed);
+typedef void (*WalkSegment_t)(FILE *out, GCSeg* sp, PRBool detailed);
+
+static void
+pr_WalkSegment(FILE* out, GCSeg* sp, PRBool detailed,
+           char* enterMsg, char* exitMsg,
+           WalkObject_t walkObject, WalkUnknown_t walkUnknown, WalkFree_t walkFree)
+{
+    PRWord *p, *limit;
+
+    p = (PRWord *) sp->base;
+    limit = (PRWord *) sp->limit;
+    if (enterMsg)
+    fprintf(out, enterMsg, p);
+    while (p < limit)
+    {
+    if (IS_HBIT(sp, p)) /* Is this an object header? */
+    {
+        PRWord h = p[0];
+        PRWord tix = GET_TYPEIX(h);
+        size_t bytes = OBJ_BYTES(h);
+        PRWord* np = (PRWord*) ((char*)p + bytes);
+
+        GCType* tp = &_pr_collectorTypes[tix].gctype;
+        if ((0 != tp) && walkObject)
+        walkObject(out, tp, p, bytes, detailed);
+        else if (walkUnknown)
+        walkUnknown(out, tp, tix, p, bytes, detailed);
+        p = np;
+    }
+    else
+    {
+        /* Must be a freelist item */
+        size_t size = ((GCFreeChunk*)p)->chunkSize;
+        if (walkFree)
+        walkFree(out, p, size, detailed);
+        p = (PRWord*)((char*)p + size);
+    }
+    }
+    if (p != limit)
+    fprintf(out, "SEGMENT OVERRUN (end should be at 0x%p)\n", limit);
+    if (exitMsg)
+    fprintf(out, exitMsg, p);
+}
+
+static void
+pr_WalkSegments(FILE *out, WalkSegment_t walkSegment, PRBool detailed)
+{
+    GCSeg *sp = segs;
+    GCSeg *esp;
+
+    LOCK_GC();
+    esp = sp + nsegs;
+    while (sp < esp)
+    {
+    walkSegment(out, sp, detailed);
+    sp++;
+    }
+    fprintf(out, "End of heap\n");
+    UNLOCK_GC();
+}
+
+/*******************************************************************************
+ * Heap Dumper
+ ******************************************************************************/
+
+PR_IMPLEMENT(void)
+PR_DumpIndent(FILE *out, int indent)
+{
+    while (--indent >= 0)
+    fprintf(out, " ");
+}
+
+static void
+PR_DumpHexWords(FILE *out, PRWord *p, int nWords,
+        int indent, int nWordsPerLine)
+{
+    while (nWords > 0)
+    {
+    int i;
+
+    PR_DumpIndent(out, indent);
+    i = nWordsPerLine;
+    if (i > nWords)
+        i = nWords;
+    nWords -= i;
+    while (i--)
+    {
+        fprintf(out, "0x%.8lX", (long) *p++);
+        if (i)
+        fputc(' ', out);
+    }
+    fputc('\n', out);
+    }
+}
+
+static void PR_CALLBACK
+pr_DumpObject(FILE *out, GCType* tp, PRWord *p, 
+          size_t bytes, PRBool detailed)
+{
+    char kindChar = tp->kindChar;
+    fprintf(out, "0x%p: 0x%.6lX %c  ",
+            p, (long) bytes, kindChar ? kindChar : '?');
+    if (tp->dump)
+    (*tp->dump)(out, (void*) (p + 1), detailed, 0);
+    if (detailed)
+    PR_DumpHexWords(out, p, bytes>>2, 22, 4);
+}
+    
+static void PR_CALLBACK
+pr_DumpUnknown(FILE *out, GCType* tp, PRWord tix, PRWord *p, 
+           size_t bytes, PRBool detailed)
+{
+    char kindChar = tp->kindChar;
+    fprintf(out, "0x%p: 0x%.6lX %c  ",
+            p, (long) bytes, kindChar ? kindChar : '?');
+    fprintf(out, "UNKNOWN KIND %ld\n", (long) tix);
+    if (detailed)
+    PR_DumpHexWords(out, p, bytes>>2, 22, 4);
+}
+
+static void PR_CALLBACK
+pr_DumpFree(FILE *out, PRWord *p, size_t size, PRBool detailed)
+{
+    fprintf(out, "0x%p: 0x%.6lX -  FREE\n", p, (long) size);
+}
+
+static void PR_CALLBACK
+pr_DumpSegment(FILE* out, GCSeg* sp, PRBool detailed)
+{
+    pr_WalkSegment(out, sp, detailed,
+           "\n   Address: Length\n0x%p: Beginning of segment\n",
+           "0x%p: End of segment\n\n",
+           pr_DumpObject, pr_DumpUnknown, pr_DumpFree);
+}
+
+static void pr_DumpRoots(FILE *out);
+
+/*
+** Dump out the GC heap.
+*/
+PR_IMPLEMENT(void)
+PR_DumpGCHeap(FILE *out, PRBool detailed)
+{
+    fprintf(out, "\n"
+        "The kinds are:\n"
+        " U unscanned block\n"
+        " W weak link block\n"
+        " S scanned block\n"
+        " F scanned and final block\n"
+        " C class record\n"
+        " X context record\n"
+        " - free list item\n"
+        " ? other\n");
+    LOCK_GC();
+    pr_WalkSegments(out, pr_DumpSegment, detailed);
+    if (detailed)
+    pr_DumpRoots(out);
+    UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void)
+PR_DumpMemory(PRBool detailed)
+{
+    PR_DumpToFile("memory.out", "Dumping memory", PR_DumpGCHeap, detailed);
+}
+
+/******************************************************************************/
+
+static PRInt32 PR_CALLBACK
+pr_DumpRootPointer(PRWord* p, void* data)
+{
+    PRWord h = p[0];
+    PRWord tix = GET_TYPEIX(h);
+      size_t bytes = OBJ_BYTES(h);
+      
+      GCType* tp = &_pr_collectorTypes[tix].gctype;
+      if (0 != tp)
+      pr_DumpObject(_pr_gcData.dumpOutput, tp, p, bytes, PR_FALSE);
+      else
+      pr_DumpUnknown(_pr_gcData.dumpOutput, tp, tix, p, bytes, PR_FALSE);
+    return 0;
+}
+
+static void PR_CALLBACK
+pr_ConservativeDumpRootPointer(void* ptr)
+{
+    (void)pr_ConservativeWalkPointer(ptr, (PRWalkFun) pr_DumpRootPointer, NULL);
+}
+
+static void PR_CALLBACK
+pr_ConservativeDumpRootBlock(void **base, PRInt32 count)
+{
+    (void)pr_ConservativeWalkBlock(base, count, (PRWalkFun) pr_DumpRootPointer, NULL);
+}
+
+extern int
+DumpThreadRoots(PRThread *t, int i, void *notused);
+
+static void
+pr_DumpRoots(FILE *out)
+{
+    RootFinder *rf;
+    void (*liveBlock)(void **base, PRInt32 count);
+    void (*livePointer)(void *ptr);
+    void (*processRootBlock)(void **base, PRInt32 count);
+    void (*processRootPointer)(void *ptr);
+
+    LOCK_GC();
+
+    liveBlock = _pr_gcData.liveBlock;
+    livePointer = _pr_gcData.livePointer;
+    processRootBlock = _pr_gcData.processRootBlock;
+    processRootPointer = _pr_gcData.processRootPointer;
+    
+    _pr_gcData.liveBlock = pr_ConservativeDumpRootBlock;
+    _pr_gcData.livePointer = pr_ConservativeDumpRootPointer;
+    _pr_gcData.processRootBlock = pr_ConservativeDumpRootBlock;
+    _pr_gcData.processRootPointer = pr_ConservativeDumpRootPointer;
+    _pr_gcData.dumpOutput = out;
+
+    rf = _pr_rootFinders;
+    while (rf) {
+    fprintf(out, "\n===== Roots for %s\n", rf->name);
+    (*rf->func)(rf->arg);
+    rf = rf->next;
+    }
+
+    _pr_gcData.liveBlock = liveBlock;
+    _pr_gcData.livePointer = livePointer;
+    _pr_gcData.processRootBlock = processRootBlock;
+    _pr_gcData.processRootPointer = processRootPointer;
+    _pr_gcData.dumpOutput = NULL;
+
+    UNLOCK_GC();
+}
+
+/*******************************************************************************
+ * Heap Summary Dumper
+ ******************************************************************************/
+
+PRSummaryPrinter summaryPrinter = NULL;
+void* summaryPrinterClosure = NULL;
+
+PR_IMPLEMENT(void) 
+PR_RegisterSummaryPrinter(PRSummaryPrinter fun, void* closure)
+{
+    summaryPrinter = fun;
+    summaryPrinterClosure = closure;
+}
+
+static void PR_CALLBACK
+pr_SummarizeObject(FILE *out, GCType* tp, PRWord *p,
+           size_t bytes, PRBool detailed)
+{
+    if (tp->summarize)
+    (*tp->summarize)((void GCPTR*)(p + 1), bytes);
+}
+
+static void PR_CALLBACK
+pr_DumpSummary(FILE* out, GCSeg* sp, PRBool detailed)
+{
+    pr_WalkSegment(out, sp, detailed, NULL, NULL,
+           pr_SummarizeObject, NULL, NULL);
+}
+
+PR_IMPLEMENT(void)
+PR_DumpGCSummary(FILE *out, PRBool detailed)
+{
+    if (summaryPrinter) {
+    pr_WalkSegments(out, pr_DumpSummary, detailed);
+    summaryPrinter(out, summaryPrinterClosure);
+    }
+#if 0
+    fprintf(out, "\nFinalizable objects:\n");
+    {
+    PRCList *qp;
+    qp = _pr_pendingFinalQueue.next;
+    while (qp != &_pr_pendingFinalQueue) {
+        GCFinal* fp = FinalPtr(qp);
+        PRWord h = fp->object[0];        /* Grab header word */
+        PRWord tix = GET_TYPEIX(h);
+        GCType* tp = _pr_gcTypes[tix];
+        size_t bytes = OBJ_BYTES(h);
+        pr_DumpObject(out, tp, fp->object, bytes, PR_FALSE);
+        qp = qp->next;
+    }
+    }
+#endif
+}
+
+PR_IMPLEMENT(void)
+PR_DumpMemorySummary(void)
+{
+    PR_DumpToFile("memory.out", "Memory Summary", PR_DumpGCSummary, PR_FALSE);
+}
+
+/*******************************************************************************
+ * End Of Heap Walker 
+ ******************************************************************************/
+
+#ifdef GC_TRACEROOTS
+
+PRInt32 pr_traceGen = 0;
+
+static PRBool
+pr_IsMarked(PRWord* p)
+{
+    GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+    PR_ASSERT(end->check == PR_BLOCK_END);
+    return end->traceGeneration == pr_traceGen;
+}
+
+static void
+pr_Mark(PRWord* p)
+{
+    GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+    PR_ASSERT(end->check == PR_BLOCK_END);
+    end->traceGeneration = pr_traceGen;
+}
+
+PRWord* pr_traceObj;	/* set this in the debugger, then execute PR_TraceRoot() */
+
+static PRInt32 PR_CALLBACK
+pr_TraceRootObject(void* obj, void* data);
+
+static PRInt32 PR_CALLBACK
+pr_TraceRootPointer(PRWord *p, void* data)
+{
+    PRInt32 printTrace = 0;
+    PRWord h = p[0];
+    PRWord tix = GET_TYPEIX(h);
+    GCType* tp = &_pr_collectorTypes[tix].gctype;
+    FILE* out = _pr_gcData.dumpOutput;
+
+    PR_ASSERT(tp);
+    if (pr_IsMarked(p))
+	return printTrace;
+
+    pr_Mark(p);
+    if (p == pr_traceObj) {
+	fprintf(out, "\n### Found path to:\n");
+	printTrace = 1;
+    }
+    else {
+	if (PR_StackSpaceLeft(PR_GetCurrentThread()) < 512) {
+	    fprintf(out, "\n### Path too deep (giving up):\n");
+	    printTrace = 1;
+	}
+	else if (tp->walk) {
+	    printTrace = tp->walk((void*)(p + 1), pr_TraceRootObject, data);
+	}
+	/* else there's no way to walk this object, so we
+	   haven't found what we're looking for */
+    }
+
+    if (printTrace == 1) {
+	PR_ASSERT(tp->dump);
+	fprintf(out, "0x%p: ", p);
+	tp->dump(out, (void*)(p + 1), PR_FALSE, 1);
+    }
+    return printTrace;
+}
+
+static PRInt32 PR_CALLBACK
+pr_TraceRootObject(void* obj, void* data)
+{
+    /* This version of pr_TraceRootPointer takes object
+       pointers, instead of gc header pointers. */
+    return pr_TraceRootPointer((PRWord*)obj - 1, data);
+}
+
+static void PR_CALLBACK
+pr_ConservativeTraceRootPointer(PRWord *p)
+{
+    PRInt32 status;
+    ++pr_traceGen;
+    status = pr_ConservativeWalkPointer(p, pr_TraceRootPointer, NULL);
+    if (status) {
+	FILE* out = _pr_gcData.dumpOutput;
+	fprintf(out, "### from root at 0x%p\n\n", p);
+    }
+}
+
+static void PR_CALLBACK
+pr_ConservativeTraceRootBlock(void **base, PRInt32 count)
+{
+    PRInt32 status;
+    ++pr_traceGen;
+    status = pr_ConservativeWalkBlock(base, count, pr_TraceRootPointer, NULL);
+    if (status) {
+	FILE* out = _pr_gcData.dumpOutput;
+	fprintf(out, "### from root in range 0x%p + 0x%lx\n\n",
+                base, (long) count);
+    }
+}
+
+static void
+PR_TraceRoot1(FILE* out, PRBool detailed)
+{
+    RootFinder *rf;
+    void (*liveBlock)(void **base, PRInt32 count);
+    void (*livePointer)(void *ptr);
+    void (*processRootBlock)(void **base, PRInt32 count);
+    void (*processRootPointer)(void *ptr);
+
+    LOCK_GC();
+
+    liveBlock = _pr_gcData.liveBlock;
+    livePointer = _pr_gcData.livePointer;
+    processRootBlock = _pr_gcData.processRootBlock;
+    processRootPointer = _pr_gcData.processRootPointer;
+    
+    _pr_gcData.liveBlock = pr_ConservativeTraceRootBlock;
+    _pr_gcData.livePointer = pr_ConservativeTraceRootPointer;
+    _pr_gcData.processRootBlock = pr_ConservativeTraceRootBlock;
+    _pr_gcData.processRootPointer = pr_ConservativeTraceRootPointer;
+    _pr_gcData.dumpOutput = out;
+
+    fprintf(out, "### Looking for paths to 0x%p\n\n", pr_traceObj);
+
+    rf = _pr_rootFinders;
+    while (rf) {
+	fprintf(out, "\n===== Roots for %s\n", rf->name);
+	(*rf->func)(rf->arg);
+	rf = rf->next;
+    }
+
+    _pr_gcData.liveBlock = liveBlock;
+    _pr_gcData.livePointer = livePointer;
+    _pr_gcData.processRootBlock = processRootBlock;
+    _pr_gcData.processRootPointer = processRootPointer;
+    _pr_gcData.dumpOutput = NULL;
+
+    UNLOCK_GC();
+}
+
+PR_PUBLIC_API(void)
+PR_TraceRoot()
+{
+    /*
+    ** How this works: 
+    ** Once you find the object you want to trace the roots of, set the
+    ** global variable pr_traceObj to point to it (the header, not the
+    ** java handle), and then call this routine (on Windows, you can set
+    ** a breakpoint at the end of a function that returns void (e.g. dogc)
+    ** and then do a "set next statement" to point to this routine and go.
+    ** This will dump a list of the paths from the roots to the object in
+    ** question to your memory.out file.
+    */
+    PR_DumpToFile("memory.out", "Tracing Roots", PR_TraceRoot1, PR_FALSE);
+}
+
+#endif /* GC_TRACEROOTS */
+
+/******************************************************************************/
+
+#if defined(DEBUG) && defined(WIN32)
+static void DumpApplicationHeap(FILE *out, HANDLE heap)
+{
+    PROCESS_HEAP_ENTRY entry;
+    DWORD err;
+
+    if (!HeapLock(heap))
+    OutputDebugString("Can't lock the heap.\n");
+    entry.lpData = 0;
+    fprintf(out, "   address:       size ovhd region\n");
+    while (HeapWalk(heap, &entry))
+    {
+    WORD flags = entry.wFlags;
+
+    fprintf(out, "0x%.8X: 0x%.8X 0x%.2X 0x%.2X  ", entry.lpData, entry.cbData,
+        entry.cbOverhead, entry.iRegionIndex);
+    if (flags & PROCESS_HEAP_REGION)
+        fprintf(out, "REGION  committedSize=0x%.8X uncommittedSize=0x%.8X firstBlock=0x%.8X lastBlock=0x%.8X",
+            entry.Region.dwCommittedSize, entry.Region.dwUnCommittedSize,
+            entry.Region.lpFirstBlock, entry.Region.lpLastBlock);
+    else if (flags & PROCESS_HEAP_UNCOMMITTED_RANGE)
+        fprintf(out, "UNCOMMITTED");
+    else if (flags & PROCESS_HEAP_ENTRY_BUSY)
+    {
+        if (flags & PROCESS_HEAP_ENTRY_DDESHARE)
+        fprintf(out, "DDEShare ");
+        if (flags & PROCESS_HEAP_ENTRY_MOVEABLE)
+        fprintf(out, "Moveable Block  handle=0x%.8X", entry.Block.hMem);
+        else
+        fprintf(out, "Block");
+    }
+    fprintf(out, "\n");
+    }
+    if ((err = GetLastError()) != ERROR_NO_MORE_ITEMS)
+    fprintf(out, "ERROR %d iterating through the heap\n", err);
+    if (!HeapUnlock(heap))
+    OutputDebugString("Can't unlock the heap.\n");
+}
+#endif
+
+#if defined(DEBUG) && defined(WIN32)
+static void DumpApplicationHeaps(FILE *out)
+{
+    HANDLE mainHeap;
+    HANDLE heaps[100];
+    DWORD nHeaps;
+    PRInt32 i;
+
+    mainHeap = GetProcessHeap();
+    nHeaps = GetProcessHeaps(100, heaps);
+    if (nHeaps > 100)
+    nHeaps = 0;
+    fprintf(out, "%ld heaps:\n", (long) nHeaps);
+    for (i = 0; i<nHeaps; i++)
+    {
+    HANDLE heap = heaps[i];
+
+    fprintf(out, "Heap at 0x%.8lX", (long) heap);
+    if (heap == mainHeap)
+        fprintf(out, " (main)");
+    fprintf(out, ":\n");
+    DumpApplicationHeap(out, heap);
+    fprintf(out, "\n");
+    }
+    fprintf(out, "End of heap dump\n\n");
+}
+#endif
+
+#if defined(DEBUG) && defined(WIN32)
+PR_IMPLEMENT(void) PR_DumpApplicationHeaps(void)
+{
+    FILE *out;
+
+    OutputDebugString("Dumping heaps...");
+    out = fopen("heaps.out", "a");
+    if (!out)
+    OutputDebugString("Can't open \"heaps.out\"\n");
+    else
+    {
+    struct tm *newtime;
+    time_t aclock;
+
+    time(&aclock);
+    newtime = localtime(&aclock);
+    fprintf(out, "Heap dump on %s\n", asctime(newtime));    /* Print current time */
+    DumpApplicationHeaps(out);
+    fprintf(out, "\n\n");
+    fclose(out);
+    }
+    OutputDebugString(" done\n");
+}
+#else
+
+PR_IMPLEMENT(void) PR_DumpApplicationHeaps(void)
+{
+    fprintf(stderr, "Native heap dumping is currently implemented only for Windows32.\n");
+}
+#endif
+
+/************************************************************************/
+
+/*
+** Scan the freelist bins looking for a big enough chunk of memory to
+** hold "bytes" worth of allocation. "bytes" already has the
+** per-allocation header added to it. Return a pointer to the object with
+** its per-allocation header already prepared.
+*/
+static PRWord *BinAlloc(int cbix, PRInt32 bytes, int dub)
+{
+    GCFreeChunk **cpp, *cp, *cpNext;
+    GCSeg *sp;
+    PRInt32 chunkSize, remainder;
+    PRWord *p, *np;
+    PRInt32 bin, newbin;
+
+    /* Compute bin that allocation belongs in */
+    InlineBinNumber(bin,bytes)
+    if (bin < minBin) {
+    bin = minBin;    /* Start at first filled bin */
+    }
+
+    /* Search in the bin, and larger bins, for a big enough piece */
+    for (; bin <= NUM_BINS-1; bin++) {
+        cpp = &bins[bin];
+    while ((cp = *cpp) != 0) {
+        chunkSize = cp->chunkSize;
+        if (chunkSize < bytes) {
+        /* Too small; skip it */
+            METER(meter.skippedFreeChunks++);
+        cpp = &cp->next;
+        continue;
+        }
+
+        /* We have found a hunk of memory large enough to use */
+        p = (PRWord*) cp;
+        sp = cp->segment;
+        cpNext = cp->next;
+#ifndef IS_64
+        if (dub && (((PRWord)p & (PR_BYTES_PER_DWORD-1)) == 0)) {
+        /*
+         * We are double aligning the memory and the current free
+         * chunk is aligned on an even boundary. Because header
+         * words are one word long we need to discard the first
+         * word of memory.
+         */
+        p[0] = MAKE_HEADER(FREE_MEMORY_TYPEIX, 1);
+        SET_HBIT(sp, p);
+        p++;
+        chunkSize -= PR_BYTES_PER_WORD;
+        bytes -= PR_BYTES_PER_WORD;
+        PR_ASSERT(((PRWord)p & (PR_BYTES_PER_DWORD-1)) != 0);
+        _pr_gcData.freeMemory -= PR_BYTES_PER_WORD;
+        _pr_gcData.busyMemory += PR_BYTES_PER_WORD;
+        }
+#endif
+        np = (PRWord*) ((char*) p + bytes);
+        remainder = chunkSize - bytes;
+        if (remainder >= MIN_FREE_CHUNK_BYTES) {
+        /* The left over memory is large enough to be freed. */
+        cp = (GCFreeChunk*) np;
+        cp->segment = sp;
+        cp->chunkSize = remainder;
+        InlineBinNumber(newbin, remainder)
+        if (newbin != bin) {
+            *cpp = (GCFreeChunk*) cpNext; /* remove */
+            cp->next = bins[newbin];      /* insert */
+            bins[newbin] = cp;
+            if (newbin < minBin) minBin = newbin;
+            if (newbin > maxBin) maxBin = newbin;
+        } else {
+            /* Leave it on the same list */
+            cp->next = cpNext;
+            *cpp = (GCFreeChunk*) np;
+        }
+        } else {
+        /*
+         * The left over memory is too small to be released. Just
+         * leave it attached to the chunk of memory being
+         * returned.
+         */
+        *cpp = cpNext;
+        bytes = chunkSize;
+        }
+        p[0] = MAKE_HEADER(cbix, (bytes >> PR_BYTES_PER_WORD_LOG2));
+        SET_HBIT(sp, p);
+        _pr_gcData.freeMemory -= bytes;
+        _pr_gcData.busyMemory += bytes;
+        return p;
+    }
+    }
+    return 0;
+}
+
+/*
+** Allocate a piece of memory that is "big" in it's own segment.  Make
+** the object consume the entire segment to avoid fragmentation.  When
+** the object is no longer referenced, the segment is freed.
+*/
+static PRWord *BigAlloc(int cbix, PRInt32 bytes, int dub)
+{
+    GCSeg *sp;
+    PRWord *p, h;
+    PRInt32 chunkSize;
+
+    /*
+    ** If the number of bytes allocated via BigAlloc() since the last GC
+    ** exceeds BIG_ALLOC_GC_SIZE then do a GC Now...
+    */
+    if (bigAllocBytes >= BIG_ALLOC_GC_SIZE) {
+        dogc();
+    }
+    bigAllocBytes += bytes;
+
+    /* Get a segment to hold this allocation */
+    sp = GrowHeapExactly(bytes);
+
+    if (sp) {
+        p = (PRWord*) sp->base;
+        chunkSize = sp->limit - sp->base;
+
+        /* All memory is double aligned on 64 bit machines... */
+#ifndef IS_64
+        if (dub && (((PRWord)p & (PR_BYTES_PER_DWORD-1)) == 0)) {
+            /*
+            ** Consume the first word of the chunk with a dummy
+            ** unreferenced object.
+            */
+            p[0] = MAKE_HEADER(FREE_MEMORY_TYPEIX, 1);
+            SET_HBIT(sp, p);
+            p++;
+            chunkSize -= PR_BYTES_PER_WORD;
+            _pr_gcData.freeMemory -= PR_BYTES_PER_WORD;
+            _pr_gcData.busyMemory += PR_BYTES_PER_WORD;
+            PR_ASSERT(((PRWord)p & (PR_BYTES_PER_DWORD-1)) != 0);
+        }
+#endif
+
+        /* Consume the *entire* segment with a single allocation */
+        h = MAKE_HEADER(cbix, (chunkSize >> PR_BYTES_PER_WORD_LOG2));
+        p[0] = h;
+        SET_HBIT(sp, p);
+        _pr_gcData.freeMemory -= chunkSize;
+        _pr_gcData.busyMemory += chunkSize;
+    return p;
+    }
+    return 0;
+}
+
+/* we disable gc allocation during low memory conditions */
+static PRBool allocationEnabled = PR_TRUE;
+
+PR_IMPLEMENT(void) PR_EnableAllocation(PRBool yesOrNo)
+{
+    allocationEnabled = yesOrNo;
+}
+
+static void CollectorCleanup(void) {
+    while (collectorCleanupNeeded) {
+    LOCK_GC();
+    collectorCleanupNeeded = 0;
+    UNLOCK_GC();
+    if (freeSegs) {
+        FreeSegments();
+    }
+    if (!WEAK_FREELIST_ISEMPTY()) {
+        EmptyWeakFreeList();
+    }
+    }
+}
+
+/******************************************************************************/
+
+#ifdef GC_CHECK
+static PRInt32 allocationCount;
+
+static void EarthShatteringKaBoom(PRInt32 whichOne) {
+    long* p = 0;
+    *p = 0;
+}
+
+/* Check a segment of heap memory. Verify that the object memory
+   hasn't been overwritten (past the end at least) */
+static void CheckSegment(GCSeg* sp) {
+    PRWord h, tix;
+    PRWord *p, *lastp, *np, *limit;
+
+    lastp = p = (PRWord *) sp->base;
+    limit = (PRWord *) sp->limit;
+    while (p < limit) {
+    if (IS_HBIT(sp, p)) {
+	    char *cp, i;
+	    GCBlockEnd* end;
+	    PRWord bytes, requestedBytes;
+
+	    h = p[0];
+	    tix = GET_TYPEIX(h);
+	    bytes = OBJ_BYTES(h);
+	    np = (PRWord *) ((char *)p + bytes);
+	    if (tix != FREE_MEMORY_TYPEIX) {
+                PRInt32 test;	/* msdev get's fooled without this local */
+		/* A live object is here. The last word in the object will
+		   contain the objects requestedSize */
+		end = (GCBlockEnd*)((char*)(p) + bytes - sizeof(GCBlockEnd));
+		test = end->check;
+		if (test != PR_BLOCK_END) {
+		    PR_ASSERT(test == PR_BLOCK_END);
+		}
+		requestedBytes = end->requestedBytes;
+		if (requestedBytes >= bytes) EarthShatteringKaBoom(0);
+		cp = (char*)(p + 1) + requestedBytes;
+		i = (char) 0xff;
+		while (cp < (char*)end) {
+            if (*cp != i) EarthShatteringKaBoom(1);
+            cp++;
+            i--;
+        }
+        }
+        lastp = p;
+        p = np;
+    } else {
+        /* Must be a freelist item */
+        GCFreeChunk *cp = (GCFreeChunk*) p;
+        if ((PRInt32)cp->chunkSize < (PRInt32)sizeof(GCFreeChunk)) {
+            EarthShatteringKaBoom(3);
+        }
+        lastp = p;
+        p = (PRWord*) ((char*)p + cp->chunkSize);
+    }
+    }
+}
+
+static void CheckHeap(void) {
+    GCSeg *sp = segs;
+    GCSeg *esp = sp + nsegs;
+    while (sp < esp) {
+    CheckSegment(sp);
+    sp++;
+    }
+}
+
+#endif /* GC_CHECK */
+
+/******************************************************************************/
+
+#ifdef DEBUG
+long gc_thrash = -1L;
+#endif
+
+/*
+** Allocate memory from the GC Heap. Performs garbage collections if
+** memory gets tight and grows the heap as needed. May return NULL if
+** memory cannot be found.
+*/
+PR_IMPLEMENT(PRWord GCPTR *)PR_AllocMemory(
+    PRWord requestedBytes, PRInt32 tix, PRWord flags)
+{
+    PRWord *p;
+    CollectorType *ct;
+    PRInt32 bytes;
+    GCFinal *final = 0;
+    GCWeak *weak = 0;
+    int dub = flags & PR_ALLOC_DOUBLE;
+    PRInt32 objBytes;
+#ifdef GC_STATS
+    PRInt64 allocTime, ldelta;
+#endif
+
+    if (!allocationEnabled) return NULL;
+
+    PR_ASSERT(requestedBytes >= 0);
+    PR_ASSERT(_pr_collectorTypes[tix].flags != 0);
+
+#ifdef DEBUG
+    if (_pr_do_a_dump) {
+    /*
+    ** Collect, pause for a second (lets finalizer run), and then GC
+    ** again.
+    */
+    PR_GC();
+    PR_Sleep(PR_MicrosecondsToInterval(1000000L));
+    PR_GC();
+    PR_DumpGCHeap(_pr_dump_file, PR_TRUE);
+    _pr_do_a_dump = 0;
+    }
+#endif
+
+#ifdef GC_STATS
+    allocTime = PR_Now();
+#endif
+    bytes = (PRInt32) requestedBytes;
+
+    /*
+    ** Align bytes to a multiple of a PRWord, then add in enough space
+    ** to hold the header word.
+    **
+    ** MSVC 1.52 crashed on the ff. code because of the "complex" shifting :-(
+    */
+    /* Check for possible overflow of bytes before performing add */
+    if ((MAX_INT - PR_BYTES_PER_WORD) < bytes ) return NULL;
+    bytes = (bytes + PR_BYTES_PER_WORD - 1) >> PR_BYTES_PER_WORD_LOG2;
+    bytes <<= PR_BYTES_PER_WORD_LOG2;
+    /* Check for possible overflow of bytes before performing add */
+    if ((MAX_INT - sizeof(PRWord)) < bytes ) return NULL;
+    bytes += sizeof(PRWord);
+    /*
+     * Add in an extra word of memory for double-aligned memory. Some
+     * percentage of the time this will waste a word of memory (too
+     * bad). Howver, it makes the allocation logic much simpler and
+     * faster.
+     */
+#ifndef IS_64
+    if (dub) {
+        /* Check for possible overflow of bytes before performing add */
+        if ((MAX_INT - PR_BYTES_PER_WORD) < bytes ) return NULL;
+        bytes += PR_BYTES_PER_WORD;
+    }
+#endif
+
+#ifdef GC_CHECK
+    if (_pr_gcData.flags & GC_CHECK) {
+        /* Bloat the allocation a bit so that we can lay down
+           a check pattern that we will validate */
+        /* Check for possible overflow of bytes before performing add */
+        if ((MAX_INT - PR_BYTES_PER_WORD * 3) < bytes ) return NULL;
+        bytes += PR_BYTES_PER_WORD * 3;
+    }
+#endif
+
+#if defined(GC_CHECK) || defined(GC_STATS) || defined(GC_TRACEROOTS)
+    if ((MAX_INT - sizeof(GCBlockEnd)) < bytes ) return NULL;
+    bytes += sizeof(GCBlockEnd);
+#endif
+
+    PR_ASSERT( bytes < MAX_ALLOC_SIZE );
+    /*
+    ** Java can ask for objects bigger than MAX_ALLOC_SIZE,
+    ** but it won't get them.
+    */
+    if (bytes >= MAX_ALLOC_SIZE) return NULL;
+
+#ifdef DEBUG
+    if (gc_thrash == -1L ? (gc_thrash = (long)PR_GetEnv("GC_THRASH")):gc_thrash) PR_GC();
+#endif
+
+    ct = &_pr_collectorTypes[tix];
+    if (ct->flags & (_GC_TYPE_FINAL|_GC_TYPE_WEAK)) {
+    if (0 != ct->gctype.finalize) {
+        /*
+        ** Allocate a GCFinal struct for this object in advance. Don't put
+        ** it on the pending list until we have allocated the object
+        */
+        final = AllocFinalNode();
+        if (!final) {
+        /* XXX THIS IS NOT ACCEPTABLE*/
+		PR_ASSERT(0);
+        return 0;
+        }
+    }
+    if (0 != ct->gctype.getWeakLinkOffset) {
+        /*
+        ** Allocate a GCWeak struct for this object in advance. Don't put
+        ** it on the weak links list until we have allocated the object
+        */
+        weak = AllocWeakNode();
+        if (!weak) {
+        /* XXX THIS IS NOT ACCEPTABLE*/
+        if (0 != final) {
+            FreeFinalNode(final);
+        }
+		PR_ASSERT(0);
+        return 0;
+        }
+    }
+    }
+
+    LOCK_GC();
+#ifdef GC_CHECK
+    if (_pr_gcData.flags & GC_CHECK) CheckHeap();
+    allocationCount++;
+#endif
+
+    /* Check for overflow of maximum size we can handle */
+    if (bytes > MAX_ALLOC) goto lost;
+
+    /* Try default allocation */
+    p = ((bytes >= BIG_ALLOC) && (nsegs < MAX_SEGS)) ?
+        BigAlloc(tix, bytes, dub) : BinAlloc(tix, bytes, dub);
+    if (0 == p) {
+#ifdef GC_STATS
+        LL_SUB(ldelta, PR_Now(), allocTime);
+#endif
+        /* Collect some memory */
+        _GCTRACE(GC_ALLOC, ("force GC: want %d", bytes));
+        dogc();
+        PR_ASSERT( GC_IS_LOCKED() );
+
+        /* After a collection we check and see if we should grow the
+        ** heap. We grow the heap when the amount of memory free is less
+        ** than a certain percentage of the heap size. We don't check to
+        ** see if the grow succeeded because our fallback strategy in
+        ** either case is to try one more time to allocate. */
+        if ((_pr_gcData.allocMemory < _pr_gcData.maxMemory)
+        && ((_pr_gcData.freeMemory <
+            ((_pr_gcData.allocMemory * MIN_FREE_THRESHOLD_AFTER_GC) / 100L))
+        || (_pr_gcData.freeMemory < bytes))) {
+            GrowHeap(PR_MAX(bytes, segmentSize));
+        }
+#ifdef GC_STATS
+        LL_ADD(allocTime, PR_Now(), ldelta);
+#endif
+
+        /* Try again */
+        p = ((bytes >= BIG_ALLOC) && (nsegs < MAX_SEGS)) ?
+            BigAlloc(tix, bytes, dub) : BinAlloc(tix, bytes, dub);
+        if (0 == p) {
+            /* Well that lost big time. Memory must be pretty well fragmented */
+            if (!GrowHeap(PR_MAX(bytes, segmentSize))) goto lost;
+            p = BinAlloc(tix, bytes, dub);
+            if (0 == p) goto lost;
+        }
+    }
+
+    /* Zero out the portion of the object memory that was used by
+       the GCFreeChunk structure (skip the first word because it
+       was already overwritten by the gc header word) */
+    objBytes = OBJ_BYTES(p[0]);
+    if (objBytes > sizeof(PRWord)) p[1] = 0;
+    if (objBytes > sizeof(PRWord)*2) p[2] = 0;
+
+    if (final) {
+	_GCTRACE(GC_ALLOC, ("alloc 0x%x (%d) final=0x%x",
+                p, bytes, final));
+    final->object = p;
+    PR_APPEND_LINK(&final->links, &_pr_finalizeableObjects);
+    } else {
+	_GCTRACE(GC_ALLOC, ("alloc 0x%x (%d)", p, bytes));
+    }
+    if (weak) {
+    weak->object = p;
+    PR_APPEND_LINK(&weak->links, &_pr_weakLinks);
+    }
+    METER(meter.allocBytes += bytes);
+    METER(meter.wastedBytes += (bytes - requestedBytes));
+    UNLOCK_GC();
+
+    if (collectorCleanupNeeded) {
+	CollectorCleanup();
+    }
+
+#if defined(GC_CHECK) || defined(GC_STATS) || defined(GC_TRACEROOTS)
+    {
+	GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+	end->check = PR_BLOCK_END;
+    }
+#endif
+#ifdef GC_STATS
+    {
+	PRInt64 now = PR_Now();
+	double delta;
+	PRInt32 bin;
+	GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+
+	end->allocTime = allocTime;
+	LL_SUB(ldelta, now, allocTime);
+	LL_L2D(delta, ldelta);
+	InlineBinNumber(bin, requestedBytes);
+	end->bin = bin;
+	gcstats[bin].nallocs++;
+	gcstats[bin].allocTime += delta;
+	gcstats[bin].allocTimeVariance += delta * delta;
+    }
+#endif
+#ifdef GC_CHECK
+    if (_pr_gcData.flags & GC_CHECK) {
+    /* Place a pattern in the memory that was allocated that was not
+       requested. We will check the pattern later. */
+    char* cp = (char*)(p + 1) + requestedBytes;
+	GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+	char i = (char) 0xff;
+	while (cp < (char*)end) {
+	    *cp++ = i--;
+	}
+	end->requestedBytes = requestedBytes;
+	CheckHeap();
+    }
+#endif
+    return p + 1;
+
+  lost:
+    /* Out of memory */
+    UNLOCK_GC();
+    if (final) {
+    FreeFinalNode(final);
+    }
+    if (weak) {
+    FreeWeakNode(weak);
+    }
+    if (collectorCleanupNeeded) {
+    CollectorCleanup();
+    }
+    return 0;
+}
+
+/* Shortcut allocator for objects that do not require finalization or
+   are weak objects */
+PR_IMPLEMENT(PRWord GCPTR *)
+PR_AllocSimpleMemory(PRWord requestedBytes, PRInt32 tix)
+{
+    PRWord *p;
+    PRInt32 bytes;
+    PRInt32 objBytes;
+#ifdef GC_STATS
+    PRInt64 allocTime, ldelta;
+#endif
+
+    if (!allocationEnabled) return NULL;
+
+    PR_ASSERT(requestedBytes >= 0);
+    PR_ASSERT(_pr_collectorTypes[tix].flags != 0);
+
+#ifdef DEBUG
+    if (_pr_do_a_dump) {
+	/*
+	** Collect, pause for a second (lets finalizer run), and then GC
+	** again.
+	*/
+	PR_GC();
+	PR_Sleep(PR_MicrosecondsToInterval(1000000L));
+	PR_GC();
+	PR_DumpGCHeap(_pr_dump_file, PR_TRUE);
+	_pr_do_a_dump = 0;
+    }
+#endif
+
+#ifdef GC_STATS
+    allocTime = PR_NowMS();
+#endif
+    bytes = (PRInt32) requestedBytes;
+
+    /*
+    ** Align bytes to a multiple of a PRWord, then add in enough space
+    ** to hold the header word.
+    **
+    ** MSVC 1.52 crashed on the ff. code because of the "complex" shifting :-(
+    */
+    bytes = (bytes + PR_BYTES_PER_WORD - 1) >> PR_BYTES_PER_WORD_LOG2;
+    bytes <<= PR_BYTES_PER_WORD_LOG2;
+    bytes += sizeof(PRWord);
+    
+    /*
+     * Add in an extra word of memory for double-aligned memory. Some
+     * percentage of the time this will waste a word of memory (too
+     * bad). Howver, it makes the allocation logic much simpler and
+     * faster.
+     */
+#ifndef IS_64
+    bytes += PR_BYTES_PER_WORD;
+#endif
+
+#ifdef GC_CHECK
+    if (_pr_gcData.flags & GC_CHECK) {
+    /* Bloat the allocation a bit so that we can lay down
+       a check pattern that we will validate */
+    bytes += PR_BYTES_PER_WORD * 2;
+    }
+#endif
+
+#if defined(GC_CHECK) || defined(GC_STATS) || defined(GC_TRACEROOTS)
+    bytes += sizeof(GCBlockEnd);
+#endif
+
+    /* Java can ask for objects bigger than 4M, but it won't get them */
+    /*
+     * This check was added because there is a fundamental limit of
+     * the size field maintained by the gc code.  Going over the 4M
+     * limit caused some bits to roll over into another bit field,
+     * violating the max segment size and causing a bug.
+     */
+    if (bytes >= MAX_ALLOC_SIZE) {
+        return NULL;
+    }
+#ifdef DEBUG
+    if (gc_thrash == -1L
+	? (gc_thrash = (long)PR_GetEnv("GC_THRASH"))
+	: gc_thrash) {
+	PR_GC();
+    }
+#endif
+
+    LOCK_GC();
+#ifdef GC_CHECK
+    if (_pr_gcData.flags & GC_CHECK) {
+    CheckHeap();
+    }
+    allocationCount++;
+#endif
+
+    /* Try default allocation */
+    if ((bytes >= BIG_ALLOC) && (nsegs < MAX_SEGS)) {
+    p = BigAlloc(tix, bytes, 1);
+    } else {
+    p = BinAlloc(tix, bytes, 1);
+    }
+    if (0 == p) {
+#ifdef GC_STATS
+      LL_SUB(ldelta, PR_Now(), allocTime);
+#endif
+      /* Collect some memory */
+      _GCTRACE(GC_ALLOC, ("force GC: want %d", bytes));
+      dogc();
+      PR_ASSERT( GC_IS_LOCKED() );
+
+      /* After a collection we check and see if we should grow the
+     heap. We grow the heap when the amount of memory free is less
+     than a certain percentage of the heap size. We don't check to
+     see if the grow succeeded because our fallback strategy in
+     either case is to try one more time to allocate. */
+      if ((_pr_gcData.allocMemory < _pr_gcData.maxMemory) &&
+      (_pr_gcData.freeMemory <
+       ((_pr_gcData.allocMemory * MIN_FREE_THRESHOLD_AFTER_GC) / 100L))) {
+    GrowHeap(PR_MAX(bytes, segmentSize));
+      }
+#ifdef GC_STATS
+      LL_ADD(allocTime, PR_Now(), ldelta);
+#endif
+
+      /* Try one last time */
+      if ((bytes >= BIG_ALLOC) && (nsegs < MAX_SEGS)) {
+    p = BigAlloc(tix, bytes, 1);
+      } else {
+    p = BinAlloc(tix, bytes, 1);
+      }
+      if (0 == p) {
+    /* Well that lost big time. Memory must be pretty well fragmented */
+    if (!GrowHeap(PR_MAX(bytes, segmentSize))) {
+      goto lost;
+    }
+    p = BinAlloc(tix, bytes, 1);
+    if (0 == p) goto lost;
+      }
+    }
+
+    /* Zero out the portion of the object memory that was used by
+       the GCFreeChunk structure (skip the first word because it
+       was already overwritten by the gc header word) */
+    objBytes = OBJ_BYTES(p[0]);
+    if (objBytes > sizeof(PRWord)) p[1] = 0;
+    if (objBytes > sizeof(PRWord)*2) p[2] = 0;
+
+    METER(meter.allocBytes += bytes);
+    METER(meter.wastedBytes += (bytes - requestedBytes));
+    UNLOCK_GC();
+
+    if (collectorCleanupNeeded) {
+	CollectorCleanup();
+    }
+
+#if defined(GC_CHECK) || defined(GC_STATS) || defined(GC_TRACEROOTS)
+    {
+	GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+	end->check = PR_BLOCK_END;
+    }
+#endif
+#ifdef GC_STATS
+    {
+	PRInt64 now = PR_Now();
+	double delta;
+	PRInt32 bin;
+	GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+
+	end->allocTime = allocTime;
+	LL_SUB(ldelta, now, allocTime);
+	LL_L2D(delta, ldelta);
+	InlineBinNumber(bin, requestedBytes);
+	end->bin = bin;
+	gcstats[bin].nallocs++;
+	gcstats[bin].allocTime += delta;
+	gcstats[bin].allocTimeVariance += delta * delta;
+    }
+#endif
+#ifdef GC_CHECK
+    if (_pr_gcData.flags & GC_CHECK) {
+    /* Place a pattern in the memory that was allocated that was not
+       requested. We will check the pattern later. */
+    char* cp = (char*)(p + 1) + requestedBytes;
+	GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+	char i = (char) 0xff;
+	while (cp < (char*)end) {
+	    *cp++ = i--;
+	}
+	end->requestedBytes = requestedBytes;
+	CheckHeap();
+    }
+#endif
+    return p + 1;
+
+  lost:
+    /* Out of memory */
+    UNLOCK_GC();
+    if (collectorCleanupNeeded) {
+    CollectorCleanup();
+    }
+    return 0;
+}
+
+/************************************************************************/
+
+PR_IMPLEMENT(PRWord) PR_GetObjectHeader(void *ptr) {
+    GCSeg *sp;
+    PRWord *h;
+
+    if (ptr == 0) return 0;
+    sp = InHeap(ptr);
+    if (sp == 0) return 0;
+    h = (PRWord*)FindObject(sp, (PRWord*)ptr);
+    return GC_GET_USER_BITS(h[0]);
+}
+
+PR_IMPLEMENT(PRWord) PR_SetObjectHeader(void *ptr, PRWord newUserBits) {
+    GCSeg *sp;
+    PRWord *h, rv;
+
+    if (ptr == 0) return 0;
+    sp = InHeap(ptr);
+    if (sp == 0) return 0;
+    h = (PRWord*)FindObject(sp, (PRWord*)ptr);
+    rv = GC_GET_USER_BITS(h[0]);
+    h[0] = (h[0] & ~GC_USER_BITS) |
+    ((newUserBits << GC_USER_BITS_SHIFT) & GC_USER_BITS);
+    return rv;
+}
+
+PR_IMPLEMENT(void) PR_InitGC(
+    PRWord flags, PRInt32 initialHeapSize, PRInt32 segSize, PRThreadScope scope)
+{
+    static char firstTime = 1;
+
+    if (!firstTime) return;
+    firstTime = 0;
+
+    _pr_msgc_lm = PR_NewLogModule("msgc");
+    _pr_pageShift = PR_GetPageShift();
+    _pr_pageSize = PR_GetPageSize();
+
+  /* Setup initial heap size and initial segment size */
+  if (0 != segSize) segmentSize = segSize;
+#ifdef DEBUG
+    GC = PR_NewLogModule("GC");
+    {
+    char *ev = PR_GetEnv("GC_SEGMENT_SIZE");
+    if (ev && ev[0]) {
+      PRInt32 newSegmentSize = atoi(ev);
+      if (0 != newSegmentSize) segmentSize = newSegmentSize;
+    }
+    ev = PR_GetEnv("GC_INITIAL_HEAP_SIZE");
+    if (ev && ev[0]) {
+      PRInt32 newInitialHeapSize = atoi(ev);
+      if (0 != newInitialHeapSize) initialHeapSize = newInitialHeapSize;
+    }
+    ev = PR_GetEnv("GC_FLAGS");
+    if (ev && ev[0]) {
+        flags |= atoi(ev);
+    }
+#ifdef GCMETER
+        ev = PR_GetEnv("GC_METER");
+        if (ev && ev[0]) {
+            _pr_gcMeter = atoi(ev);
+        }
+#endif
+    }
+#endif
+  if (0 == initialHeapSize) initialHeapSize = segmentSize;
+  if (initialHeapSize < segmentSize) initialHeapSize = segmentSize;
+
+  _pr_gcData.maxMemory   = MAX_SEGS * segmentSize;
+  _pr_gcData.liveBlock  = ProcessRootBlock;
+  _pr_gcData.livePointer = ProcessRootPointer;
+  _pr_gcData.processRootBlock  = ProcessRootBlock;
+  _pr_gcData.processRootPointer = ProcessRootPointer;
+  _pr_gcData.dumpOutput = NULL;
+
+  PR_INIT_CLIST(&_pr_finalizeableObjects);
+    PR_INIT_CLIST(&_pr_finalQueue);
+    _PR_InitGC(flags);
+
+    /* Create finalizer thread */
+    _PR_CreateFinalizer(scope);
+
+  /* Allocate the initial segment for the heap */
+  minBin = 31;
+  maxBin = 0;
+  GrowHeap(initialHeapSize);
+    PR_RegisterRootFinder(ScanWeakFreeList, "scan weak free list", 0);
+}
+
+/** Added by Vishy for sanity checking a few GC structures **/
+/** Can use SanityCheckGC to debug corrupted GC Heap situations **/
+
+#ifdef DEBUG
+
+static int SegmentOverlaps(int i, int j)
+{
+  return
+    (((segs[i].limit > segs[j].base) && (segs[i].base < segs[j].base)) ||
+     ((segs[j].limit > segs[i].base) && (segs[j].base < segs[i].base)));
+}
+
+static void NoSegmentOverlaps(void)
+{
+  int i,j;
+
+  for (i = 0; i < nsegs; i++)
+    for (j = i+1 ; j < nsegs ; j++)
+      PR_ASSERT(!SegmentOverlaps(i,j));
+}
+
+static void SegInfoCheck(void)
+{
+  int i;
+  for (i = 0 ; i < nsegs ; i++)
+    PR_ASSERT((segs[i].info->hbits) &&
+	      (segs[i].info->hbits == segs[i].hbits) &&
+	      (segs[i].info->base == segs[i].base) &&
+	      (segs[i].info->limit == segs[i].limit));
+}
+
+static void SanityCheckGC()
+{
+  NoSegmentOverlaps();
+  SegInfoCheck();
+}
+
+#endif
+
+#if defined(DEBUG) && defined(WIN32)
+
+extern void *baseaddr;
+extern void *lastaddr;
+
+PR_IMPLEMENT(void)
+PR_PrintGCStats(void)
+{
+    long reportedSegSpace = _pr_gcData.busyMemory + _pr_gcData.freeMemory;
+    char* msg;
+    long largeCount = 0, largeSize = 0;
+    long segCount = 0, segSize = 0;
+    long freeCount = 0, freeSize = 0;
+    GCSeg *sp, *esp;
+    GCSegInfo* si;
+
+    LOCK_GC();
+
+    sp = segs;
+    esp = sp + nsegs;
+    while (sp < esp) {
+    long size = sp->info->limit - sp->info->base;
+    segCount++;
+    segSize += size;
+        if (sp->info->fromMalloc) {
+        largeCount++;
+        largeSize += size;
+    }
+        sp++;
+    }
+
+    si = freeSegs;
+    while (si != NULL) {
+    long size = si->limit - si->base;
+    freeCount++;
+    freeSize += size;
+    si = si->next;
+    }
+    
+    msg = PR_smprintf("\
+# GC Stats:\n\
+#   vm space:\n\
+#     range:      %ld - %ld\n\
+#     size:       %ld\n\
+#   segments:\n\
+#     range:      %ld - %ld\n\
+#     count:      %ld (reported: %ld)\n\
+#     size:       %ld (reported: %ld)\n\
+#     free count: %ld\n\
+#     free size:  %ld\n\
+#     busy objs:  %ld (%ld%%)\n\
+#     free objs:  %ld (%ld%%)\n\
+#   large blocks:\n\
+#     count:      %ld\n\
+#     total size: %ld (%ld%%)\n\
+#     avg size:   %ld\n\
+",
+              /* vm space */
+              (long)baseaddr, (long)lastaddr,
+              (long)lastaddr - (long)baseaddr,
+              /* segments */
+              _pr_gcData.lowSeg, _pr_gcData.highSeg,
+              segCount, nsegs,
+              segSize, reportedSegSpace,
+              freeCount,
+              freeSize,
+              _pr_gcData.busyMemory,
+              (_pr_gcData.busyMemory * 100 / reportedSegSpace),
+              _pr_gcData.freeMemory,
+              (_pr_gcData.freeMemory * 100 / reportedSegSpace),
+              /* large blocks */
+              largeCount,
+              largeSize, (largeSize * 100 / reportedSegSpace),
+              (largeCount ? largeSize / largeCount : 0)
+              );
+    UNLOCK_GC();
+    fprintf(stderr, msg);
+    OutputDebugString(msg);
+    PR_smprintf_free(msg);
+#ifdef GC_STATS
+    PR_PrintGCAllocStats();
+#endif
+}
+#endif
+
+PR_IMPLEMENT(void)
+PR_DumpToFile(char* filename, char* msg, PRFileDumper dump, PRBool detailed)
+{
+    FILE *out;
+    OutputDebugString(msg);
+    out = fopen(filename, "a");
+    if (!out) {
+	char buf[64];
+	PR_ASSERT(strlen(filename) < sizeof(buf) - 16);
+	PR_snprintf(buf, sizeof(buf), "Can't open \"%s\"\n",
+		    filename);
+	OutputDebugString(buf);
+    }
+    else
+    {
+	struct tm *newtime;
+	time_t aclock;
+	int i;
+
+	time(&aclock);
+	newtime = localtime(&aclock);
+	fprintf(out, "%s on %s\n", msg, asctime(newtime));  /* Print current time */
+	dump(out, detailed);
+	fprintf(out, "\n\n");
+	for (i = 0; i < 80; i++)
+	    fprintf(out, "=");
+	fprintf(out, "\n\n");
+	fclose(out);
+    }
+    OutputDebugString(" done\n");
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/unixgc.c b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/unixgc.c
new file mode 100644
index 0000000..cea4225
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/unixgc.c
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prlock.h"
+#include "prlog.h"
+#include "prmem.h"
+#include "gcint.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#define _PR_GC_VMBASE 0x40000000
+
+#if defined(SOLARIS)
+#define _MD_MMAP_FLAGS MAP_SHARED
+#elif defined(RELIANTUNIX)
+#define _MD_MMAP_FLAGS MAP_PRIVATE|MAP_FIXED
+#else
+#define _MD_MMAP_FLAGS MAP_PRIVATE
+#endif
+
+static PRInt32 zero_fd = -1;
+static PRLock *zero_fd_lock = NULL;
+
+void _MD_InitGC(void)
+{
+#ifdef DEBUG
+    /*
+     * Disable using mmap(2) if NSPR_NO_MMAP is set
+     */
+    if (getenv("NSPR_NO_MMAP")) {
+        zero_fd = -2;
+        return;
+    }
+#endif
+    zero_fd = open("/dev/zero",O_RDWR , 0);
+    zero_fd_lock = PR_NewLock();
+}
+
+/* This static variable is used by _MD_GrowGCHeap and _MD_ExtendGCHeap */
+static void *lastaddr = (void*) _PR_GC_VMBASE;
+
+void *_MD_GrowGCHeap(PRUint32 *sizep)
+{
+	void *addr;
+	PRUint32 size;
+
+	size = *sizep;
+
+	PR_Lock(zero_fd_lock);
+	if (zero_fd < 0) {
+		goto mmap_loses;
+	}
+
+	/* Extend the mapping */
+	addr = mmap(lastaddr, size, PROT_READ|PROT_WRITE|PROT_EXEC,
+	    _MD_MMAP_FLAGS,
+	    zero_fd, 0);
+	if (addr == (void*)-1) {
+		zero_fd = -1;
+		goto mmap_loses;
+	}
+	lastaddr = ((char*)addr + size);
+#ifdef DEBUG
+	PR_LOG(_pr_msgc_lm, PR_LOG_WARNING,
+	    ("GC: heap extends from %08x to %08x\n",
+	    _PR_GC_VMBASE,
+	    _PR_GC_VMBASE + (char*)lastaddr - (char*)_PR_GC_VMBASE));
+#endif
+	PR_Unlock(zero_fd_lock);
+	return addr;
+
+mmap_loses:
+	PR_Unlock(zero_fd_lock);
+	return PR_MALLOC(size);
+}
+
+/* XXX - This is disabled.  MAP_FIXED just does not work. */
+#if 0
+PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize) {
+	PRBool rv = PR_FALSE;
+	void* addr;
+	PRInt32 allocSize = newSize - oldSize;
+
+	PR_Lock(zero_fd_lock);
+	addr = mmap(base + oldSize, allocSize, PROT_READ|PROT_WRITE|PROT_EXEC,
+	    _MD_MMAP_FLAGS | MAP_FIXED, zero_fd, 0);
+	if (addr == (void*)-1) {
+		goto loser;
+	}
+	if (addr != (void*) (base + oldSize)) {
+		munmap(base + oldSize, allocSize);
+		goto loser;
+	}
+	lastaddr = ((char*)base + newSize);
+	PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS,
+	    ("GC: heap now extends from %p to %p",
+	    base, base + newSize));
+	rv = PR_TRUE;
+
+loser:
+	PR_Unlock(zero_fd_lock);
+	return rv;
+}
+#else
+PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize) {
+	return PR_FALSE;
+}
+#endif
+
+void _MD_FreeGCSegment(void *base, PRInt32 len)
+{
+	if (zero_fd < 0) {
+		PR_DELETE(base);
+	} else {
+		(void) munmap(base, len);
+	}
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/win32gc.c b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/win32gc.c
new file mode 100644
index 0000000..eec8377
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/src/win32gc.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * GC related routines
+ *
+ */
+#include <windows.h>
+#include "prlog.h"
+
+extern PRLogModuleInfo* _pr_msgc_lm;
+
+#define GC_VMBASE               0x40000000
+#define GC_VMLIMIT              0x00FFFFFF
+
+/************************************************************************/
+/*
+** Machine dependent GC Heap management routines:
+**    _MD_GrowGCHeap
+*/
+/************************************************************************/
+
+void *baseaddr = (void*) GC_VMBASE;
+void *lastaddr = (void*) GC_VMBASE;
+
+void _MD_InitGC() {}
+
+void *_MD_GrowGCHeap(PRUint32 *sizep)
+{
+    void *addr;
+    size_t size;
+
+    /* Reserve a block of memory for the GC */
+    if( lastaddr == baseaddr ) {
+        addr = VirtualAlloc( (void *)GC_VMBASE, GC_VMLIMIT, MEM_RESERVE, PAGE_READWRITE );
+
+        /* 
+        ** If the GC_VMBASE address is already mapped, then let the OS choose a 
+        ** base address that is available...
+        */
+        if (addr == NULL) {
+            addr = VirtualAlloc( NULL, GC_VMLIMIT, MEM_RESERVE, PAGE_READWRITE );
+
+            baseaddr = lastaddr = addr;
+            if (addr == NULL) {
+                PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("GC: unable to allocate heap: LastError=%ld",
+                       GetLastError()));
+                return 0;
+            }
+        }
+    }
+    size = *sizep;
+
+    /* Extend the mapping */
+    addr = VirtualAlloc( lastaddr, size, MEM_COMMIT, PAGE_READWRITE );
+    if (addr == NULL) {
+        return 0;
+    }
+
+    lastaddr = ((char*)addr + size);
+    PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS,
+	   ("GC: heap extends from %08x to %08x",
+	    baseaddr, (long)baseaddr + (char*)lastaddr - (char*)baseaddr));
+
+    return addr;
+}
+
+PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize) {
+  void* addr;
+
+  addr = VirtualAlloc( base + oldSize, newSize - oldSize,
+		       MEM_COMMIT, PAGE_READWRITE );
+  if (NULL == addr) {
+    PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("GC: unable to extend heap: LastError=%ld",
+		     GetLastError()));
+    return PR_FALSE;
+  }
+  if (base + oldSize != (char*)addr) {
+    PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("GC: segment extension returned %x instead of %x",
+		     addr, base + oldSize));
+    VirtualFree(addr, newSize - oldSize, MEM_DECOMMIT);
+    return PR_FALSE;
+  }
+  lastaddr = base + newSize;
+  PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS,
+	 ("GC: heap now extends from %p to %p",
+	  base, base + newSize));
+  return PR_TRUE;
+}
+
+
+void _MD_FreeGCSegment(void *base, PRInt32 len)
+{
+     (void)VirtualFree(base, 0, MEM_RELEASE);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/Makefile.in
new file mode 100644
index 0000000..51031ed
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/Makefile.in
@@ -0,0 +1,270 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifeq ($(OS_TARGET), OS2)
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+endif
+
+CSRCS = gc1.c thrashgc.c
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS) $(OBJS)
+
+INCLUDES = -I$(dist_includedir)
+
+# Setting the variables LDOPTS and LIBPR.  We first initialize
+# them to the default values, then adjust them for some platforms.
+LDOPTS = -L$(dist_libdir)
+NSPR_VERSION = $(MOD_MAJOR_VERSION)
+GC_VERSION = $(MOD_MAJOR_VERSION)
+LIBPR = -lnspr$(NSPR_VERSION)
+LIBPLC = -lplc$(NSPR_VERSION)
+LIBGC = -lmsgc$(GC_VERSION)
+
+ifeq ($(OS_ARCH), WINNT)
+  LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO
+  LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).$(LIB_SUFFIX)
+  LIBPLC = $(dist_libdir)/libplc$(NSPR_VERSION).$(LIB_SUFFIX)
+  LIBGC= $(dist_libdir)/libmsgc$(GC_VERSION).$(LIB_SUFFIX)
+endif
+
+ifeq ($(OS_ARCH),OS2)
+  LDOPTS += -Zomf -Zlinker /PM:VIO
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+LDOPTS += -rpath $(PWD)/$(dist_libdir) -rdata_shared
+
+# For 6.x machines, include this flag
+ifeq ($(basename $(OS_RELEASE)),6)
+ifeq ($(USE_N32),1)
+LDOPTS += -n32
+else
+LDOPTS += -32
+endif
+endif
+
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+# I haven't figured out how to pass -rpath to cc on OSF1 V3.2, so
+# we do static linking.
+ifeq ($(OS_RELEASE), V3.2)
+  LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).a
+  LIBPLC = $(dist_libdir)/libplc$(NSPR_VERSION).a
+  LIBGC = $(dist_libdir)/libmsgc$(GC_VERSION).a
+  EXTRA_LIBS = -lc_r
+else
+  LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+LDOPTS += -z -Wl,+s,+b,$(PWD)/$(dist_libdir)
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib
+ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1)
+LIBPR = -lnspr$(NSPR_VERSION)_shr
+LIBPLC = -lplc$(NSPR_VERSION)_shr
+LIBGC = -lmsgc$(GC_VERSION)_shr
+else
+LDOPTS += -brtl
+EXTRA_LIBS = -ldl
+endif
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+ifneq ($(OS_RELEASE), 4.1.3_U1)
+ifdef NS_USE_GCC
+LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir)
+else
+LDOPTS += -R $(PWD)/$(dist_libdir)
+endif
+endif
+
+# SunOS 5.5 needs to link with -lpthread, even though we already
+# linked with this system library when we built libnspr.so.
+ifeq ($(OS_RELEASE), 5.5)
+ifdef USE_PTHREADS
+EXTRA_LIBS = -lpthread
+endif
+endif
+endif # SunOS
+
+ifeq ($(OS_ARCH),NEC)
+EXTRA_LIBS = $(OS_LIBS)
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), NCR)
+# XXX: We see some strange problems when we link with libnspr.so.
+# So for now we use static libraries on NCR.  The shared library
+# stuff below is commented out.
+LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).a
+LIBPLC = $(dist_libdir)/libplc$(NSPR_VERSION).a
+LIBGC = $(dist_libdir)/libmsgc$(GC_VERSION).a
+EXTRA_LIBS = -lsocket -lnsl -ldl
+
+# NCR needs to link against -lsocket -lnsl (and -lc, which is linked
+# implicitly by $(CC)) again even though we already linked with these
+# system libraries when we built libnspr.so.
+#EXTRA_LIBS = -lsocket -lnsl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+#export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), Linux)
+ifeq ($(OS_RELEASE), 1.2)
+EXTRA_LIBS = -ldl
+endif
+endif
+
+ifeq ($(OS_ARCH), SCOOS)
+# SCO Unix needs to link against -lsocket again even though we
+# already linked with these system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH),SINIX)
+EXTRA_LIBS = -lsocket -lnsl -lresolv -ldl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH),BSD_OS)
+EXTRA_LIBS = -ldl
+endif
+
+ifeq ($(OS_ARCH),DGUX)
+EXTRA_LIBS = -lsocket -lnsl -ldl
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifneq ($(OS_RELEASE),4.2)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to 
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+	rm -f $@ $(AIX_TMP)
+	$(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(NSPR_VERSION).a
+	$(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+	rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+ifeq ($(OS_ARCH), WINNT)
+	link $(LDOPTS) $< $(LIBGC) $(LIBPLC) $(LIBPR) wsock32.lib -out:$@
+else
+ifeq ($(OS_ARCH),OS2)
+	$(LINK) $(LDOPTS) $< $(LIBGC) $(LIBPLC) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS) -o $@
+else
+	$(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBGC) $(LIBPLC) $(LIBPR) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/gc1.c b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/gc1.c
new file mode 100644
index 0000000..9bd485e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/gc1.c
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prgc.h"
+#include "prinit.h"
+#include "prmon.h"
+#include "prinrval.h"
+#include "private/pprthred.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static PRMonitor *mon;
+static PRInt32 threads, waiting, iterations;
+static PRInt32 scanCount, finalizeCount, freeCount;
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+typedef struct Array {
+    PRUintn size;
+    void *body[1];
+} Array;
+
+int arrayTypeIndex;
+
+static void PR_CALLBACK ScanArray(void *a)
+{
+/*	printf ("In ScanArray a = %X size = %d \n", a, a->size); */
+	scanCount++;
+}
+
+static void PR_CALLBACK FinalizeArray(void *a)
+{
+/*	printf ("In FinalizeArray a = %X size = %d \n", a, a->size); */	
+	finalizeCount++;
+}
+
+static void PR_CALLBACK FreeArray(void *a)
+{
+/*	printf ("In FreeArray\n");	*/
+	freeCount++;
+}
+
+static Array *NewArray(PRUintn size)
+{
+    Array *a;
+
+    a = (Array *)PR_AllocMemory(sizeof(Array) + size*sizeof(void*) - 1*sizeof(void*),
+                       arrayTypeIndex, PR_ALLOC_CLEAN);
+
+/*	printf ("In NewArray a = %X \n", a); */	
+
+    if (a)
+        a->size = size;
+    return a;
+}
+
+GCType arrayType = {
+    ScanArray,
+    FinalizeArray,
+    0,
+    0,
+    FreeArray,
+    0
+};
+
+static void Initialize(void)
+{
+    PR_InitGC(0, 0, 0, PR_GLOBAL_THREAD);
+    arrayTypeIndex = PR_RegisterType(&arrayType);
+}
+
+static void PR_CALLBACK AllocateLikeMad(void *arg)
+{
+    Array *prev;
+    PRInt32 i;
+	PRInt32 count;
+
+	count = (PRInt32)arg;
+    prev = 0;
+    for (i = 0; i < count; i++) {
+        Array *leak = NewArray(i & 511);
+        if ((i & 1023) == 0) {
+            prev = 0;                   /* forget */
+        } else {
+            if (i & 1) {
+                prev = leak;            /* remember */
+            }
+        }
+    }
+    PR_EnterMonitor(mon);
+    waiting++;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+}
+
+int main(int argc, char **argv)
+{
+    PRIntervalTime start, stop, usec;
+    double d;
+    PRIntn i, totalIterations;
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");
+
+	threads = 10;
+	iterations = 100;
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) {
+            fprintf(stderr, "Invalid command-line option\n");
+            exit(1);
+        }
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 't':  /* number of threads */
+            threads = atoi(opt->value);
+            break;
+        case 'c':  /* iteration count */
+            iterations = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    fprintf(stderr, "t is %ld, i is %ld\n", (long) threads, (long) iterations);
+	/* main test */
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 5);
+    PR_STDIO_INIT();
+    Initialize();
+
+    /* Spin all of the allocator threads and then wait for them to exit */
+    start = PR_IntervalNow();
+    mon = PR_NewMonitor();
+    PR_EnterMonitor(mon);
+    waiting = 0;
+    for (i = 0; i < threads; i++) {
+        (void) PR_CreateThreadGCAble(PR_USER_THREAD,
+                               AllocateLikeMad, (void*)iterations,
+						      PR_PRIORITY_NORMAL,
+						      PR_LOCAL_THREAD,
+		    				  PR_UNJOINABLE_THREAD,
+						      0);
+    }
+    while (waiting != threads) {
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_ExitMonitor(mon);
+
+	PR_GC();
+	PR_ForceFinalize();	
+
+	totalIterations = iterations * threads;
+/*
+	if (scanCount != totalIterations)
+		printf ("scanCount discrepancy scanCount = %d totalIterations = %d \n", 
+			scanCount, totalIterations);
+	if (freeCount != totalIterations)
+		printf ("freeCount discrepancy freeCount = %d totalIterations = %d \n", 
+			freeCount, totalIterations);
+	if ((finalizeCount != totalIterations) && (finalizeCount != (totalIterations-1)))
+		printf ("finalizeCount discrepancy finalizeCount = %d totalIterations = %d \n", 
+			finalizeCount,totalIterations);
+*/
+
+    stop = PR_IntervalNow();
+    
+    usec = stop = stop - start;
+    d = (double)usec;
+
+    if (debug_mode) printf("%40s: %6.2f usec\n", "GC allocation", d / (iterations * threads));
+	else {
+		if (d == 0.0) failed_already = PR_TRUE;
+
+	}
+
+    PR_Cleanup();
+	if(failed_already)	
+	{
+	    printf("FAIL\n");
+		return 1;
+	}
+	else
+	{
+	    printf("PASS\n");
+		return 0;
+	}
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/thrashgc.c b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/thrashgc.c
new file mode 100644
index 0000000..a440d49
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/msgc/tests/thrashgc.c
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+** Name: thrashgc
+**
+** Description: test garbace collection functions.
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+#include "prthread.h"
+#include "prgc.h"
+#include "prprf.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prinit.h"
+#include "prcvar.h"
+
+#include "private/pprthred.h"
+
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static char* progname;
+static PRInt32 loops = 1000;
+static int tix1, tix2, tix3;
+static GCInfo* gcInfo;
+static PRLock* stderrLock;
+
+typedef struct Type1 Type1;
+typedef struct Type2 Type2;
+
+struct Type1 {
+  Type2* atwo;
+  Type1* next;
+};
+
+struct Type2 {
+  void* buf;
+};
+
+static void PR_CALLBACK ScanType1(void *obj) {
+  gcInfo->livePointer(((Type1 *)obj)->atwo);
+  gcInfo->livePointer(((Type1 *)obj)->next);
+}
+
+static void PR_CALLBACK ScanType2(void *obj) {
+  gcInfo->livePointer(((Type2 *)obj)->buf);
+}
+
+static GCType type1 = {
+    ScanType1
+};
+
+static GCType type2 = {
+    ScanType2
+/*  (void (*)(void*)) ScanType2 */
+};
+
+static GCType type3 = {
+  0
+};
+
+Type1* NewType1(void) {
+    Type1* p = (Type1*) PR_AllocMemory(sizeof(Type1), tix1, PR_ALLOC_DOUBLE);
+    PR_ASSERT(p != NULL);
+    return p;
+}
+
+Type2* NewType2(void) {
+    Type2* p = (Type2*) PR_AllocMemory(sizeof(Type2), tix2, PR_ALLOC_DOUBLE);
+    PR_ASSERT(p != NULL);
+    return p;
+}
+
+void* NewBuffer(PRInt32 size) {
+    void* p = PR_AllocMemory(size, tix3, PR_ALLOC_DOUBLE);
+    PR_ASSERT(p != NULL);
+    return p;
+}
+
+/* Allocate alot of garbage */
+static void PR_CALLBACK AllocStuff(void *unused) {
+  PRInt32 i;
+  void* danglingRefs[50];
+  PRIntervalTime start, end;
+  char msg[100];
+
+  start = PR_IntervalNow();
+  for (i = 0; i < loops; i++) {
+    void* p;
+    if (i & 1) {
+      Type1* t1 = NewType1();
+      t1->atwo = NewType2();
+      t1->next = NewType1();
+      t1->atwo->buf = NewBuffer(100);
+      p = t1;
+    } else {
+      Type2* t2 = NewType2();
+      t2->buf = NewBuffer(i & 16383);
+      p = t2;
+    }
+    if ((i % 10) == 0) {
+      memmove(&danglingRefs[0], &danglingRefs[1], 49*sizeof(void*));
+      danglingRefs[49] = p;
+    }
+  }
+  end = PR_IntervalNow();
+  if (debug_mode) PR_snprintf(msg, sizeof(msg), "Thread %p: %ld allocations took %ld ms",
+	      PR_GetCurrentThread(), loops,
+	      PR_IntervalToMilliseconds((PRIntervalTime) (end - start)));
+  PR_Lock(stderrLock);
+  fprintf(stderr, "%s\n", msg);
+  PR_Unlock(stderrLock);
+  }
+
+static void usage(char *progname) {
+  fprintf(stderr, "Usage: %s [-t threads] [-l loops]\n", progname);
+  exit(-1);
+}
+
+static int realMain(int argc, char **argv, char *notused) {
+  int i;
+  int threads = 0;
+
+  progname = strrchr(argv[0], '/');
+  if (progname == 0) progname = argv[0];
+  for (i = 1; i < argc; i++) {
+    if (strcmp(argv[i], "-t") == 0) {
+      if (i == argc - 1) {
+	usage(progname);
+      }
+      threads = atoi(argv[++i]);
+      if (threads < 0) threads = 0;
+      if (threads > 10000) threads = 10000;
+      continue;
+    }
+    if (strcmp(argv[i], "-l") == 0) {
+      if (i == argc - 1) {
+	usage(progname);
+      }
+      loops = atoi(argv[++i]);
+      continue;
+    }
+    usage(progname);
+  }
+
+  for (i = 0; i < threads; i++) {
+    PRThread* thread;
+
+    /* XXXXX */
+    thread = PR_CreateThreadGCAble(PR_USER_THREAD,  /* thread type */
+			     AllocStuff,  /* start function */
+			     NULL,  /* arg */
+			     PR_PRIORITY_NORMAL,  /* priority */
+			     PR_LOCAL_THREAD,  /* thread scope */
+			     PR_UNJOINABLE_THREAD,  /* thread state */
+			     0);   /* stack size */
+    if (thread == 0) {
+      fprintf(stderr, "%s: no more threads (only %d were created)\n",
+	      progname, i);
+      break;
+    }
+  }
+  AllocStuff(NULL);
+  return 0;
+}
+
+static int padMain(int argc, char **argv) {
+  char pad[512];
+  return realMain(argc, argv, pad);
+}
+
+int main(int argc, char **argv) {
+  int rv;
+
+  debug_mode = 1;
+  
+  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+  PR_SetThreadGCAble();
+
+  PR_InitGC(0, 0, 0, PR_GLOBAL_THREAD);
+  PR_STDIO_INIT();
+  stderrLock = PR_NewLock();
+  tix1 = PR_RegisterType(&type1);
+  tix2 = PR_RegisterType(&type2);
+  tix3 = PR_RegisterType(&type3);
+  gcInfo = PR_GetGCInfo();
+  rv = padMain(argc, argv);
+  printf("PASS\n");
+  PR_Cleanup();
+  return rv;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/Makefile.in
new file mode 100644
index 0000000..b41f199
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/Makefile.in
@@ -0,0 +1,200 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+# Disable optimization of the nspr on SunOS4.1.3
+ifeq ($(OS_ARCH),SunOS)
+    ifeq ($(OS_RELEASE),4.1.3_U1)
+        OPTIMIZER =
+    else
+        # The C++ compiler in Workshop 5.0 uses standard
+        # iostreams as default.  -library=iostream will
+        # allow Workshop 5.0 to work with classic iostreams.
+        ifndef NS_USE_GCC
+        CCC_VERSION := $(shell $(CCC) -V 2>&1)
+        ifneq (,$(findstring 5.0,$(CCC_VERSION)))
+        CCC_ONLY_FLAGS += -library=iostream
+        endif
+        endif
+    endif
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+    ifneq ($(OS_RELEASE),5.3)
+        CCC_ONLY_FLAGS += -exceptions
+    endif
+endif
+
+ifeq ($(OS_ARCH), BeOS)
+    CFLAGS += -frtti -fexceptions
+endif
+
+INCLUDES = -I$(dist_includedir)
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+CSRCS = \
+	plvrsion.c \
+	$(NULL)
+
+CXXSRCS = \
+	prstrms.cpp \
+	$(NULL)
+
+OBJS = $(addprefix $(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)) $(CXXSRCS:.cpp=.$(OBJ_SUFFIX)))
+
+ifeq ($(OS_ARCH), WINNT)
+        RES=$(OBJDIR)/prstrms.res
+        RESNAME=prstrms.rc
+        OS_LIBS = user32.lib
+else
+    ifeq ($(OS_ARCH),OS2)
+        OS_LIBS = -lstdcpp
+    else
+    ifeq ($(OS_ARCH), AIX)
+      ifeq ($(OS_RELEASE), 4.1)
+        ifeq ($(CLASSIC_NSPR),1)
+            OS_LIBS += -lC -lc
+        else
+            OS_LIBS += -lC_r -lc_r
+        endif
+      else
+        # makeC++SharedLib(_r) is in either /usr/lpp/xlC/bin
+        # or /usr/ibmcxx/bin.
+        ifeq ($(CLASSIC_NSPR),1)
+            MKSHLIB = makeC++SharedLib -p 0
+        else
+            MKSHLIB = makeC++SharedLib_r -p 0
+        endif
+        OS_LIBS += -ldl
+      endif
+    endif
+    endif
+endif
+
+ifeq ($(OS_ARCH),BeOS)
+    OS_LIBS = -lstdc++.r4
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+    OS_LIBS += -lC
+endif
+
+EXTRA_LIBS = $(LIBNSPR)
+
+# On NCR and SCOOS, we can't link with extra libraries when
+# we build a shared library.  If we do so, the linker doesn't
+# complain, but we would run into weird problems at run-time.
+# Therefore on these platforms, we link just the object files.
+ifeq ($(OS_ARCH),NCR)
+    EXTRA_LIBS =
+endif
+ifeq ($(OS_ARCH),SCOOS)
+    EXTRA_LIBS =
+endif
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+LIBRARY_NAME    = prstrms
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+RELEASE_LIBS    = $(TARGETS)
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+TINC = $(OBJDIR)/_pl_bld.h
+PROD = $(notdir $(SHARED_LIBRARY))
+NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
+SH_DATE = $(shell date "+%Y-%m-%d %T")
+SH_NOW = $(shell $(NOW))
+
+ifeq ($(OS_ARCH), WINNT)
+	SUF = i64
+else
+	SUF = LL
+endif
+
+$(TINC):
+	@$(MAKE_OBJDIR)
+	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+	@if test ! -z "$(SH_NOW)"; then \
+	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+	else \
+	    true; \
+	fi
+	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
+
+
+$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+ifeq ($(OS_ARCH), WINNT)
+	$(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+	$(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+endif
+#
+# Version information generation (end)
+#
+
+export:: $(TARGETS) $(HEADERS)
+	$(INSTALL) -m 444 $(HEADERS) $(dist_includedir)
+	$(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifeq ($(OS_ARCH),OS2)
+	$(INSTALL) -m 444 $(TARGETS) $(dist_bindir)
+endif
+ifeq ($(OS_ARCH),HP-UX)
+ifdef SHARED_LIBRARY
+	$(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir)
+endif
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/plvrsion.c b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/plvrsion.c
new file mode 100644
index 0000000..87b62e7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/plvrsion.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prvrsion.h"
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+#include "_pl_bld.h"
+#if !defined(_BUILD_TIME)
+#ifdef HAVE_LONG_LONG
+#define _BUILD_TIME 0
+#else
+#define _BUILD_TIME {0, 0}
+#endif
+#endif
+#if !defined(_BUILD_STRING)
+#define _BUILD_STRING ""
+#endif
+#if !defined(_PRODUCTION)
+#define _PRODUCTION ""
+#endif
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * 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 */
+#if defined(DEBUG)
+    /* debug            */  PR_TRUE,            /* a debug build */
+#else
+    /* debug            */  PR_FALSE,           /* an optomized build */
+#endif
+    /* special          */  PR_FALSE,           /* they're all special, but ... */
+    /* filename         */  _PRODUCTION,        /* the produced library name */
+    /* description      */ "Portable runtime",  /* what we are */
+    /* security         */ "N/A",               /* not applicable here */
+    /* copywrite        */  "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved",
+    /* comment          */  "http://www.mozilla.org/MPL/",
+    /* specialString    */ ""
+};
+
+#ifdef XP_UNIX
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING
+        "  " _BUILD_STRING " $";
+static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
+        "  " _BUILD_STRING;
+
+#endif /* XP_UNIX */
+
+PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
+{
+#ifdef XP_UNIX
+    /*
+     * 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 &VERSION_DESC_NAME;
+}  /* versionEntryPointType */
+
+/* plvrsion.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.cpp b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.cpp
new file mode 100644
index 0000000..9f709c0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.cpp
@@ -0,0 +1,546 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Robin J. Maxwell 11-22-96
+ */
+
+#include "prstrms.h"
+#include <string.h> // memmove
+
+//
+// Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C.
+//
+// _PRSTR_BP is the protected member of class ios that is returned
+// by the public method rdbuf().
+//
+// _PRSTR_DELBUF is the method or data member of class ios, if available,
+// with which we can ensure that the ios destructor does not delete
+// the associated streambuf.  If such a method or data member does not
+// exist, define _PRSTR_DELBUF to be empty.
+//
+// _PRSTR_DELBUF_C is just _PRSTR_DELBUF qualified by a base class.
+//
+
+#if defined(__GNUC__)
+#define _PRSTR_BP _strbuf
+#define _PRSTR_DELBUF(x)    /* as nothing */
+#define _PRSTR_DELBUF_C(c, x)  /* as nothing */
+#elif defined(WIN32)
+#define _PRSTR_BP bp
+#define _PRSTR_DELBUF(x)	delbuf(x)
+#define _PRSTR_DELBUF_C(c, x)	c::_PRSTR_DELBUF(x)
+#elif defined(OSF1)
+#define _PRSTR_BP m_psb
+#define _PRSTR_DELBUF(x) /* as nothing */
+#define _PRSTR_DELBUF_C(c, x)	/* as nothing */
+#elif defined(QNX)
+#define PRFSTREAMS_BROKEN
+#else
+#define _PRSTR_BP bp
+// Unix compilers don't believe in encapsulation
+// At least on Solaris this is also ignored
+#define _PRSTR_DELBUF(x)	delbuf = x
+#define _PRSTR_DELBUF_C(c, x)	c::_PRSTR_DELBUF(x)
+#endif
+
+const PRIntn STRM_BUFSIZ = 8192;
+
+#if !defined (PRFSTREAMS_BROKEN)   
+
+PRfilebuf::PRfilebuf():
+_fd(0),
+_opened(PR_FALSE),
+_allocated(PR_FALSE)
+{
+}
+
+PRfilebuf::PRfilebuf(PRFileDesc *fd):
+streambuf(),
+_fd(fd),
+_opened(PR_FALSE),
+_allocated(PR_FALSE)
+{
+}
+
+PRfilebuf::PRfilebuf(PRFileDesc *fd, char * buffptr, int bufflen):
+_fd(fd),
+_opened(PR_FALSE),
+_allocated(PR_FALSE)
+{
+    PRfilebuf::setbuf(buffptr, bufflen);
+}
+
+PRfilebuf::~PRfilebuf()
+{
+    if (_opened){
+        close();
+    }else
+        sync();
+	if (_allocated)
+		delete base();
+}
+
+PRfilebuf*	
+PRfilebuf::open(const char *name, int mode, int flags)
+{
+     if (_fd != 0)
+        return 0;    // error if already open
+     PRIntn PRmode = 0;
+    // translate mode argument
+    if (!(mode & ios::nocreate))
+        PRmode |= PR_CREATE_FILE;
+    //if (mode & ios::noreplace)
+    //    PRmode |= O_EXCL;
+    if (mode & ios::app){
+        mode |= ios::out;
+        PRmode |= PR_APPEND;
+    }
+    if (mode & ios::trunc){
+        mode |= ios::out;  // IMPLIED
+        PRmode |= PR_TRUNCATE;
+    }
+    if (mode & ios::out){
+        if (mode & ios::in)
+            PRmode |= PR_RDWR;
+        else
+            PRmode |= PR_WRONLY;
+        if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace))){
+            mode |= ios::trunc; // IMPLIED
+            PRmode |= PR_TRUNCATE;
+        }
+    }else if (mode & ios::in)
+        PRmode |= PR_RDONLY;
+    else
+        return 0;    // error if not ios:in or ios::out
+
+
+    //
+    // The usual portable across unix crap...
+    // NT gets a hokey piece of junk layer that prevents
+    // access to the API.
+#ifdef WIN32
+    _fd = PR_Open(name, PRmode, PRmode);
+#else
+    _fd = PR_Open(name, PRmode, flags);
+#endif
+    if (_fd == 0)
+        return 0;
+    _opened = PR_TRUE;
+    if ((!unbuffered()) && (!ebuf())){
+        char * sbuf = new char[STRM_BUFSIZ];
+        if (!sbuf)
+            unbuffered(1);
+        else{
+			_allocated = PR_TRUE;
+            streambuf::setb(sbuf,sbuf+STRM_BUFSIZ,0);
+		}
+    }
+    if (mode & ios::ate){
+        if (seekoff(0,ios::end,mode)==EOF){
+            close();
+            return 0;
+        }
+    }
+    return this;
+}
+
+PRfilebuf*	
+PRfilebuf::attach(PRFileDesc *fd)
+{
+    _opened = PR_FALSE;
+    _fd = fd;
+    return this;
+}
+
+int	
+PRfilebuf::overflow(int c)
+{
+    if (allocate()==EOF)        // make sure there is a reserve area
+        return EOF;
+    if (PRfilebuf::sync()==EOF) // sync before new buffer created below
+        return EOF;
+
+    if (!unbuffered())
+        setp(base(),ebuf());
+
+    if (c!=EOF){
+        if ((!unbuffered()) && (pptr() < epptr())) // guard against recursion
+            sputc(c);
+        else{
+            if (PR_Write(_fd, &c, 1)!=1)
+                return(EOF);
+        }
+    }
+    return(1);  // return something other than EOF if successful
+}
+
+int	
+PRfilebuf::underflow()
+{
+    int count;
+    unsigned char tbuf;
+
+    if (in_avail())
+        return (int)(unsigned char) *gptr();
+
+    if (allocate()==EOF)        // make sure there is a reserve area
+        return EOF;
+    if (PRfilebuf::sync()==EOF)
+        return EOF;
+
+    if (unbuffered())
+        {
+        if (PR_Read(_fd,(void *)&tbuf,1)<=0)
+            return EOF;
+        return (int)tbuf;
+        }
+
+    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, PRstreambuflen bufflen)
+{
+    if (is_open() && (ebuf()))
+        return 0;
+    if ((!buffptr) || (bufflen <= 0))
+        unbuffered(1);
+    else
+        setb(buffptr, buffptr+bufflen, 0);
+    return this;
+}
+
+streampos	
+PRfilebuf::seekoff(streamoff offset, ios::seek_dir dir, int /* mode */)
+{
+    if (PR_GetDescType(_fd) == PR_DESC_FILE){
+        PRSeekWhence fdir;
+        PRInt32 retpos;
+        switch (dir) {
+            case ios::beg :
+                fdir = PR_SEEK_SET;
+                break;
+            case ios::cur :
+                fdir = PR_SEEK_CUR;
+                break;
+            case ios::end :
+                fdir = PR_SEEK_END;
+                break;
+            default:
+            // error
+                return(EOF);
+            }
+
+        if (PRfilebuf::sync()==EOF)
+            return EOF;
+        if ((retpos=PR_Seek(_fd, offset, fdir))==-1L)
+            return (EOF);
+        return((streampos)retpos);
+    }else
+        return (EOF);
+}
+
+
+int 
+PRfilebuf::sync()
+{
+    PRInt32 count; 
+
+    if (_fd==0)
+        return(EOF);
+
+    if (!unbuffered()){
+        // Sync write area
+        if ((count=out_waiting())!=0){
+            PRInt32 nout;
+            if ((nout =PR_Write(_fd,
+                               (void *) pbase(),
+                               (unsigned int)count)) != count){
+                if (nout > 0) {
+                    // should set _pptr -= nout
+                    pbump(-(int)nout);
+                    memmove(pbase(), pbase()+nout, (int)(count-nout));
+                }
+                return(EOF);
+            }
+        }
+        setp(0,0); // empty put area
+
+        if (PR_GetDescType(_fd) == PR_DESC_FILE){
+            // Sockets can't seek; don't need this
+            if ((count=in_avail()) > 0){
+                if (PR_Seek(_fd, -count, PR_SEEK_CUR)!=-1L)
+                {
+                    return (EOF);
+                }
+            }
+        }
+        setg(0,0,0); // empty get area
+    }
+    return(0);
+}
+
+PRfilebuf * 
+PRfilebuf::close()
+{
+    int retval;
+    if (_fd==0)
+        return 0;
+
+    retval = sync();
+
+    if ((PR_Close(_fd)==0) || (retval==EOF))
+        return 0;
+    _fd = 0;
+    return this;
+}
+
+PRifstream::PRifstream():
+istream(new PRfilebuf)
+{
+    _PRSTR_DELBUF(0);
+}
+
+PRifstream::PRifstream(PRFileDesc *fd):
+istream(new PRfilebuf(fd))
+{
+    _PRSTR_DELBUF(0);
+}
+
+PRifstream::PRifstream(PRFileDesc *fd, char *buff, int bufflen):
+istream(new PRfilebuf(fd, buff, bufflen))
+{
+    _PRSTR_DELBUF(0);
+}
+
+PRifstream::PRifstream(const char * name, int mode, int flags):
+istream(new PRfilebuf)
+{
+    _PRSTR_DELBUF(0);
+    if (!rdbuf()->open(name, (mode|ios::in), flags))
+        clear(rdstate() | ios::failbit);
+}
+
+PRifstream::~PRifstream()
+{
+	sync();
+
+	delete rdbuf();
+#ifdef _PRSTR_BP
+	_PRSTR_BP = 0;
+#endif
+}
+
+streambuf * 
+PRifstream::setbuf(char * ptr, int len)
+{
+    if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
+        clear(rdstate() | ios::failbit);
+        return 0;
+    }
+    return rdbuf();
+}
+
+void 
+PRifstream::attach(PRFileDesc *fd)
+{
+    if (!(rdbuf()->attach(fd)))
+        clear(rdstate() | ios::failbit);
+}
+
+void 
+PRifstream::open(const char * name, int mode, int flags)
+{
+    if (is_open() || !(rdbuf()->open(name, (mode|ios::in), flags)))
+        clear(rdstate() | ios::failbit);
+}
+
+void 
+PRifstream::close()
+{
+    clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
+}
+
+PRofstream::PRofstream():
+ostream(new PRfilebuf)
+{
+    _PRSTR_DELBUF(0);
+}
+
+PRofstream::PRofstream(PRFileDesc *fd):
+ostream(new PRfilebuf(fd))
+{
+    _PRSTR_DELBUF(0);
+}
+
+PRofstream::PRofstream(PRFileDesc *fd, char *buff, int bufflen):
+ostream(new PRfilebuf(fd, buff, bufflen))
+{
+    _PRSTR_DELBUF(0);
+}
+
+PRofstream::PRofstream(const char *name, int mode, int flags):
+ostream(new PRfilebuf)
+{
+    _PRSTR_DELBUF(0);
+    if (!rdbuf()->open(name, (mode|ios::out), flags))
+        clear(rdstate() | ios::failbit);
+}
+
+PRofstream::~PRofstream()
+{
+	flush();
+
+	delete rdbuf();
+#ifdef _PRSTR_BP
+	_PRSTR_BP = 0;
+#endif
+}
+
+streambuf * 
+PRofstream::setbuf(char * ptr, int len)
+{
+    if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
+        clear(rdstate() | ios::failbit);
+        return 0;
+    }
+    return rdbuf();
+}
+
+void 
+PRofstream::attach(PRFileDesc *fd)
+{
+    if (!(rdbuf()->attach(fd)))
+        clear(rdstate() | ios::failbit);
+}
+
+void 
+PRofstream::open(const char * name, int mode, int flags)
+{
+    if (is_open() || !(rdbuf()->open(name, (mode|ios::out), flags)))
+        clear(rdstate() | ios::failbit);
+}
+
+void 
+PRofstream::close()
+{
+    clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
+}
+
+PRfstream::PRfstream():
+iostream(new PRfilebuf)
+{
+	_PRSTR_DELBUF_C(istream, 0);
+	_PRSTR_DELBUF_C(ostream, 0);
+}
+
+PRfstream::PRfstream(PRFileDesc *fd):
+iostream(new PRfilebuf(fd))
+{
+	_PRSTR_DELBUF_C(istream, 0);
+	_PRSTR_DELBUF_C(ostream, 0);
+}
+
+PRfstream::PRfstream(PRFileDesc *fd, char *buff, int bufflen):
+iostream(new PRfilebuf(fd, buff, bufflen))
+{
+	_PRSTR_DELBUF_C(istream, 0);
+	_PRSTR_DELBUF_C(ostream, 0);
+}
+
+PRfstream::PRfstream(const char *name, int mode, int flags):
+iostream(new PRfilebuf)
+{
+	_PRSTR_DELBUF_C(istream, 0);
+	_PRSTR_DELBUF_C(ostream, 0);
+    if (!rdbuf()->open(name, (mode|(ios::in|ios::out)), flags))
+        clear(rdstate() | ios::failbit);
+}
+
+PRfstream::~PRfstream()
+{
+	sync();
+	flush();
+
+	delete rdbuf();
+#ifdef _PRSTR_BP
+	istream::_PRSTR_BP = 0;
+	ostream::_PRSTR_BP = 0;
+#endif
+}
+
+streambuf * 
+PRfstream::setbuf(char * ptr, int len)
+{
+    if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
+        clear(rdstate() | ios::failbit);
+        return 0;
+    }
+    return rdbuf();
+}
+
+void 
+PRfstream::attach(PRFileDesc *fd)
+{
+    if (!(rdbuf()->attach(fd)))
+        clear(rdstate() | ios::failbit);
+}
+
+void 
+PRfstream::open(const char * name, int mode, int flags)
+{
+    if (is_open() || !(rdbuf()->open(name, (mode|(ios::in|ios::out)), flags)))
+        clear(rdstate() | ios::failbit);
+}
+
+void 
+PRfstream::close()
+{
+    clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
+}
+
+#else
+
+// fix it sometime
+
+int fix_prfstreams ()	{	return 0; }
+
+#endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.h b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.h
new file mode 100644
index 0000000..a6752fc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.h
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Robin J. Maxwell 11-22-96
+ */
+
+#ifndef _PRSTRMS_H
+#define _PRSTRMS_H
+
+#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
+
+#else
+
+class PR_IMPLEMENT(PRfilebuf): public streambuf
+{
+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, 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;}
+
+private:
+    PRFileDesc * _fd;
+    PRBool _opened;
+	PRBool _allocated;
+};
+
+class PR_IMPLEMENT(PRifstream): public istream {
+public:
+	PRifstream();
+	PRifstream(const char *, int mode=ios::in, int flags = 0);
+	PRifstream(PRFileDesc *);
+	PRifstream(PRFileDesc *, char *, int);
+	~PRifstream();
+
+	streambuf * setbuf(char *, int);
+	PRfilebuf* rdbuf(){return (PRfilebuf*) ios::rdbuf(); }
+
+	void attach(PRFileDesc *fd);
+	PRFileDesc *fd() {return rdbuf()->fd();}
+
+	int is_open(){return rdbuf()->is_open();}
+	void open(const char *, int mode=ios::in, int flags= 0);
+	void close();
+};
+
+class PR_IMPLEMENT(PRofstream) : public ostream {
+public:
+	PRofstream();
+	PRofstream(const char *, int mode=ios::out, int flags = 0);
+	PRofstream(PRFileDesc *);
+	PRofstream(PRFileDesc *, char *, int);
+	~PRofstream();
+
+	streambuf * setbuf(char *, int);
+	PRfilebuf* rdbuf() { return (PRfilebuf*) ios::rdbuf(); }
+
+	void attach(PRFileDesc *);
+	PRFileDesc *fd() {return rdbuf()->fd();}
+
+	int is_open(){return rdbuf()->is_open();}
+	void open(const char *, int =ios::out, int = 0);
+	void close();
+};
+	
+class PR_IMPLEMENT(PRfstream) : public iostream {
+public:
+	PRfstream();
+	PRfstream(const char *name, int mode, int flags= 0);
+	PRfstream(PRFileDesc *fd);
+	PRfstream(PRFileDesc *fd, char *buff, int bufflen);
+	~PRfstream();
+
+	streambuf * setbuf(char *, int);
+	PRfilebuf* rdbuf(){ return (PRfilebuf*) ostream::rdbuf(); }
+
+	void attach(PRFileDesc *);
+	PRFileDesc *fd() { return rdbuf()->fd(); }
+
+	int is_open() { return rdbuf()->is_open(); }
+	void open(const char *, int, int = 0);
+	void close();
+};
+
+#endif
+
+#endif /* _PRSTRMS_H */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.rc b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.rc
new file mode 100644
index 0000000..aff3bde
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/prstrms.rc
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#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
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+        BEGIN
+            VALUE "CompanyName", "Mozilla Foundation\0"
+            VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+            VALUE "FileVersion", PR_VERSION "\0"
+            VALUE "InternalName", MY_INTERNAL_NAME "\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
+    END
+END
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in
new file mode 100644
index 0000000..3089367
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in
@@ -0,0 +1,220 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+CXXSRCS =           \
+	testprstrm.cpp    \
+	$(NULL)
+
+OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX)))
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CXXSRCS:.cpp=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS) $(OBJS)
+
+INCLUDES = -I$(dist_includedir)
+
+# Setting the variables LDOPTS and LIBPR.  We first initialize
+# them to the default values, then adjust them for some platforms.
+LDOPTS = -L$(dist_libdir)
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)
+LIBPRSTRMS = -lprstrms$(MOD_MAJOR_VERSION)
+
+ifeq ($(OS_ARCH), WINNT)
+  LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO
+  ifeq ($(OS_TARGET), WIN95)
+    LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+    LIBPRSTRMS = $(dist_libdir)/prstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  else
+    LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+    LIBPRSTRMS = $(dist_libdir)/libprstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+LDOPTS += -Zomf -Zlinker /PM:VIO -lstdcpp
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir)
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib
+ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1)
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr
+LIBPRSTRMS = -lprstrms$(MOD_MAJOR_VERSION)_shr
+else
+LDOPTS += -brtl
+EXTRA_LIBS = -ldl
+endif
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+ifneq ($(OS_RELEASE), 4.1.3_U1)
+ifdef NS_USE_GCC
+LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir)
+else
+LDOPTS += -R $(PWD)/$(dist_libdir)
+# CC on SunOS 5.5.x needs to link with -lpthread even though we already
+# linked with this system library when we built libnspr.so.
+ifdef USE_PTHREADS
+EXTRA_LIBS = -lpthread
+endif # USE_PTHREADS
+endif # NS_USE_GCC
+endif # 4.1.3_U1
+endif # SunOS
+
+ifeq ($(OS_ARCH), NCR)
+# XXX: We see some strange problems when we link with libnspr.so.
+# So for now we use static libraries on NCR.  The shared library
+# stuff below is commented out.
+LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+LIBPRSTRMS = $(dist_libdir)/libprstrms$(MOD_MAJOR_VERSION).a
+EXTRA_LIBS = -lsocket -lnsl -ldl
+
+# NCR needs to link against -lsocket -lnsl (and -lc, which is linked
+# implicitly by $(CC)) again even though we already linked with these
+# system libraries when we built libnspr.so.
+#EXTRA_LIBS = -lsocket -lnsl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+#export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), SCOOS)
+# SCO Unix needs to link against -lsocket again even though we
+# already linked with these system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifneq ($(OS_RELEASE),4.2)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to 
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+	rm -f $@ $(AIX_TMP)
+	$(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+	$(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+	rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+ifeq ($(OS_ARCH), WINNT)
+	link $(LDOPTS) $< $(LIBPR) $(LIBPRSTRMS) wsock32.lib -out:$@
+else
+ifeq ($(OS_ARCH),OS2)
+	$(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPR) $(LIBPRSTRMS) $(OS_LIBS) $(EXTRA_LIBS)
+else
+	$(CCC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPRSTRMS) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
+
+testlinker:
+	echo $(LINK)
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp
new file mode 100644
index 0000000..771172e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prstrms.h"
+#include "prio.h"
+#include <string.h>
+#include <stdio.h>
+#if defined(XP_UNIX) || defined(XP_OS2)
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+const unsigned int MaxCnt = 1;
+
+void threadwork(void *mytag);
+
+
+typedef struct threadarg {
+    void *mytag;
+} threadarg;
+
+void 
+threadmain(void *mytag)
+{
+    threadarg arg;
+
+    arg.mytag = mytag;
+
+    threadwork(&arg);
+}
+
+
+void
+threadwork(void *_arg)
+{
+	threadarg *arg = (threadarg *)_arg;
+	unsigned int i;
+
+	char fname1[256];
+	char fname2[256];
+
+	strcpy(fname1, (char *)arg->mytag);
+	strcpy(fname2, (char *)arg->mytag);
+	strcat(fname2, "2");
+	PR_Delete(fname1);
+	PR_Delete(fname2);
+
+	PRfilebuf *fb[MaxCnt];
+	PRifstream *ifs[MaxCnt];
+	PRofstream *ofs[MaxCnt];
+	int mode = 0;
+#ifdef XP_UNIX
+	mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IRGRP|S_IWOTH|S_IROTH;
+#endif
+
+	//
+	// Allocate a bunch
+	cout << "Testing unused filebufs ----------------" << endl;
+	for (i=0; i < MaxCnt; i++){
+		fb[i] = new PRfilebuf;
+	}
+	// Delete them
+	for (i=0; i < MaxCnt; i++){
+		delete fb[i];
+	}
+	cout << "Unused filebufs complete ---------------" << endl;
+
+	//
+	// Allocate a bunch
+	cout << "Testing unused ifstream -----------------" << endl;
+	for (i=0; i < MaxCnt; i++){
+	  ifs[i] = new PRifstream;
+	}
+	//
+	// Delete them
+	for (i=0; i < MaxCnt; i++){
+	  delete ifs[i];
+	}
+	cout << "Unused ifstream complete ----------------" << endl;
+	//
+	// Allocate a bunch
+	cout << "Testing unused ofstream -----------------" << endl;
+	for (i=0; i < MaxCnt; i++){
+		ofs[i] = new PRofstream;
+	}
+	for (i=0; i < MaxCnt; i++){
+	  *(ofs[i]) << "A"; // Write a bit
+	  delete ofs[i]; // Delete it.
+	}
+	cout << "Unused ofstream complete ----------------" << endl;
+
+	cout << "Testing use of ofstream 1 (extra filebuf allocated) ---------" << endl;
+	PRofstream *aos = new PRofstream(fname1, ios::out|ios::ate, mode);
+	for (i=0; i < MaxCnt; i++){
+	  for (int j=0; j < 8192; j++)
+		*aos << "AaBbCcDdEeFfGg" << endl;
+		fb[i] = new PRfilebuf; // Allocate as we go to hack at the heap
+	}
+	//
+	// Delete the extra foo we allocated
+	for (i=0; i < MaxCnt; i++){
+	  delete fb[i];
+	}
+	aos->flush(); // Explicit flush
+	delete aos;
+	cout << "Testing use of ofstream 1 complete (extra filebuf deleted) --" << endl;
+	cout << "Testing use of ofstream 2 (extra filebuf allocated) ---------" << endl;
+	PRofstream *aos2 = new PRofstream(fname2, ios::out, mode);
+
+	for (i=0; i < MaxCnt; i++){
+	    *aos2 << "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
+	}
+	// Force flushing in the dtor
+	delete aos2;
+	cout << "Testing use of ofstream 2 complete (extra filebuf deleted) --" << endl;
+	char line[1024];
+	cout << "Testing use of ifstream 1 (stack allocation) -------------" << endl;
+	PRifstream ais(fname1);
+	for (i=0; i < MaxCnt; i++){
+		ais >> line;
+	}
+	cout << "Testing use of ifstream 1 complete -----------------------" << endl;
+	cout << "Testing use of ifstream 2 ----------------------" << endl;
+	PRifstream *ais2 = new PRifstream(fname2);
+	char achar;
+	for (i=0; i < MaxCnt*10; i++){
+		*ais2 >> achar;
+	}
+	delete ais2;
+	cout << "Testing use of ifstream 2 complete -------------" << endl;
+}
+
+#define STACKSIZE 1024*1024
+int
+main(int argc, char **argv)
+{
+	PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 256);
+	threadmain("TestFile");
+	PRThread *thr1 = PR_CreateThread(PR_SYSTEM_THREAD, 
+					 threadmain, 
+					 (void *)"TestFile1",
+					 PR_PRIORITY_NORMAL,
+					 PR_GLOBAL_THREAD,
+					 PR_JOINABLE_THREAD,
+					 STACKSIZE);
+	PRThread *thr2 = PR_CreateThread(PR_SYSTEM_THREAD, 
+					 threadmain, 
+					 (void *)"TestFile2",
+					 PR_PRIORITY_NORMAL,
+					 PR_GLOBAL_THREAD,
+					 PR_JOINABLE_THREAD,
+					 STACKSIZE);
+
+	PRThread *thr3 = PR_CreateThread(PR_SYSTEM_THREAD, 
+					 threadmain, 
+					 (void *)"TestFile3",
+					 PR_PRIORITY_NORMAL,
+					 PR_GLOBAL_THREAD,
+					 PR_JOINABLE_THREAD,
+					 STACKSIZE);
+	PR_JoinThread(thr1);
+	PR_JoinThread(thr2);
+	PR_JoinThread(thr3);
+	return 0;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/tests/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/lib/tests/Makefile.in
new file mode 100644
index 0000000..d96a2d5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/tests/Makefile.in
@@ -0,0 +1,219 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+CSRCS = \
+	arena.c \
+	base64t.c \
+	getopt.c \
+	string.c
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+CSRCS += arena.c
+endif
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS) $(OBJS)
+
+INCLUDES = -I$(dist_includedir)
+
+# Setting the variables LDOPTS and LIBPR.  We first initialize
+# them to the default values, then adjust them for some platforms.
+LDOPTS = -L$(dist_libdir)
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)
+LIBPLC = -lplc$(MOD_MAJOR_VERSION)
+LIBPLDS = -lplds$(MOD_MAJOR_VERSION)
+
+ifeq ($(OS_ARCH), WINNT)
+  LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO
+  ifeq ($(OS_TARGET), WIN95)
+  LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  LIBPLC= $(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  LIBPLDS= $(dist_libdir)/plds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  else
+  LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  LIBPLC= $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  LIBPLDS= $(dist_libdir)/libplds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+LDOPTS += -Zomf -Zlinker /PM:VIO
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), Linux)
+    ifeq ($(OS_RELEASE), 1.2)
+        EXTRA_LIBS = -ldl
+    else
+        LDOPTS += -Xlinker -rpath $(PWD)/$(dist_libdir)
+        ifeq ($(USE_PTHREADS),1)
+            EXTRA_LIBS = -lpthread
+        endif
+    endif
+endif
+
+ifeq (,$(filter-out OpenBSD,$(OS_ARCH)))
+    ifeq ($(USE_PTHREADS),1)
+        EXTRA_LIBS = -lpthread
+    endif
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+LDOPTS += -rpath $(PWD)/$(dist_libdir) -lpthread
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir)
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr
+LIBPLC = -lplc$(MOD_MAJOR_VERSION)_shr
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+ifneq ($(OS_RELEASE), 4.1.3_U1)
+ifdef NS_USE_GCC
+LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir)
+else
+LDOPTS += -R $(PWD)/$(dist_libdir)
+endif
+endif
+
+# SunOS 5.5 needs to link with -lpthread, even though we already
+# linked with this system library when we built libnspr.so.
+ifeq ($(OS_RELEASE), 5.5)
+ifdef USE_PTHREADS
+EXTRA_LIBS = -lpthread
+endif
+endif
+endif # SunOS
+
+ifeq ($(OS_ARCH), NCR)
+# NCR needs to link against -lsocket -lnsl (and -lc, which is linked
+# implicitly by $(CC)) again even though we already linked with these
+# system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket -lnsl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifneq ($(OS_RELEASE),4.2)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to 
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+	rm -f $@ $(AIX_TMP)
+	$(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+	$(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+	rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+
+ifeq ($(OS_ARCH), WINNT)
+	link $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) wsock32.lib -out:$@
+else
+ifeq ($(OS_ARCH),OS2)
+	$(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPLC)  $(LIBPLDS) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS)
+else
+	$(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPLDS) $(LIBPR) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/tests/arena.c b/nspr-4.8.6/mozilla/nsprpub/lib/tests/arena.c
new file mode 100644
index 0000000..9c74479
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/tests/arena.c
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        arena.c
+** Description: Testing arenas
+**
+*/
+
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include "nspr.h"
+#include "plarena.h"
+#include "plgetopt.h"
+
+PRLogModuleInfo *tLM;
+PRIntn  threadCount = 0;
+PRMonitor   *tMon;
+PRBool failed_already = PR_FALSE;
+
+/* Arguments from the command line with default values */
+PRIntn debug_mode = 0;
+PRIntn  poolMin = 4096;
+PRIntn  poolMax = (100 * 4096);
+PRIntn  arenaMin = 40;
+PRIntn  arenaMax = (100 * 40);
+PRIntn  stressIterations = 15;
+PRIntn  maxAlloc = (1024 * 1024);
+PRIntn  stressThreads = 4;
+
+void DumpAll( void )
+{
+	return;
+}
+
+/*
+** Test Arena allocation.
+*/
+static void ArenaAllocate( void )
+{
+    PLArenaPool ap;
+    void    *ptr;
+	PRInt32	i;
+
+    PL_InitArenaPool( &ap, "AllocArena", 2048, sizeof(double));
+    PR_LOG( tLM, PR_LOG_DEBUG, ("AA, InitPool -- Pool: %p. first: %p, current: %p, size: %d", 
+        &ap, ap.first, ap.current, ap.arenasize  ));
+
+	for( i = 0; i < 150; i++ )
+	{
+		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+        PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", 
+               &ap, ap.first, ap.current, ap.arenasize  ));
+		PR_LOG( tLM, PR_LOG_DEBUG,(
+		    "AA -- Pool: %p. alloc: %p ", &ap, ptr ));
+	}
+
+    PL_FreeArenaPool( &ap );
+
+	for( i = 0; i < 221; i++ )
+	{
+		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+        PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", 
+               &ap, ap.first, ap.current, ap.arenasize  ));
+		PR_LOG( tLM, PR_LOG_DEBUG,(
+		    "AA -- Pool: %p. alloc: %p ", &ap, ptr ));
+	}
+
+    PL_FreeArenaPool( &ap );
+    
+    return;
+} /* end ArenaGrow() */
+/*
+** Test Arena grow.
+*/
+static void ArenaGrow( void )
+{
+    PLArenaPool ap;
+    void    *ptr;
+	PRInt32	i;
+
+    PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double));
+    PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+
+	PR_LOG( tLM, PR_LOG_DEBUG, ("Before growth -- Pool: %p. alloc: %p ", &ap, ptr ));
+
+	for( i = 0; i < 10; i++ )
+	{
+		PL_ARENA_GROW( ptr, &ap, 512, 7000 );
+		PR_LOG( tLM, PR_LOG_DEBUG, ("After growth -- Pool: %p. alloc: %p ", &ap, ptr ));
+	}
+
+
+    return;
+} /* end ArenaGrow() */
+
+
+/*
+** Test arena Mark and Release.
+*/
+static void MarkAndRelease( void )
+{
+    PLArenaPool ap;
+    void    *ptr = NULL;
+    void    *mark0, *mark1;
+    PRIntn  i;
+
+    PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double));
+    mark0 = PL_ARENA_MARK( &ap );
+    PR_LOG( tLM, PR_LOG_DEBUG,
+        ("mark0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m0: %p", 
+            &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark0 ));
+
+	for( i = 0; i < 201; i++ )
+	{
+		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+        PR_LOG( tLM, PR_LOG_DEBUG,
+            ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
+                &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+	}
+
+    mark1 = PL_ARENA_MARK( &ap );
+    PR_LOG( tLM, PR_LOG_DEBUG,
+        ("mark1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m1: %p", 
+            &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark1 ));
+
+
+	for( i = 0; i < 225; i++ )
+	{
+		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+        PR_LOG( tLM, PR_LOG_DEBUG,
+            ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
+                &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+	}
+
+    PL_ARENA_RELEASE( &ap, mark1 );
+    PR_LOG( tLM, PR_LOG_DEBUG,
+        ("Release-1: %p -- Pool: %p. first: %p, current: %p, size: %d", 
+               mark1, &ap, ap.first, ap.current, ap.arenasize  ));
+
+	for( i = 0; i < 20; i++ )
+	{
+		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+        PR_LOG( tLM, PR_LOG_DEBUG,
+            ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
+                &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+	}
+
+    PL_ARENA_RELEASE( &ap, mark1 );
+    PR_LOG( tLM, PR_LOG_DEBUG,
+        ("Release-1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
+            &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+
+    PL_ARENA_RELEASE( &ap, mark0 );
+    PR_LOG( tLM, PR_LOG_DEBUG,
+        ("Release-0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
+            &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+
+    PL_FreeArenaPool( &ap );
+    PR_LOG( tLM, PR_LOG_DEBUG,
+        ("Free. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
+            &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+    
+    PL_FinishArenaPool( &ap );
+    PR_LOG( tLM, PR_LOG_DEBUG,
+        ("Finish. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
+            &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+
+    return;
+} /* end MarkAndRelease() */
+
+/*
+** RandSize() returns a random number in the range 
+** min..max, rounded to the next doubleword
+**
+*/
+static PRIntn RandSize( PRIntn min, PRIntn max )
+{
+    PRIntn  sz = (rand() % (max -min)) + min + sizeof(double);
+
+    sz &= ~sizeof(double)-1;
+
+    return(sz);
+}
+
+
+/*
+** StressThread()
+** A bunch of these beat on individual arenas
+** This tests the free_list protection.
+**
+*/
+static void PR_CALLBACK StressThread( void *arg )
+{
+    PLArenaPool ap;
+    PRIntn i;
+    PRIntn sz;
+    void *ptr;
+    PRThread *tp = PR_GetCurrentThread();
+
+    PR_LOG( tLM, PR_LOG_DEBUG, ("Stress Thread %p started\n", PR_GetCurrentThread()));
+    PL_InitArenaPool( &ap, "TheArena", RandSize( poolMin, poolMax), sizeof(double));
+
+    for ( i = 0; i < stressIterations; i++ )
+    {
+        PRIntn allocated = 0;
+
+        while ( allocated < maxAlloc )
+        {
+            sz = RandSize( arenaMin, arenaMax );
+            PL_ARENA_ALLOCATE( ptr, &ap, sz );
+            if ( ptr == NULL )
+            {
+                PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated));
+                break;
+            }
+            allocated += sz;
+        }
+        PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp));
+        PL_FreeArenaPool( &ap );
+    }
+    PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp));
+    PL_FinishArenaPool( &ap );
+    PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp));
+
+    /* That's all folks! let's quit */
+    PR_EnterMonitor(tMon);
+    threadCount--;
+    PR_Notify(tMon);
+    PR_ExitMonitor(tMon);    
+    return;
+}    
+
+/*
+** Stress()
+** Flog the hell out of arenas multi-threaded.
+** Do NOT pass an individual arena to another thread.
+** 
+*/
+static void Stress( void )
+{
+    PRThread    *tt;
+    PRIntn      i;
+
+    tMon = PR_NewMonitor();
+
+    for ( i = 0 ; i < stressThreads ; i++ )
+    {
+        PR_EnterMonitor(tMon);
+        tt = PR_CreateThread(PR_USER_THREAD,
+               StressThread,
+               NULL,
+               PR_PRIORITY_NORMAL,
+               PR_GLOBAL_THREAD,
+               PR_UNJOINABLE_THREAD,
+               0);
+        threadCount++;
+        PR_ExitMonitor(tMon);
+    }
+
+    /* Wait for all threads to exit */
+    PR_EnterMonitor(tMon);
+    while ( threadCount != 0 ) 
+    {
+        PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_ExitMonitor(tMon);
+	PR_DestroyMonitor(tMon);
+
+    return;
+} /* end Stress() */
+
+/*
+** EvaluateResults()
+** uses failed_already to display results and set program
+** exit code.
+*/
+static PRIntn  EvaluateResults(void)
+{
+    PRIntn rc = 0;
+
+    if ( failed_already == PR_TRUE )
+    {
+        PR_LOG( tLM, PR_LOG_DEBUG, ("FAIL\n"));
+        rc =1;
+    } 
+    else
+    {
+        PR_LOG( tLM, PR_LOG_DEBUG, ("PASS\n"));
+    }
+    return(rc);
+} /* EvaluateResults() */
+
+void Help( void )
+{
+    printf("arena [options]\n");
+    printf("where options are:\n");
+    printf("-p <n>   minimum size of an arena pool. Default(%d)\n", poolMin);
+    printf("-P <n>   maximum size of an arena pool. Default(%d)\n", poolMax);
+    printf("-a <n>   minimum size of an arena allocation. Default(%d)\n", arenaMin);
+    printf("-A <n>   maximum size of an arena allocation. Default(%d)\n", arenaMax);
+    printf("-i <n>   number of iterations in a stress thread. Default(%d)\n", stressIterations);
+    printf("-s <n>   maximum allocation for a single stress thread. Default(%d)\n", maxAlloc);
+    printf("-t <n>   number of stress threads. Default(%d)\n", stressThreads );
+    printf("-d       enable debug mode\n");
+    printf("\n");
+    exit(1);
+}    
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dhp:P:a:A:i:s:t:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'a':  /* arena Min size */
+            arenaMin = atol( opt->value );
+            break;
+        case 'A':  /* arena Max size  */
+            arenaMax = atol( opt->value );
+            break;
+        case 'p':  /* pool Min size */
+            poolMin = atol( opt->value );
+            break;
+        case 'P':  /* pool Max size */
+            poolMax = atol( opt->value );
+            break;
+        case 'i':  /* Iterations in stress tests */
+            stressIterations = atol( opt->value );
+            break;
+        case 's':  /* storage to get per iteration */
+            maxAlloc = atol( opt->value );
+            break;
+        case 't':  /* Number of stress threads to create */
+            stressThreads = atol( opt->value );
+            break;
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'h':  /* help */
+        default:
+            Help();
+        } /* end switch() */
+    } /* end while() */
+	PL_DestroyOptState(opt);
+
+    srand( (unsigned)time( NULL ) ); /* seed random number generator */
+    tLM = PR_NewLogModule("testcase");
+
+
+#if 0
+	ArenaAllocate();
+	ArenaGrow();
+#endif
+
+    MarkAndRelease();
+
+    Stress();
+
+    return(EvaluateResults());
+} /* end main() */
+
+/* arena.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/tests/base64t.c b/nspr-4.8.6/mozilla/nsprpub/lib/tests/base64t.c
new file mode 100644
index 0000000..c3c4881
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/tests/base64t.c
@@ -0,0 +1,3047 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plbase64.h"
+#include "plstr.h"
+#include "nspr.h"
+
+#include <stdio.h>
+
+static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* PL_Base64Encode, single characters */
+PRBool test_001(void)
+{
+    PRUint32 a, b;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char result[ 8 ];
+    char *rv;
+
+    printf("Test 001 (PL_Base64Encode, single characters)                         ..."); fflush(stdout);
+
+    plain[1] = plain[2] = plain[3] = (unsigned char)0;
+    cypher[2] = cypher[3] = (unsigned char)'=';
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (unsigned char)(a * 4 + b);
+            cypher[1] = base[(b * 16)];
+
+            rv = PL_Base64Encode((char *)plain, 1, result);
+            if( rv != result )
+            {
+                printf("FAIL\n\t(%d, %d): return value\n", a, b);
+                return PR_FALSE;
+            }
+
+            if( 0 != PL_strncmp((char *)cypher, result, 4) )
+            {
+                printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.4s.\"\n",
+                       a, b, cypher, result);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, double characters */
+PRBool test_002(void)
+{
+    PRUint32 a, b, c, d;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char result[ 8 ];
+    char *rv;
+
+    printf("Test 002 (PL_Base64Encode, double characters)                         ..."); fflush(stdout);
+
+    plain[2] = plain[3] = (unsigned char)0;
+    cypher[3] = (unsigned char)'=';
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    cypher[2] = base[d*4];
+
+                    rv = PL_Base64Encode((char *)plain, 2, result);
+                    if( rv != result )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d);
+                        return PR_FALSE;
+                    }
+
+                    if( 0 != PL_strncmp((char *)cypher, result, 4) )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n",
+                               a, b, c, d, cypher, result);
+                        return PR_FALSE;
+                    }
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, triple characters */
+PRBool test_003(void)
+{
+    PRUint32 a, b, c, d, e, f;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char result[ 8 ];
+    char *rv;
+
+    printf("Test 003 (PL_Base64Encode, triple characters)                         ..."); fflush(stdout);
+
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    for( e = 0; e < 4; e++ )
+                    {
+                        cypher[2] = base[d*4 + e];
+                        for( f = 0; f < 64; f++ )
+                        {
+                            plain[2] = e * 64 + f;
+                            cypher[3] = base[f];
+
+                            rv = PL_Base64Encode((char *)plain, 3, result);
+                            if( rv != result )
+                            {
+                                printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): return value\n", a, b, c, d, e, f);
+                                return PR_FALSE;
+                            }
+
+                            if( 0 != PL_strncmp((char *)cypher, result, 4) )
+                            {
+                                printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n",
+                                       a, b, c, d, e, f, cypher, result);
+                                return PR_FALSE;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+    static struct
+    {
+        const char *plaintext;
+        const char *cyphertext;
+    } array[] =
+      {
+          /* Cyphertexts generated with uuenview 0.5.13 */
+          { " ", "IA==" },
+          { ".", "Lg==" },
+          { "/", "Lw==" },
+          { "C", "Qw==" },
+          { "H", "SA==" },
+          { "S", "Uw==" },
+          { "^", "Xg==" },
+          { "a", "YQ==" },
+          { "o", "bw==" },
+          { "t", "dA==" },
+
+          { "AB", "QUI=" },
+          { "AH", "QUg=" },
+          { "AQ", "QVE=" },
+          { "BD", "QkQ=" },
+          { "CR", "Q1I=" },
+          { "CS", "Q1M=" },
+          { "DB", "REI=" },
+          { "DC", "REM=" },
+          { "EK", "RUs=" },
+          { "ET", "RVQ=" },
+          { "IM", "SU0=" },
+          { "JR", "SlI=" },
+          { "LO", "TE8=" },
+          { "LW", "TFc=" },
+          { "ML", "TUw=" },
+          { "SB", "U0I=" },
+          { "TO", "VE8=" },
+          { "VS", "VlM=" },
+          { "WP", "V1A=" },
+          /* legitimate two-letter words */
+          { "ad", "YWQ=" },
+          { "ah", "YWg=" },
+          { "am", "YW0=" },
+          { "an", "YW4=" },
+          { "as", "YXM=" },
+          { "at", "YXQ=" },
+          { "ax", "YXg=" },
+          { "be", "YmU=" },
+          { "by", "Ynk=" },
+          { "do", "ZG8=" },
+          { "go", "Z28=" },
+          { "he", "aGU=" },
+          { "hi", "aGk=" },
+          { "if", "aWY=" },
+          { "in", "aW4=" },
+          { "is", "aXM=" },
+          { "it", "aXQ=" },
+          { "me", "bWU=" },
+          { "my", "bXk=" },
+          { "no", "bm8=" },
+          { "of", "b2Y=" },
+          { "on", "b24=" },
+          { "or", "b3I=" },
+          { "ox", "b3g=" },
+          { "so", "c28=" },
+          { "to", "dG8=" },
+          { "up", "dXA=" },
+          { "us", "dXM=" },
+          { "we", "d2U=" },
+          /* all three-letter entries in /usr/dict/words */
+          { "1st", "MXN0" },
+          { "2nd", "Mm5k" },
+          { "3rd", "M3Jk" },
+          { "4th", "NHRo" },
+          { "5th", "NXRo" },
+          { "6th", "NnRo" },
+          { "7th", "N3Ro" },
+          { "8th", "OHRo" },
+          { "9th", "OXRo" },
+          { "AAA", "QUFB" },
+          { "AAU", "QUFV" },
+          { "ABA", "QUJB" },
+          { "abc", "YWJj" },
+          { "Abe", "QWJl" },
+          { "Abo", "QWJv" },
+          { "ace", "YWNl" },
+          { "ACM", "QUNN" },
+          { "ACS", "QUNT" },
+          { "act", "YWN0" },
+          { "Ada", "QWRh" },
+          { "add", "YWRk" },
+          { "ado", "YWRv" },
+          { "aft", "YWZ0" },
+          { "age", "YWdl" },
+          { "ago", "YWdv" },
+          { "aid", "YWlk" },
+          { "ail", "YWls" },
+          { "aim", "YWlt" },
+          { "air", "YWly" },
+          { "ala", "YWxh" },
+          { "alb", "YWxi" },
+          { "ale", "YWxl" },
+          { "Ali", "QWxp" },
+          { "all", "YWxs" },
+          { "alp", "YWxw" },
+          { "A&M", "QSZN" },
+          { "AMA", "QU1B" },
+          { "ami", "YW1p" },
+          { "amp", "YW1w" },
+          { "Amy", "QW15" },
+          { "amy", "YW15" },
+          { "ana", "YW5h" },
+          { "and", "YW5k" },
+          { "ani", "YW5p" },
+          { "Ann", "QW5u" },
+          { "ant", "YW50" },
+          { "any", "YW55" },
+          { "A&P", "QSZQ" },
+          { "ape", "YXBl" },
+          { "Apr", "QXBy" },
+          { "APS", "QVBT" },
+          { "apt", "YXB0" },
+          { "arc", "YXJj" },
+          { "are", "YXJl" },
+          { "ark", "YXJr" },
+          { "arm", "YXJt" },
+          { "art", "YXJ0" },
+          { "a's", "YSdz" },
+          { "ash", "YXNo" },
+          { "ask", "YXNr" },
+          { "ass", "YXNz" },
+          { "ate", "YXRl" },
+          { "Aug", "QXVn" },
+          { "auk", "YXVr" },
+          { "Ave", "QXZl" },
+          { "awe", "YXdl" },
+          { "awl", "YXds" },
+          { "awn", "YXdu" },
+          { "axe", "YXhl" },
+          { "aye", "YXll" },
+          { "bad", "YmFk" },
+          { "bag", "YmFn" },
+          { "bah", "YmFo" },
+          { "bam", "YmFt" },
+          { "ban", "YmFu" },
+          { "bar", "YmFy" },
+          { "bat", "YmF0" },
+          { "bay", "YmF5" },
+          { "bed", "YmVk" },
+          { "bee", "YmVl" },
+          { "beg", "YmVn" },
+          { "bel", "YmVs" },
+          { "Ben", "QmVu" },
+          { "bet", "YmV0" },
+          { "bey", "YmV5" },
+          { "bib", "Ymli" },
+          { "bid", "Ymlk" },
+          { "big", "Ymln" },
+          { "bin", "Ymlu" },
+          { "bit", "Yml0" },
+          { "biz", "Yml6" },
+          { "BMW", "Qk1X" },
+          { "boa", "Ym9h" },
+          { "bob", "Ym9i" },
+          { "bog", "Ym9n" },
+          { "bon", "Ym9u" },
+          { "boo", "Ym9v" },
+          { "bop", "Ym9w" },
+          { "bow", "Ym93" },
+          { "box", "Ym94" },
+          { "boy", "Ym95" },
+          { "b's", "Yidz" },
+          { "BTL", "QlRM" },
+          { "BTU", "QlRV" },
+          { "bub", "YnVi" },
+          { "bud", "YnVk" },
+          { "bug", "YnVn" },
+          { "bum", "YnVt" },
+          { "bun", "YnVu" },
+          { "bus", "YnVz" },
+          { "but", "YnV0" },
+          { "buy", "YnV5" },
+          { "bye", "Ynll" },
+          { "cab", "Y2Fi" },
+          { "Cal", "Q2Fs" },
+          { "cam", "Y2Ft" },
+          { "can", "Y2Fu" },
+          { "cap", "Y2Fw" },
+          { "car", "Y2Fy" },
+          { "cat", "Y2F0" },
+          { "caw", "Y2F3" },
+          { "CBS", "Q0JT" },
+          { "CDC", "Q0RD" },
+          { "CEQ", "Q0VR" },
+          { "chi", "Y2hp" },
+          { "CIA", "Q0lB" },
+          { "cit", "Y2l0" },
+          { "cod", "Y29k" },
+          { "cog", "Y29n" },
+          { "col", "Y29s" },
+          { "con", "Y29u" },
+          { "coo", "Y29v" },
+          { "cop", "Y29w" },
+          { "cos", "Y29z" },
+          { "cot", "Y290" },
+          { "cow", "Y293" },
+          { "cox", "Y294" },
+          { "coy", "Y295" },
+          { "CPA", "Q1BB" },
+          { "cpu", "Y3B1" },
+          { "CRT", "Q1JU" },
+          { "cry", "Y3J5" },
+          { "c's", "Yydz" },
+          { "cub", "Y3Vi" },
+          { "cud", "Y3Vk" },
+          { "cue", "Y3Vl" },
+          { "cup", "Y3Vw" },
+          { "cur", "Y3Vy" },
+          { "cut", "Y3V0" },
+          { "dab", "ZGFi" },
+          { "dad", "ZGFk" },
+          { "dam", "ZGFt" },
+          { "Dan", "RGFu" },
+          { "Dar", "RGFy" },
+          { "day", "ZGF5" },
+          { "Dec", "RGVj" },
+          { "Dee", "RGVl" },
+          { "Del", "RGVs" },
+          { "den", "ZGVu" },
+          { "Des", "RGVz" },
+          { "dew", "ZGV3" },
+          { "dey", "ZGV5" },
+          { "did", "ZGlk" },
+          { "die", "ZGll" },
+          { "dig", "ZGln" },
+          { "dim", "ZGlt" },
+          { "din", "ZGlu" },
+          { "dip", "ZGlw" },
+          { "Dis", "RGlz" },
+          { "DNA", "RE5B" },
+          { "DOD", "RE9E" },
+          { "doe", "ZG9l" },
+          { "dog", "ZG9n" },
+          { "don", "ZG9u" },
+          { "dot", "ZG90" },
+          { "Dow", "RG93" },
+          { "dry", "ZHJ5" },
+          { "d's", "ZCdz" },
+          { "dub", "ZHVi" },
+          { "dud", "ZHVk" },
+          { "due", "ZHVl" },
+          { "dug", "ZHVn" },
+          { "dun", "ZHVu" },
+          { "dye", "ZHll" },
+          { "ear", "ZWFy" },
+          { "eat", "ZWF0" },
+          { "ebb", "ZWJi" },
+          { "EDT", "RURU" },
+          { "eel", "ZWVs" },
+          { "eft", "ZWZ0" },
+          { "e.g", "ZS5n" },
+          { "egg", "ZWdn" },
+          { "ego", "ZWdv" },
+          { "eke", "ZWtl" },
+          { "Eli", "RWxp" },
+          { "elk", "ZWxr" },
+          { "ell", "ZWxs" },
+          { "elm", "ZWxt" },
+          { "Ely", "RWx5" },
+          { "end", "ZW5k" },
+          { "Eng", "RW5n" },
+          { "EPA", "RVBB" },
+          { "era", "ZXJh" },
+          { "ere", "ZXJl" },
+          { "erg", "ZXJn" },
+          { "err", "ZXJy" },
+          { "e's", "ZSdz" },
+          { "EST", "RVNU" },
+          { "eta", "ZXRh" },
+          { "etc", "ZXRj" },
+          { "Eva", "RXZh" },
+          { "eve", "ZXZl" },
+          { "ewe", "ZXdl" },
+          { "eye", "ZXll" },
+          { "FAA", "RkFB" },
+          { "fad", "ZmFk" },
+          { "fag", "ZmFn" },
+          { "fan", "ZmFu" },
+          { "far", "ZmFy" },
+          { "fat", "ZmF0" },
+          { "fay", "ZmF5" },
+          { "FBI", "RkJJ" },
+          { "FCC", "RkND" },
+          { "FDA", "RkRB" },
+          { "Feb", "RmVi" },
+          { "fed", "ZmVk" },
+          { "fee", "ZmVl" },
+          { "few", "ZmV3" },
+          { "fib", "Zmli" },
+          { "fig", "Zmln" },
+          { "fin", "Zmlu" },
+          { "fir", "Zmly" },
+          { "fit", "Zml0" },
+          { "fix", "Zml4" },
+          { "Flo", "Rmxv" },
+          { "flu", "Zmx1" },
+          { "fly", "Zmx5" },
+          { "FMC", "Rk1D" },
+          { "fob", "Zm9i" },
+          { "foe", "Zm9l" },
+          { "fog", "Zm9n" },
+          { "fop", "Zm9w" },
+          { "for", "Zm9y" },
+          { "fox", "Zm94" },
+          { "FPC", "RlBD" },
+          { "fro", "ZnJv" },
+          { "fry", "ZnJ5" },
+          { "f's", "Zidz" },
+          { "FTC", "RlRD" },
+          { "fum", "ZnVt" },
+          { "fun", "ZnVu" },
+          { "fur", "ZnVy" },
+          { "gab", "Z2Fi" },
+          { "gad", "Z2Fk" },
+          { "gag", "Z2Fn" },
+          { "gal", "Z2Fs" },
+          { "gam", "Z2Ft" },
+          { "GAO", "R0FP" },
+          { "gap", "Z2Fw" },
+          { "gar", "Z2Fy" },
+          { "gas", "Z2Fz" },
+          { "gay", "Z2F5" },
+          { "gee", "Z2Vl" },
+          { "gel", "Z2Vs" },
+          { "gem", "Z2Vt" },
+          { "get", "Z2V0" },
+          { "gig", "Z2ln" },
+          { "Gil", "R2ls" },
+          { "gin", "Z2lu" },
+          { "GMT", "R01U" },
+          { "GNP", "R05Q" },
+          { "gnu", "Z251" },
+          { "Goa", "R29h" },
+          { "gob", "Z29i" },
+          { "god", "Z29k" },
+          { "gog", "Z29n" },
+          { "GOP", "R09Q" },
+          { "got", "Z290" },
+          { "GPO", "R1BP" },
+          { "g's", "Zydz" },
+          { "GSA", "R1NB" },
+          { "gum", "Z3Vt" },
+          { "gun", "Z3Vu" },
+          { "Gus", "R3Vz" },
+          { "gut", "Z3V0" },
+          { "guy", "Z3V5" },
+          { "gym", "Z3lt" },
+          { "gyp", "Z3lw" },
+          { "had", "aGFk" },
+          { "Hal", "SGFs" },
+          { "ham", "aGFt" },
+          { "Han", "SGFu" },
+          { "hap", "aGFw" },
+          { "hat", "aGF0" },
+          { "haw", "aGF3" },
+          { "hay", "aGF5" },
+          { "hem", "aGVt" },
+          { "hen", "aGVu" },
+          { "her", "aGVy" },
+          { "hew", "aGV3" },
+          { "hex", "aGV4" },
+          { "hey", "aGV5" },
+          { "hid", "aGlk" },
+          { "him", "aGlt" },
+          { "hip", "aGlw" },
+          { "his", "aGlz" },
+          { "hit", "aGl0" },
+          { "hob", "aG9i" },
+          { "hoc", "aG9j" },
+          { "hoe", "aG9l" },
+          { "hog", "aG9n" },
+          { "hoi", "aG9p" },
+          { "Hom", "SG9t" },
+          { "hop", "aG9w" },
+          { "hot", "aG90" },
+          { "how", "aG93" },
+          { "hoy", "aG95" },
+          { "h's", "aCdz" },
+          { "hub", "aHVi" },
+          { "hue", "aHVl" },
+          { "hug", "aHVn" },
+          { "huh", "aHVo" },
+          { "hum", "aHVt" },
+          { "Hun", "SHVu" },
+          { "hut", "aHV0" },
+          { "Ian", "SWFu" },
+          { "IBM", "SUJN" },
+          { "Ibn", "SWJu" },
+          { "ICC", "SUND" },
+          { "ice", "aWNl" },
+          { "icy", "aWN5" },
+          { "I'd", "SSdk" },
+          { "Ida", "SWRh" },
+          { "i.e", "aS5l" },
+          { "iii", "aWlp" },
+          { "Ike", "SWtl" },
+          { "ill", "aWxs" },
+          { "I'm", "SSdt" },
+          { "imp", "aW1w" },
+          { "Inc", "SW5j" },
+          { "ink", "aW5r" },
+          { "inn", "aW5u" },
+          { "ion", "aW9u" },
+          { "Ira", "SXJh" },
+          { "ire", "aXJl" },
+          { "irk", "aXJr" },
+          { "IRS", "SVJT" },
+          { "i's", "aSdz" },
+          { "Ito", "SXRv" },
+          { "ITT", "SVRU" },
+          { "ivy", "aXZ5" },
+          { "jab", "amFi" },
+          { "jag", "amFn" },
+          { "jam", "amFt" },
+          { "Jan", "SmFu" },
+          { "jar", "amFy" },
+          { "jaw", "amF3" },
+          { "jay", "amF5" },
+          { "Jed", "SmVk" },
+          { "jet", "amV0" },
+          { "Jew", "SmV3" },
+          { "jig", "amln" },
+          { "Jim", "Smlt" },
+          { "job", "am9i" },
+          { "Joe", "Sm9l" },
+          { "jog", "am9n" },
+          { "Jon", "Sm9u" },
+          { "jot", "am90" },
+          { "joy", "am95" },
+          { "j's", "aidz" },
+          { "jug", "anVn" },
+          { "jut", "anV0" },
+          { "Kay", "S2F5" },
+          { "keg", "a2Vn" },
+          { "ken", "a2Vu" },
+          { "key", "a2V5" },
+          { "kid", "a2lk" },
+          { "Kim", "S2lt" },
+          { "kin", "a2lu" },
+          { "kit", "a2l0" },
+          { "k's", "aydz" },
+          { "lab", "bGFi" },
+          { "lac", "bGFj" },
+          { "lad", "bGFk" },
+          { "lag", "bGFn" },
+          { "lam", "bGFt" },
+          { "Lao", "TGFv" },
+          { "lap", "bGFw" },
+          { "law", "bGF3" },
+          { "lax", "bGF4" },
+          { "lay", "bGF5" },
+          { "lea", "bGVh" },
+          { "led", "bGVk" },
+          { "lee", "bGVl" },
+          { "leg", "bGVn" },
+          { "Len", "TGVu" },
+          { "Leo", "TGVv" },
+          { "let", "bGV0" },
+          { "Lev", "TGV2" },
+          { "Lew", "TGV3" },
+          { "lew", "bGV3" },
+          { "lid", "bGlk" },
+          { "lie", "bGll" },
+          { "lim", "bGlt" },
+          { "Lin", "TGlu" },
+          { "lip", "bGlw" },
+          { "lit", "bGl0" },
+          { "Liz", "TGl6" },
+          { "lob", "bG9i" },
+          { "log", "bG9n" },
+          { "lop", "bG9w" },
+          { "Los", "TG9z" },
+          { "lot", "bG90" },
+          { "Lou", "TG91" },
+          { "low", "bG93" },
+          { "loy", "bG95" },
+          { "l's", "bCdz" },
+          { "LSI", "TFNJ" },
+          { "Ltd", "THRk" },
+          { "LTV", "TFRW" },
+          { "lug", "bHVn" },
+          { "lux", "bHV4" },
+          { "lye", "bHll" },
+          { "Mac", "TWFj" },
+          { "mad", "bWFk" },
+          { "Mae", "TWFl" },
+          { "man", "bWFu" },
+          { "Mao", "TWFv" },
+          { "map", "bWFw" },
+          { "mar", "bWFy" },
+          { "mat", "bWF0" },
+          { "maw", "bWF3" },
+          { "Max", "TWF4" },
+          { "max", "bWF4" },
+          { "may", "bWF5" },
+          { "MBA", "TUJB" },
+          { "Meg", "TWVn" },
+          { "Mel", "TWVs" },
+          { "men", "bWVu" },
+          { "met", "bWV0" },
+          { "mew", "bWV3" },
+          { "mid", "bWlk" },
+          { "mig", "bWln" },
+          { "min", "bWlu" },
+          { "MIT", "TUlU" },
+          { "mix", "bWl4" },
+          { "mob", "bW9i" },
+          { "Moe", "TW9l" },
+          { "moo", "bW9v" },
+          { "mop", "bW9w" },
+          { "mot", "bW90" },
+          { "mow", "bW93" },
+          { "MPH", "TVBI" },
+          { "Mrs", "TXJz" },
+          { "m's", "bSdz" },
+          { "mud", "bXVk" },
+          { "mug", "bXVn" },
+          { "mum", "bXVt" },
+          { "nab", "bmFi" },
+          { "nag", "bmFn" },
+          { "Nan", "TmFu" },
+          { "nap", "bmFw" },
+          { "Nat", "TmF0" },
+          { "nay", "bmF5" },
+          { "NBC", "TkJD" },
+          { "NBS", "TkJT" },
+          { "NCO", "TkNP" },
+          { "NCR", "TkNS" },
+          { "Ned", "TmVk" },
+          { "nee", "bmVl" },
+          { "net", "bmV0" },
+          { "new", "bmV3" },
+          { "nib", "bmli" },
+          { "NIH", "TklI" },
+          { "nil", "bmls" },
+          { "nip", "bmlw" },
+          { "nit", "bml0" },
+          { "NNE", "Tk5F" },
+          { "NNW", "Tk5X" },
+          { "nob", "bm9i" },
+          { "nod", "bm9k" },
+          { "non", "bm9u" },
+          { "nor", "bm9y" },
+          { "not", "bm90" },
+          { "Nov", "Tm92" },
+          { "now", "bm93" },
+          { "NRC", "TlJD" },
+          { "n's", "bidz" },
+          { "NSF", "TlNG" },
+          { "nun", "bnVu" },
+          { "nut", "bnV0" },
+          { "NYC", "TllD" },
+          { "NYU", "TllV" },
+          { "oaf", "b2Fm" },
+          { "oak", "b2Fr" },
+          { "oar", "b2Fy" },
+          { "oat", "b2F0" },
+          { "Oct", "T2N0" },
+          { "odd", "b2Rk" },
+          { "ode", "b2Rl" },
+          { "off", "b2Zm" },
+          { "oft", "b2Z0" },
+          { "ohm", "b2ht" },
+          { "oil", "b2ls" },
+          { "old", "b2xk" },
+          { "one", "b25l" },
+          { "opt", "b3B0" },
+          { "orb", "b3Ji" },
+          { "ore", "b3Jl" },
+          { "Orr", "T3Jy" },
+          { "o's", "bydz" },
+          { "Ott", "T3R0" },
+          { "our", "b3Vy" },
+          { "out", "b3V0" },
+          { "ova", "b3Zh" },
+          { "owe", "b3dl" },
+          { "owl", "b3ds" },
+          { "own", "b3du" },
+          { "pad", "cGFk" },
+          { "pal", "cGFs" },
+          { "Pam", "UGFt" },
+          { "pan", "cGFu" },
+          { "pap", "cGFw" },
+          { "par", "cGFy" },
+          { "pat", "cGF0" },
+          { "paw", "cGF3" },
+          { "pax", "cGF4" },
+          { "pay", "cGF5" },
+          { "Paz", "UGF6" },
+          { "PBS", "UEJT" },
+          { "PDP", "UERQ" },
+          { "pea", "cGVh" },
+          { "pee", "cGVl" },
+          { "peg", "cGVn" },
+          { "pen", "cGVu" },
+          { "pep", "cGVw" },
+          { "per", "cGVy" },
+          { "pet", "cGV0" },
+          { "pew", "cGV3" },
+          { "PhD", "UGhE" },
+          { "phi", "cGhp" },
+          { "pie", "cGll" },
+          { "pig", "cGln" },
+          { "pin", "cGlu" },
+          { "pip", "cGlw" },
+          { "pit", "cGl0" },
+          { "ply", "cGx5" },
+          { "pod", "cG9k" },
+          { "Poe", "UG9l" },
+          { "poi", "cG9p" },
+          { "pol", "cG9s" },
+          { "pop", "cG9w" },
+          { "pot", "cG90" },
+          { "pow", "cG93" },
+          { "ppm", "cHBt" },
+          { "pro", "cHJv" },
+          { "pry", "cHJ5" },
+          { "p's", "cCdz" },
+          { "psi", "cHNp" },
+          { "PTA", "UFRB" },
+          { "pub", "cHVi" },
+          { "PUC", "UFVD" },
+          { "pug", "cHVn" },
+          { "pun", "cHVu" },
+          { "pup", "cHVw" },
+          { "pus", "cHVz" },
+          { "put", "cHV0" },
+          { "PVC", "UFZD" },
+          { "QED", "UUVE" },
+          { "q's", "cSdz" },
+          { "qua", "cXVh" },
+          { "quo", "cXVv" },
+          { "Rae", "UmFl" },
+          { "rag", "cmFn" },
+          { "raj", "cmFq" },
+          { "ram", "cmFt" },
+          { "ran", "cmFu" },
+          { "rap", "cmFw" },
+          { "rat", "cmF0" },
+          { "raw", "cmF3" },
+          { "ray", "cmF5" },
+          { "RCA", "UkNB" },
+          { "R&D", "UiZE" },
+          { "reb", "cmVi" },
+          { "red", "cmVk" },
+          { "rep", "cmVw" },
+          { "ret", "cmV0" },
+          { "rev", "cmV2" },
+          { "Rex", "UmV4" },
+          { "rho", "cmhv" },
+          { "rib", "cmli" },
+          { "rid", "cmlk" },
+          { "rig", "cmln" },
+          { "rim", "cmlt" },
+          { "Rio", "Umlv" },
+          { "rip", "cmlw" },
+          { "RNA", "Uk5B" },
+          { "rob", "cm9i" },
+          { "rod", "cm9k" },
+          { "roe", "cm9l" },
+          { "Ron", "Um9u" },
+          { "rot", "cm90" },
+          { "row", "cm93" },
+          { "Roy", "Um95" },
+          { "RPM", "UlBN" },
+          { "r's", "cidz" },
+          { "rub", "cnVi" },
+          { "rue", "cnVl" },
+          { "rug", "cnVn" },
+          { "rum", "cnVt" },
+          { "run", "cnVu" },
+          { "rut", "cnV0" },
+          { "rye", "cnll" },
+          { "sac", "c2Fj" },
+          { "sad", "c2Fk" },
+          { "sag", "c2Fn" },
+          { "Sal", "U2Fs" },
+          { "Sam", "U2Ft" },
+          { "San", "U2Fu" },
+          { "Sao", "U2Fv" },
+          { "sap", "c2Fw" },
+          { "sat", "c2F0" },
+          { "saw", "c2F3" },
+          { "sax", "c2F4" },
+          { "say", "c2F5" },
+          { "Sci", "U2Np" },
+          { "SCM", "U0NN" },
+          { "sea", "c2Vh" },
+          { "sec", "c2Vj" },
+          { "see", "c2Vl" },
+          { "sen", "c2Vu" },
+          { "seq", "c2Vx" },
+          { "set", "c2V0" },
+          { "sew", "c2V3" },
+          { "sex", "c2V4" },
+          { "she", "c2hl" },
+          { "Shu", "U2h1" },
+          { "shy", "c2h5" },
+          { "sib", "c2li" },
+          { "sic", "c2lj" },
+          { "sin", "c2lu" },
+          { "sip", "c2lw" },
+          { "sir", "c2ly" },
+          { "sis", "c2lz" },
+          { "sit", "c2l0" },
+          { "six", "c2l4" },
+          { "ski", "c2tp" },
+          { "sky", "c2t5" },
+          { "sly", "c2x5" },
+          { "sob", "c29i" },
+          { "Soc", "U29j" },
+          { "sod", "c29k" },
+          { "Sol", "U29s" },
+          { "son", "c29u" },
+          { "sop", "c29w" },
+          { "sou", "c291" },
+          { "sow", "c293" },
+          { "soy", "c295" },
+          { "spa", "c3Bh" },
+          { "spy", "c3B5" },
+          { "Sri", "U3Jp" },
+          { "s's", "cydz" },
+          { "SSE", "U1NF" },
+          { "SST", "U1NU" },
+          { "SSW", "U1NX" },
+          { "Stu", "U3R1" },
+          { "sub", "c3Vi" },
+          { "sud", "c3Vk" },
+          { "sue", "c3Vl" },
+          { "sum", "c3Vt" },
+          { "sun", "c3Vu" },
+          { "sup", "c3Vw" },
+          { "Sus", "U3Vz" },
+          { "tab", "dGFi" },
+          { "tad", "dGFk" },
+          { "tag", "dGFn" },
+          { "tam", "dGFt" },
+          { "tan", "dGFu" },
+          { "tao", "dGFv" },
+          { "tap", "dGFw" },
+          { "tar", "dGFy" },
+          { "tat", "dGF0" },
+          { "tau", "dGF1" },
+          { "tax", "dGF4" },
+          { "tea", "dGVh" },
+          { "Ted", "VGVk" },
+          { "ted", "dGVk" },
+          { "tee", "dGVl" },
+          { "Tel", "VGVs" },
+          { "ten", "dGVu" },
+          { "the", "dGhl" },
+          { "thy", "dGh5" },
+          { "tic", "dGlj" },
+          { "tid", "dGlk" },
+          { "tie", "dGll" },
+          { "til", "dGls" },
+          { "Tim", "VGlt" },
+          { "tin", "dGlu" },
+          { "tip", "dGlw" },
+          { "tit", "dGl0" },
+          { "TNT", "VE5U" },
+          { "toe", "dG9l" },
+          { "tog", "dG9n" },
+          { "Tom", "VG9t" },
+          { "ton", "dG9u" },
+          { "too", "dG9v" },
+          { "top", "dG9w" },
+          { "tor", "dG9y" },
+          { "tot", "dG90" },
+          { "tow", "dG93" },
+          { "toy", "dG95" },
+          { "TRW", "VFJX" },
+          { "try", "dHJ5" },
+          { "t's", "dCdz" },
+          { "TTL", "VFRM" },
+          { "TTY", "VFRZ" },
+          { "tub", "dHVi" },
+          { "tug", "dHVn" },
+          { "tum", "dHVt" },
+          { "tun", "dHVu" },
+          { "TVA", "VFZB" },
+          { "TWA", "VFdB" },
+          { "two", "dHdv" },
+          { "TWX", "VFdY" },
+          { "ugh", "dWdo" },
+          { "UHF", "VUhG" },
+          { "Uri", "VXJp" },
+          { "urn", "dXJu" },
+          { "U.S", "VS5T" },
+          { "u's", "dSdz" },
+          { "USA", "VVNB" },
+          { "USC", "VVND" },
+          { "use", "dXNl" },
+          { "USN", "VVNO" },
+          { "van", "dmFu" },
+          { "vat", "dmF0" },
+          { "vee", "dmVl" },
+          { "vet", "dmV0" },
+          { "vex", "dmV4" },
+          { "VHF", "VkhG" },
+          { "via", "dmlh" },
+          { "vie", "dmll" },
+          { "vii", "dmlp" },
+          { "vis", "dmlz" },
+          { "viz", "dml6" },
+          { "von", "dm9u" },
+          { "vow", "dm93" },
+          { "v's", "didz" },
+          { "WAC", "V0FD" },
+          { "wad", "d2Fk" },
+          { "wag", "d2Fn" },
+          { "wah", "d2Fo" },
+          { "wan", "d2Fu" },
+          { "war", "d2Fy" },
+          { "was", "d2Fz" },
+          { "wax", "d2F4" },
+          { "way", "d2F5" },
+          { "web", "d2Vi" },
+          { "wed", "d2Vk" },
+          { "wee", "d2Vl" },
+          { "Wei", "V2Vp" },
+          { "wet", "d2V0" },
+          { "who", "d2hv" },
+          { "why", "d2h5" },
+          { "wig", "d2ln" },
+          { "win", "d2lu" },
+          { "wit", "d2l0" },
+          { "woe", "d29l" },
+          { "wok", "d29r" },
+          { "won", "d29u" },
+          { "woo", "d29v" },
+          { "wop", "d29w" },
+          { "wow", "d293" },
+          { "wry", "d3J5" },
+          { "w's", "dydz" },
+          { "x's", "eCdz" },
+          { "yah", "eWFo" },
+          { "yak", "eWFr" },
+          { "yam", "eWFt" },
+          { "yap", "eWFw" },
+          { "yaw", "eWF3" },
+          { "yea", "eWVh" },
+          { "yen", "eWVu" },
+          { "yet", "eWV0" },
+          { "yin", "eWlu" },
+          { "yip", "eWlw" },
+          { "yon", "eW9u" },
+          { "you", "eW91" },
+          { "yow", "eW93" },
+          { "y's", "eSdz" },
+          { "yuh", "eXVo" },
+          { "zag", "emFn" },
+          { "Zan", "WmFu" },
+          { "zap", "emFw" },
+          { "Zen", "WmVu" },
+          { "zig", "emln" },
+          { "zip", "emlw" },
+          { "Zoe", "Wm9l" },
+          { "zoo", "em9v" },
+          { "z's", "eidz" },
+          /* the false rumors file */
+          { "\"So when I die, the first thing I will see in heaven is a score list?\"", 
+            "IlNvIHdoZW4gSSBkaWUsIHRoZSBmaXJzdCB0aGluZyBJIHdpbGwgc2VlIGluIGhlYXZlbiBpcyBhIHNjb3JlIGxpc3Q/Ig==" },
+          { "1st Law of Hacking: leaving is much more difficult than entering.", 
+            "MXN0IExhdyBvZiBIYWNraW5nOiBsZWF2aW5nIGlzIG11Y2ggbW9yZSBkaWZmaWN1bHQgdGhhbiBlbnRlcmluZy4=" },
+          { "2nd Law of Hacking: first in, first out.", 
+            "Mm5kIExhdyBvZiBIYWNraW5nOiBmaXJzdCBpbiwgZmlyc3Qgb3V0Lg==" },
+          { "3rd Law of Hacking: the last blow counts most.", 
+            "M3JkIExhdyBvZiBIYWNraW5nOiB0aGUgbGFzdCBibG93IGNvdW50cyBtb3N0Lg==" },
+          { "4th Law of Hacking: you will find the exit at the entrance.", 
+            "NHRoIExhdyBvZiBIYWNraW5nOiB5b3Ugd2lsbCBmaW5kIHRoZSBleGl0IGF0IHRoZSBlbnRyYW5jZS4=" },
+          { "A chameleon imitating a mail daemon often delivers scrolls of fire.", 
+            "QSBjaGFtZWxlb24gaW1pdGF0aW5nIGEgbWFpbCBkYWVtb24gb2Z0ZW4gZGVsaXZlcnMgc2Nyb2xscyBvZiBmaXJlLg==" },
+          { "A cockatrice corpse is guaranteed to be untainted!", 
+            "QSBjb2NrYXRyaWNlIGNvcnBzZSBpcyBndWFyYW50ZWVkIHRvIGJlIHVudGFpbnRlZCE=" },
+          { "A dead cockatrice is just a dead lizard.", 
+            "QSBkZWFkIGNvY2thdHJpY2UgaXMganVzdCBhIGRlYWQgbGl6YXJkLg==" },
+          { "A dragon is just a snake that ate a scroll of fire.", 
+            "QSBkcmFnb24gaXMganVzdCBhIHNuYWtlIHRoYXQgYXRlIGEgc2Nyb2xsIG9mIGZpcmUu" },
+          { "A fading corridor enlightens your insight.", 
+            "QSBmYWRpbmcgY29ycmlkb3IgZW5saWdodGVucyB5b3VyIGluc2lnaHQu" },
+          { "A glowing potion is too hot to drink.", 
+            "QSBnbG93aW5nIHBvdGlvbiBpcyB0b28gaG90IHRvIGRyaW5rLg==" },
+          { "A good amulet may protect you against guards.", 
+            "QSBnb29kIGFtdWxldCBtYXkgcHJvdGVjdCB5b3UgYWdhaW5zdCBndWFyZHMu" },
+          { "A lizard corpse is a good thing to turn undead.", 
+            "QSBsaXphcmQgY29ycHNlIGlzIGEgZ29vZCB0aGluZyB0byB0dXJuIHVuZGVhZC4=" },
+          { "A long worm can be defined recursively. So how should you attack it?", 
+            "QSBsb25nIHdvcm0gY2FuIGJlIGRlZmluZWQgcmVjdXJzaXZlbHkuIFNvIGhvdyBzaG91bGQgeW91IGF0dGFjayBpdD8=" },
+          { "A monstrous mind is a toy forever.", 
+            "QSBtb25zdHJvdXMgbWluZCBpcyBhIHRveSBmb3JldmVyLg==" },
+          { "A nymph will be very pleased if you call her by her real name: Lorelei.", 
+            "QSBueW1waCB3aWxsIGJlIHZlcnkgcGxlYXNlZCBpZiB5b3UgY2FsbCBoZXIgYnkgaGVyIHJlYWwgbmFtZTogTG9yZWxlaS4=" },
+          { "A ring of dungeon master control is a great find.", 
+            "QSByaW5nIG9mIGR1bmdlb24gbWFzdGVyIGNvbnRyb2wgaXMgYSBncmVhdCBmaW5kLg==" },
+          { "A ring of extra ring finger is useless if not enchanted.", 
+            "QSByaW5nIG9mIGV4dHJhIHJpbmcgZmluZ2VyIGlzIHVzZWxlc3MgaWYgbm90IGVuY2hhbnRlZC4=" },
+          { "A rope may form a trail in a maze.", 
+            "QSByb3BlIG1heSBmb3JtIGEgdHJhaWwgaW4gYSBtYXplLg==" },
+          { "A staff may recharge if you drop it for awhile.", 
+            "QSBzdGFmZiBtYXkgcmVjaGFyZ2UgaWYgeW91IGRyb3AgaXQgZm9yIGF3aGlsZS4=" },
+          { "A visit to the Zoo is very educational; you meet interesting animals.", 
+            "QSB2aXNpdCB0byB0aGUgWm9vIGlzIHZlcnkgZWR1Y2F0aW9uYWw7IHlvdSBtZWV0IGludGVyZXN0aW5nIGFuaW1hbHMu" },
+          { "A wand of deaf is a more dangerous weapon than a wand of sheep.", 
+            "QSB3YW5kIG9mIGRlYWYgaXMgYSBtb3JlIGRhbmdlcm91cyB3ZWFwb24gdGhhbiBhIHdhbmQgb2Ygc2hlZXAu" },
+          { "A wand of vibration might bring the whole cave crashing about your ears.", 
+            "QSB3YW5kIG9mIHZpYnJhdGlvbiBtaWdodCBicmluZyB0aGUgd2hvbGUgY2F2ZSBjcmFzaGluZyBhYm91dCB5b3VyIGVhcnMu" },
+          { "A winner never quits. A quitter never wins.", 
+            "QSB3aW5uZXIgbmV2ZXIgcXVpdHMuIEEgcXVpdHRlciBuZXZlciB3aW5zLg==" },
+          { "A wish? Okay, make me a fortune cookie!", 
+            "QSB3aXNoPyBPa2F5LCBtYWtlIG1lIGEgZm9ydHVuZSBjb29raWUh" },
+          { "Afraid of mimics? Try to wear a ring of true seeing.", 
+            "QWZyYWlkIG9mIG1pbWljcz8gVHJ5IHRvIHdlYXIgYSByaW5nIG9mIHRydWUgc2VlaW5nLg==" },
+          { "All monsters are created evil, but some are more evil than others.", 
+            "QWxsIG1vbnN0ZXJzIGFyZSBjcmVhdGVkIGV2aWwsIGJ1dCBzb21lIGFyZSBtb3JlIGV2aWwgdGhhbiBvdGhlcnMu" },
+          { "Always attack a floating eye from behind!", 
+            "QWx3YXlzIGF0dGFjayBhIGZsb2F0aW5nIGV5ZSBmcm9tIGJlaGluZCE=" },
+          { "An elven cloak is always the height of fashion.", 
+            "QW4gZWx2ZW4gY2xvYWsgaXMgYWx3YXlzIHRoZSBoZWlnaHQgb2YgZmFzaGlvbi4=" },
+          { "Any small object that is accidentally dropped will hide under a larger object.", 
+            "QW55IHNtYWxsIG9iamVjdCB0aGF0IGlzIGFjY2lkZW50YWxseSBkcm9wcGVkIHdpbGwgaGlkZSB1bmRlciBhIGxhcmdlciBvYmplY3Qu" },
+          { "Balrogs do not appear above level 20.", 
+            "QmFscm9ncyBkbyBub3QgYXBwZWFyIGFib3ZlIGxldmVsIDIwLg==" },
+          { "Banana peels work especially well against Keystone Kops.", 
+            "QmFuYW5hIHBlZWxzIHdvcmsgZXNwZWNpYWxseSB3ZWxsIGFnYWluc3QgS2V5c3RvbmUgS29wcy4=" },
+          { "Be careful when eating bananas. Monsters might slip on the peels.", 
+            "QmUgY2FyZWZ1bCB3aGVuIGVhdGluZyBiYW5hbmFzLiBNb25zdGVycyBtaWdodCBzbGlwIG9uIHRoZSBwZWVscy4=" },
+          { "Better leave the dungeon; otherwise you might get hurt badly.", 
+            "QmV0dGVyIGxlYXZlIHRoZSBkdW5nZW9uOyBvdGhlcndpc2UgeW91IG1pZ2h0IGdldCBodXJ0IGJhZGx5Lg==" },
+          { "Beware of the potion of nitroglycerin -- it's not for the weak of heart.", 
+            "QmV3YXJlIG9mIHRoZSBwb3Rpb24gb2Ygbml0cm9nbHljZXJpbiAtLSBpdCdzIG5vdCBmb3IgdGhlIHdlYWsgb2YgaGVhcnQu" },
+          { "Beware: there's always a chance that your wand explodes as you try to zap it!", 
+            "QmV3YXJlOiB0aGVyZSdzIGFsd2F5cyBhIGNoYW5jZSB0aGF0IHlvdXIgd2FuZCBleHBsb2RlcyBhcyB5b3UgdHJ5IHRvIHphcCBpdCE=" },
+          { "Beyond the 23rd level lies a happy retirement in a room of your own.", 
+            "QmV5b25kIHRoZSAyM3JkIGxldmVsIGxpZXMgYSBoYXBweSByZXRpcmVtZW50IGluIGEgcm9vbSBvZiB5b3VyIG93bi4=" },
+          { "Changing your suit without dropping your sword? You must be kidding!", 
+            "Q2hhbmdpbmcgeW91ciBzdWl0IHdpdGhvdXQgZHJvcHBpbmcgeW91ciBzd29yZD8gWW91IG11c3QgYmUga2lkZGluZyE=" },
+          { "Cockatrices might turn themselves to stone faced with a mirror.", 
+            "Q29ja2F0cmljZXMgbWlnaHQgdHVybiB0aGVtc2VsdmVzIHRvIHN0b25lIGZhY2VkIHdpdGggYSBtaXJyb3Iu" },
+          { "Consumption of home-made food is strictly forbidden in this dungeon.", 
+            "Q29uc3VtcHRpb24gb2YgaG9tZS1tYWRlIGZvb2QgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIGluIHRoaXMgZHVuZ2Vvbi4=" },
+          { "Dark room? Your chance to develop your photographs!", 
+            "RGFyayByb29tPyBZb3VyIGNoYW5jZSB0byBkZXZlbG9wIHlvdXIgcGhvdG9ncmFwaHMh" },
+          { "Dark rooms are not *completely* dark: just wait and let your eyes adjust...", 
+            "RGFyayByb29tcyBhcmUgbm90ICpjb21wbGV0ZWx5KiBkYXJrOiBqdXN0IHdhaXQgYW5kIGxldCB5b3VyIGV5ZXMgYWRqdXN0Li4u" },
+          { "David London sez, \"Hey guys, *WIELD* a lizard corpse against a cockatrice!\"", 
+            "RGF2aWQgTG9uZG9uIHNleiwgIkhleSBndXlzLCAqV0lFTEQqIGEgbGl6YXJkIGNvcnBzZSBhZ2FpbnN0IGEgY29ja2F0cmljZSEi" },
+          { "Death is just life's way of telling you you've been fired.", 
+            "RGVhdGggaXMganVzdCBsaWZlJ3Mgd2F5IG9mIHRlbGxpbmcgeW91IHlvdSd2ZSBiZWVuIGZpcmVkLg==" },
+          { "Demi-gods don't need any help from the gods.", 
+            "RGVtaS1nb2RzIGRvbid0IG5lZWQgYW55IGhlbHAgZnJvbSB0aGUgZ29kcy4=" },
+          { "Demons *HATE* Priests and Priestesses.", 
+            "RGVtb25zICpIQVRFKiBQcmllc3RzIGFuZCBQcmllc3Rlc3Nlcy4=" },
+          { "Didn't you forget to pay?", 
+            "RGlkbid0IHlvdSBmb3JnZXQgdG8gcGF5Pw==" },
+          { "Didn't your mother tell you not to eat food off the floor?", 
+            "RGlkbid0IHlvdXIgbW90aGVyIHRlbGwgeW91IG5vdCB0byBlYXQgZm9vZCBvZmYgdGhlIGZsb29yPw==" },
+          { "Direct a direct hit on your direct opponent, directing in the right direction.", 
+            "RGlyZWN0IGEgZGlyZWN0IGhpdCBvbiB5b3VyIGRpcmVjdCBvcHBvbmVudCwgZGlyZWN0aW5nIGluIHRoZSByaWdodCBkaXJlY3Rpb24u" },
+          { "Do you want to make more money? Sure, we all do! Join the Fort Ludios guard!", 
+            "RG8geW91IHdhbnQgdG8gbWFrZSBtb3JlIG1vbmV5PyBTdXJlLCB3ZSBhbGwgZG8hIEpvaW4gdGhlIEZvcnQgTHVkaW9zIGd1YXJkIQ==" },
+          { "Don't eat too much: you might start hiccoughing!", 
+            "RG9uJ3QgZWF0IHRvbyBtdWNoOiB5b3UgbWlnaHQgc3RhcnQgaGljY291Z2hpbmch" },
+          { "Don't play hack at your work; your boss might hit you!", 
+            "RG9uJ3QgcGxheSBoYWNrIGF0IHlvdXIgd29yazsgeW91ciBib3NzIG1pZ2h0IGhpdCB5b3Uh" },
+          { "Don't tell a soul you found a secret door, otherwise it isn't a secret anymore.", 
+            "RG9uJ3QgdGVsbCBhIHNvdWwgeW91IGZvdW5kIGEgc2VjcmV0IGRvb3IsIG90aGVyd2lzZSBpdCBpc24ndCBhIHNlY3JldCBhbnltb3JlLg==" },
+          { "Drinking potions of booze may land you in jail if you are under 21.", 
+            "RHJpbmtpbmcgcG90aW9ucyBvZiBib296ZSBtYXkgbGFuZCB5b3UgaW4gamFpbCBpZiB5b3UgYXJlIHVuZGVyIDIxLg==" },
+          { "Drop your vanity and get rid of your jewels! Pickpockets about!", 
+            "RHJvcCB5b3VyIHZhbml0eSBhbmQgZ2V0IHJpZCBvZiB5b3VyIGpld2VscyEgUGlja3BvY2tldHMgYWJvdXQh" },
+          { "Eat 10 cloves of garlic and keep all humans at a two-square distance.", 
+            "RWF0IDEwIGNsb3ZlcyBvZiBnYXJsaWMgYW5kIGtlZXAgYWxsIGh1bWFucyBhdCBhIHR3by1zcXVhcmUgZGlzdGFuY2Uu" },
+          { "Eels hide under mud. Use a unicorn to clear the water and make them visible.", 
+            "RWVscyBoaWRlIHVuZGVyIG11ZC4gVXNlIGEgdW5pY29ybiB0byBjbGVhciB0aGUgd2F0ZXIgYW5kIG1ha2UgdGhlbSB2aXNpYmxlLg==" },
+          { "Engrave your wishes with a wand of wishing.", 
+            "RW5ncmF2ZSB5b3VyIHdpc2hlcyB3aXRoIGEgd2FuZCBvZiB3aXNoaW5nLg==" },
+          { "Eventually you will come to admire the swift elegance of a retreating nymph.", 
+            "RXZlbnR1YWxseSB5b3Ugd2lsbCBjb21lIHRvIGFkbWlyZSB0aGUgc3dpZnQgZWxlZ2FuY2Ugb2YgYSByZXRyZWF0aW5nIG55bXBoLg==" },
+          { "Ever heard hissing outside? I *knew* you hadn't!", 
+            "RXZlciBoZWFyZCBoaXNzaW5nIG91dHNpZGU/IEkgKmtuZXcqIHlvdSBoYWRuJ3Qh" },
+          { "Ever lifted a dragon corpse?", 
+            "RXZlciBsaWZ0ZWQgYSBkcmFnb24gY29ycHNlPw==" },
+          { "Ever seen a leocrotta dancing the tengu?", 
+            "RXZlciBzZWVuIGEgbGVvY3JvdHRhIGRhbmNpbmcgdGhlIHRlbmd1Pw==" },
+          { "Ever seen your weapon glow plaid?", 
+            "RXZlciBzZWVuIHlvdXIgd2VhcG9uIGdsb3cgcGxhaWQ/" },
+          { "Ever tamed a shopkeeper?", 
+            "RXZlciB0YW1lZCBhIHNob3BrZWVwZXI/" },
+          { "Ever tried digging through a Vault Guard?", 
+            "RXZlciB0cmllZCBkaWdnaW5nIHRocm91Z2ggYSBWYXVsdCBHdWFyZD8=" },
+          { "Ever tried enchanting a rope?", 
+            "RXZlciB0cmllZCBlbmNoYW50aW5nIGEgcm9wZT8=" },
+          { "Floating eyes can't stand Hawaiian shirts.", 
+            "RmxvYXRpbmcgZXllcyBjYW4ndCBzdGFuZCBIYXdhaWlhbiBzaGlydHMu" },
+          { "For any remedy there is a misery.", 
+            "Rm9yIGFueSByZW1lZHkgdGhlcmUgaXMgYSBtaXNlcnku" },
+          { "Giant bats turn into giant vampires.", 
+            "R2lhbnQgYmF0cyB0dXJuIGludG8gZ2lhbnQgdmFtcGlyZXMu" },
+          { "Good day for overcoming obstacles. Try a steeplechase.", 
+            "R29vZCBkYXkgZm9yIG92ZXJjb21pbmcgb2JzdGFjbGVzLiBUcnkgYSBzdGVlcGxlY2hhc2Uu" },
+          { "Half Moon tonight. (At least it's better than no Moon at all.)", 
+            "SGFsZiBNb29uIHRvbmlnaHQuIChBdCBsZWFzdCBpdCdzIGJldHRlciB0aGFuIG5vIE1vb24gYXQgYWxsLik=" },
+          { "Help! I'm being held prisoner in a fortune cookie factory!", 
+            "SGVscCEgSSdtIGJlaW5nIGhlbGQgcHJpc29uZXIgaW4gYSBmb3J0dW5lIGNvb2tpZSBmYWN0b3J5IQ==" },
+          { "Housecats have nine lives, kittens only one.", 
+            "SG91c2VjYXRzIGhhdmUgbmluZSBsaXZlcywga2l0dGVucyBvbmx5IG9uZS4=" },
+          { "How long can you tread water?", 
+            "SG93IGxvbmcgY2FuIHlvdSB0cmVhZCB3YXRlcj8=" },
+          { "Hungry? There is an abundance of food on the next level.", 
+            "SHVuZ3J5PyBUaGVyZSBpcyBhbiBhYnVuZGFuY2Ugb2YgZm9vZCBvbiB0aGUgbmV4dCBsZXZlbC4=" },
+          { "I guess you've never hit a mail daemon with the Amulet of Yendor...", 
+            "SSBndWVzcyB5b3UndmUgbmV2ZXIgaGl0IGEgbWFpbCBkYWVtb24gd2l0aCB0aGUgQW11bGV0IG9mIFllbmRvci4uLg==" },
+          { "If you are the shopkeeper, you can take things for free.", 
+            "SWYgeW91IGFyZSB0aGUgc2hvcGtlZXBlciwgeW91IGNhbiB0YWtlIHRoaW5ncyBmb3IgZnJlZS4=" },
+          { "If you can't learn to do it well, learn to enjoy doing it badly.", 
+            "SWYgeW91IGNhbid0IGxlYXJuIHRvIGRvIGl0IHdlbGwsIGxlYXJuIHRvIGVuam95IGRvaW5nIGl0IGJhZGx5Lg==" },
+          { "If you thought the Wizard was bad, just wait till you meet the Warlord!", 
+            "SWYgeW91IHRob3VnaHQgdGhlIFdpemFyZCB3YXMgYmFkLCBqdXN0IHdhaXQgdGlsbCB5b3UgbWVldCB0aGUgV2FybG9yZCE=" },
+          { "If you turn blind, don't expect your dog to be turned into a seeing-eye dog.", 
+            "SWYgeW91IHR1cm4gYmxpbmQsIGRvbid0IGV4cGVjdCB5b3VyIGRvZyB0byBiZSB0dXJuZWQgaW50byBhIHNlZWluZy1leWUgZG9nLg==" },
+          { "If you want to feel great, you must eat something real big.", 
+            "SWYgeW91IHdhbnQgdG8gZmVlbCBncmVhdCwgeW91IG11c3QgZWF0IHNvbWV0aGluZyByZWFsIGJpZy4=" },
+          { "If you want to float, you'd better eat a floating eye.", 
+            "SWYgeW91IHdhbnQgdG8gZmxvYXQsIHlvdSdkIGJldHRlciBlYXQgYSBmbG9hdGluZyBleWUu" },
+          { "If your ghost kills a player, it increases your score.", 
+            "SWYgeW91ciBnaG9zdCBraWxscyBhIHBsYXllciwgaXQgaW5jcmVhc2VzIHlvdXIgc2NvcmUu" },
+          { "Increase mindpower: Tame your own ghost!", 
+            "SW5jcmVhc2UgbWluZHBvd2VyOiBUYW1lIHlvdXIgb3duIGdob3N0IQ==" },
+          { "It furthers one to see the great man.", 
+            "SXQgZnVydGhlcnMgb25lIHRvIHNlZSB0aGUgZ3JlYXQgbWFuLg==" },
+          { "It's easy to overlook a monster in a wood.", 
+            "SXQncyBlYXN5IHRvIG92ZXJsb29rIGEgbW9uc3RlciBpbiBhIHdvb2Qu" },
+          { "Just below any trapdoor there may be another one. Just keep falling!", 
+            "SnVzdCBiZWxvdyBhbnkgdHJhcGRvb3IgdGhlcmUgbWF5IGJlIGFub3RoZXIgb25lLiBKdXN0IGtlZXAgZmFsbGluZyE=" },
+          { "Katanas are very sharp; watch you don't cut yourself.", 
+            "S2F0YW5hcyBhcmUgdmVyeSBzaGFycDsgd2F0Y2ggeW91IGRvbid0IGN1dCB5b3Vyc2VsZi4=" },
+          { "Keep a clear mind: quaff clear potions.", 
+            "S2VlcCBhIGNsZWFyIG1pbmQ6IHF1YWZmIGNsZWFyIHBvdGlvbnMu" },
+          { "Kicking the terminal doesn't hurt the monsters.", 
+            "S2lja2luZyB0aGUgdGVybWluYWwgZG9lc24ndCBodXJ0IHRoZSBtb25zdGVycy4=" },
+          { "Killer bees keep appearing till you kill their queen.", 
+            "S2lsbGVyIGJlZXMga2VlcCBhcHBlYXJpbmcgdGlsbCB5b3Uga2lsbCB0aGVpciBxdWVlbi4=" },
+          { "Killer bunnies can be tamed with carrots only.", 
+            "S2lsbGVyIGJ1bm5pZXMgY2FuIGJlIHRhbWVkIHdpdGggY2Fycm90cyBvbmx5Lg==" },
+          { "Latest news? Put `rec.games.roguelike.nethack' in your .newsrc!", 
+            "TGF0ZXN0IG5ld3M/IFB1dCBgcmVjLmdhbWVzLnJvZ3VlbGlrZS5uZXRoYWNrJyBpbiB5b3VyIC5uZXdzcmMh" },
+          { "Learn how to spell. Play NetHack!", 
+            "TGVhcm4gaG93IHRvIHNwZWxsLiBQbGF5IE5ldEhhY2sh" },
+          { "Leprechauns hide their gold in a secret room.", 
+            "TGVwcmVjaGF1bnMgaGlkZSB0aGVpciBnb2xkIGluIGEgc2VjcmV0IHJvb20u" },
+          { "Let your fingers do the walking on the yulkjhnb keys.", 
+            "TGV0IHlvdXIgZmluZ2VycyBkbyB0aGUgd2Fsa2luZyBvbiB0aGUgeXVsa2pobmIga2V5cy4=" },
+          { "Let's face it: this time you're not going to win.", 
+            "TGV0J3MgZmFjZSBpdDogdGhpcyB0aW1lIHlvdSdyZSBub3QgZ29pbmcgdG8gd2luLg==" },
+          { "Let's have a party, drink a lot of booze.", 
+            "TGV0J3MgaGF2ZSBhIHBhcnR5LCBkcmluayBhIGxvdCBvZiBib296ZS4=" },
+          { "Liquor sellers do not drink; they hate to see you twice.", 
+            "TGlxdW9yIHNlbGxlcnMgZG8gbm90IGRyaW5rOyB0aGV5IGhhdGUgdG8gc2VlIHlvdSB0d2ljZS4=" },
+          { "Lunar eclipse tonight. May as well quit now!", 
+            "THVuYXIgZWNsaXBzZSB0b25pZ2h0LiBNYXkgYXMgd2VsbCBxdWl0IG5vdyE=" },
+          { "Meeting your own ghost decreases your luck considerably!", 
+            "TWVldGluZyB5b3VyIG93biBnaG9zdCBkZWNyZWFzZXMgeW91ciBsdWNrIGNvbnNpZGVyYWJseSE=" },
+          { "Money to invest? Take it to the local branch of the Magic Memory Vault!", 
+            "TW9uZXkgdG8gaW52ZXN0PyBUYWtlIGl0IHRvIHRoZSBsb2NhbCBicmFuY2ggb2YgdGhlIE1hZ2ljIE1lbW9yeSBWYXVsdCE=" },
+          { "Monsters come from nowhere to hit you everywhere.", 
+            "TW9uc3RlcnMgY29tZSBmcm9tIG5vd2hlcmUgdG8gaGl0IHlvdSBldmVyeXdoZXJlLg==" },
+          { "Monsters sleep because you are boring, not because they ever get tired.", 
+            "TW9uc3RlcnMgc2xlZXAgYmVjYXVzZSB5b3UgYXJlIGJvcmluZywgbm90IGJlY2F1c2UgdGhleSBldmVyIGdldCB0aXJlZC4=" },
+          { "Most monsters prefer minced meat. That's why they are hitting you!", 
+            "TW9zdCBtb25zdGVycyBwcmVmZXIgbWluY2VkIG1lYXQuIFRoYXQncyB3aHkgdGhleSBhcmUgaGl0dGluZyB5b3Uh" },
+          { "Most of the bugs in NetHack are on the floor.", 
+            "TW9zdCBvZiB0aGUgYnVncyBpbiBOZXRIYWNrIGFyZSBvbiB0aGUgZmxvb3Iu" },
+          { "Much ado Nothing Happens.", 
+            "TXVjaCBhZG8gTm90aGluZyBIYXBwZW5zLg==" },
+          { "Multi-player NetHack is a myth.", 
+            "TXVsdGktcGxheWVyIE5ldEhhY2sgaXMgYSBteXRoLg==" },
+          { "NetHack is addictive. Too late, you're already hooked.", 
+            "TmV0SGFjayBpcyBhZGRpY3RpdmUuIFRvbyBsYXRlLCB5b3UncmUgYWxyZWFkeSBob29rZWQu" },
+          { "Never ask a shopkeeper for a price list.", 
+            "TmV2ZXIgYXNrIGEgc2hvcGtlZXBlciBmb3IgYSBwcmljZSBsaXN0Lg==" },
+          { "Never burn a tree, unless you like getting whacked with a +5 shovel.", 
+            "TmV2ZXIgYnVybiBhIHRyZWUsIHVubGVzcyB5b3UgbGlrZSBnZXR0aW5nIHdoYWNrZWQgd2l0aCBhICs1IHNob3ZlbC4=" },
+          { "Never eat with glowing hands!", 
+            "TmV2ZXIgZWF0IHdpdGggZ2xvd2luZyBoYW5kcyE=" },
+          { "Never mind the monsters hitting you: they just replace the charwomen.", 
+            "TmV2ZXIgbWluZCB0aGUgbW9uc3RlcnMgaGl0dGluZyB5b3U6IHRoZXkganVzdCByZXBsYWNlIHRoZSBjaGFyd29tZW4u" },
+          { "Never play leapfrog with a unicorn.", 
+            "TmV2ZXIgcGxheSBsZWFwZnJvZyB3aXRoIGEgdW5pY29ybi4=" },
+          { "Never step on a cursed engraving.", 
+            "TmV2ZXIgc3RlcCBvbiBhIGN1cnNlZCBlbmdyYXZpbmcu" },
+          { "Never swim with a camera: there's nothing to take pictures of.", 
+            "TmV2ZXIgc3dpbSB3aXRoIGEgY2FtZXJhOiB0aGVyZSdzIG5vdGhpbmcgdG8gdGFrZSBwaWN0dXJlcyBvZi4=" },
+          { "Never teach your pet rust monster to fetch.", 
+            "TmV2ZXIgdGVhY2ggeW91ciBwZXQgcnVzdCBtb25zdGVyIHRvIGZldGNoLg==" },
+          { "Never trust a random generator in magic fields.", 
+            "TmV2ZXIgdHJ1c3QgYSByYW5kb20gZ2VuZXJhdG9yIGluIG1hZ2ljIGZpZWxkcy4=" },
+          { "Never use a wand of death.", 
+            "TmV2ZXIgdXNlIGEgd2FuZCBvZiBkZWF0aC4=" },
+          { "No level contains two shops. The maze is no level. So...", 
+            "Tm8gbGV2ZWwgY29udGFpbnMgdHdvIHNob3BzLiBUaGUgbWF6ZSBpcyBubyBsZXZlbC4gU28uLi4=" },
+          { "No part of this fortune may be reproduced, stored in a retrieval system, ...", 
+            "Tm8gcGFydCBvZiB0aGlzIGZvcnR1bmUgbWF5IGJlIHJlcHJvZHVjZWQsIHN0b3JlZCBpbiBhIHJldHJpZXZhbCBzeXN0ZW0sIC4uLg==" },
+          { "Not all rumors are as misleading as this one.", 
+            "Tm90IGFsbCBydW1vcnMgYXJlIGFzIG1pc2xlYWRpbmcgYXMgdGhpcyBvbmUu" },
+          { "Nymphs and nurses like beautiful rings.", 
+            "TnltcGhzIGFuZCBudXJzZXMgbGlrZSBiZWF1dGlmdWwgcmluZ3Mu" },
+          { "Nymphs are blondes. Are you a gentleman?", 
+            "TnltcGhzIGFyZSBibG9uZGVzLiBBcmUgeW91IGEgZ2VudGxlbWFuPw==" },
+          { "Offering a unicorn a worthless piece of glass might prove to be fatal!", 
+            "T2ZmZXJpbmcgYSB1bmljb3JuIGEgd29ydGhsZXNzIHBpZWNlIG9mIGdsYXNzIG1pZ2h0IHByb3ZlIHRvIGJlIGZhdGFsIQ==" },
+          { "Old hackers never die: young ones do.", 
+            "T2xkIGhhY2tlcnMgbmV2ZXIgZGllOiB5b3VuZyBvbmVzIGRvLg==" },
+          { "One has to leave shops before closing time.", 
+            "T25lIGhhcyB0byBsZWF2ZSBzaG9wcyBiZWZvcmUgY2xvc2luZyB0aW1lLg==" },
+          { "One homunculus a day keeps the doctor away.", 
+            "T25lIGhvbXVuY3VsdXMgYSBkYXkga2VlcHMgdGhlIGRvY3RvciBhd2F5Lg==" },
+          { "One level further down somebody is getting killed, right now.", 
+            "T25lIGxldmVsIGZ1cnRoZXIgZG93biBzb21lYm9keSBpcyBnZXR0aW5nIGtpbGxlZCwgcmlnaHQgbm93Lg==" },
+          { "Only a wizard can use a magic whistle.", 
+            "T25seSBhIHdpemFyZCBjYW4gdXNlIGEgbWFnaWMgd2hpc3RsZS4=" },
+          { "Only adventurers of evil alignment think of killing their dog.", 
+            "T25seSBhZHZlbnR1cmVycyBvZiBldmlsIGFsaWdubWVudCB0aGluayBvZiBraWxsaW5nIHRoZWlyIGRvZy4=" },
+          { "Only chaotic evils kill sleeping monsters.", 
+            "T25seSBjaGFvdGljIGV2aWxzIGtpbGwgc2xlZXBpbmcgbW9uc3RlcnMu" },
+          { "Only real trappers escape traps.", 
+            "T25seSByZWFsIHRyYXBwZXJzIGVzY2FwZSB0cmFwcy4=" },
+          { "Only real wizards can write scrolls.", 
+            "T25seSByZWFsIHdpemFyZHMgY2FuIHdyaXRlIHNjcm9sbHMu" },
+          { "Operation OVERKILL has started now.", 
+            "T3BlcmF0aW9uIE9WRVJLSUxMIGhhcyBzdGFydGVkIG5vdy4=" },
+          { "PLEASE ignore previous rumor.", 
+            "UExFQVNFIGlnbm9yZSBwcmV2aW91cyBydW1vci4=" },
+          { "Polymorph into an ettin; meet your opponents face to face to face.", 
+            "UG9seW1vcnBoIGludG8gYW4gZXR0aW47IG1lZXQgeW91ciBvcHBvbmVudHMgZmFjZSB0byBmYWNlIHRvIGZhY2Uu" },
+          { "Praying will frighten demons.", 
+            "UHJheWluZyB3aWxsIGZyaWdodGVuIGRlbW9ucy4=" },
+          { "Row (3x) that boat gently down the stream, Charon (4x), death is but a dream.", 
+            "Um93ICgzeCkgdGhhdCBib2F0IGdlbnRseSBkb3duIHRoZSBzdHJlYW0sIENoYXJvbiAoNHgpLCBkZWF0aCBpcyBidXQgYSBkcmVhbS4=" },
+          { "Running is good for your legs.", 
+            "UnVubmluZyBpcyBnb29kIGZvciB5b3VyIGxlZ3Mu" },
+          { "Screw up your courage! You've screwed up everything else.", 
+            "U2NyZXcgdXAgeW91ciBjb3VyYWdlISBZb3UndmUgc2NyZXdlZCB1cCBldmVyeXRoaW5nIGVsc2Uu" },
+          { "Seepage? Leaky pipes? Rising damp? Summon the plumber!", 
+            "U2VlcGFnZT8gTGVha3kgcGlwZXM/IFJpc2luZyBkYW1wPyBTdW1tb24gdGhlIHBsdW1iZXIh" },
+          { "Segmentation fault (core dumped).", 
+            "U2VnbWVudGF0aW9uIGZhdWx0IChjb3JlIGR1bXBlZCku" },
+          { "Shopkeepers sometimes die from old age.", 
+            "U2hvcGtlZXBlcnMgc29tZXRpbWVzIGRpZSBmcm9tIG9sZCBhZ2Uu" },
+          { "Some mazes (especially small ones) have no solutions, says man 6 maze.", 
+            "U29tZSBtYXplcyAoZXNwZWNpYWxseSBzbWFsbCBvbmVzKSBoYXZlIG5vIHNvbHV0aW9ucywgc2F5cyBtYW4gNiBtYXplLg==" },
+          { "Some questions the Sphynx asks just *don't* have any answers.", 
+            "U29tZSBxdWVzdGlvbnMgdGhlIFNwaHlueCBhc2tzIGp1c3QgKmRvbid0KiBoYXZlIGFueSBhbnN3ZXJzLg==" },
+          { "Sometimes \"mu\" is the answer.", 
+            "U29tZXRpbWVzICJtdSIgaXMgdGhlIGFuc3dlci4=" },
+          { "Sorry, no fortune this time. Better luck next cookie!", 
+            "U29ycnksIG5vIGZvcnR1bmUgdGhpcyB0aW1lLiBCZXR0ZXIgbHVjayBuZXh0IGNvb2tpZSE=" },
+          { "Spare your scrolls of make-edible until it's really necessary!", 
+            "U3BhcmUgeW91ciBzY3JvbGxzIG9mIG1ha2UtZWRpYmxlIHVudGlsIGl0J3MgcmVhbGx5IG5lY2Vzc2FyeSE=" },
+          { "Suddenly, the dungeon will collapse...", 
+            "U3VkZGVubHksIHRoZSBkdW5nZW9uIHdpbGwgY29sbGFwc2UuLi4=" },
+          { "Taming a mail daemon may cause a system security violation.", 
+            "VGFtaW5nIGEgbWFpbCBkYWVtb24gbWF5IGNhdXNlIGEgc3lzdGVtIHNlY3VyaXR5IHZpb2xhdGlvbi4=" },
+          { "The crowd was so tough, the Stooges won't play the Dungeon anymore, nyuk nyuk.", 
+            "VGhlIGNyb3dkIHdhcyBzbyB0b3VnaCwgdGhlIFN0b29nZXMgd29uJ3QgcGxheSB0aGUgRHVuZ2VvbiBhbnltb3JlLCBueXVrIG55dWsu" },
+          { "The leprechauns hide their treasure in a small hidden room.", 
+            "VGhlIGxlcHJlY2hhdW5zIGhpZGUgdGhlaXIgdHJlYXN1cmUgaW4gYSBzbWFsbCBoaWRkZW4gcm9vbS4=" },
+          { "The longer the wand the better.", 
+            "VGhlIGxvbmdlciB0aGUgd2FuZCB0aGUgYmV0dGVyLg==" },
+          { "The magic word is \"XYZZY\".", 
+            "VGhlIG1hZ2ljIHdvcmQgaXMgIlhZWlpZIi4=" },
+          { "The meek shall inherit your bones files.", 
+            "VGhlIG1lZWsgc2hhbGwgaW5oZXJpdCB5b3VyIGJvbmVzIGZpbGVzLg==" },
+          { "The mines are dark and deep, and I have levels to go before I sleep.", 
+            "VGhlIG1pbmVzIGFyZSBkYXJrIGFuZCBkZWVwLCBhbmQgSSBoYXZlIGxldmVscyB0byBnbyBiZWZvcmUgSSBzbGVlcC4=" },
+          { "The use of dynamite is dangerous.", 
+            "VGhlIHVzZSBvZiBkeW5hbWl0ZSBpcyBkYW5nZXJvdXMu" },
+          { "There are no worms in the UNIX version.", 
+            "VGhlcmUgYXJlIG5vIHdvcm1zIGluIHRoZSBVTklYIHZlcnNpb24u" },
+          { "There is a trap on this level!", 
+            "VGhlcmUgaXMgYSB0cmFwIG9uIHRoaXMgbGV2ZWwh" },
+          { "They say that Demogorgon, Asmodeus, Orcus, Yeenoghu & Juiblex is no law firm.", 
+            "VGhleSBzYXkgdGhhdCBEZW1vZ29yZ29uLCBBc21vZGV1cywgT3JjdXMsIFllZW5vZ2h1ICYgSnVpYmxleCBpcyBubyBsYXcgZmlybS4=" },
+          { "They say that Geryon has an evil twin, beware!", 
+            "VGhleSBzYXkgdGhhdCBHZXJ5b24gaGFzIGFuIGV2aWwgdHdpbiwgYmV3YXJlIQ==" },
+          { "They say that Medusa would make a terrible pet.", 
+            "VGhleSBzYXkgdGhhdCBNZWR1c2Egd291bGQgbWFrZSBhIHRlcnJpYmxlIHBldC4=" },
+          { "They say that NetHack bugs are Seldon planned.", 
+            "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGJ1Z3MgYXJlIFNlbGRvbiBwbGFubmVkLg==" },
+          { "They say that NetHack comes in 256 flavors.", 
+            "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGNvbWVzIGluIDI1NiBmbGF2b3JzLg==" },
+          { "They say that NetHack is just a computer game.", 
+            "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIGp1c3QgYSBjb21wdXRlciBnYW1lLg==" },
+          { "They say that NetHack is more than just a computer game.", 
+            "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIG1vcmUgdGhhbiBqdXN0IGEgY29tcHV0ZXIgZ2FtZS4=" },
+          { "They say that NetHack is never what it used to be.", 
+            "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIG5ldmVyIHdoYXQgaXQgdXNlZCB0byBiZS4=" },
+          { "They say that a baby dragon is too small to hurt or help you.", 
+            "VGhleSBzYXkgdGhhdCBhIGJhYnkgZHJhZ29uIGlzIHRvbyBzbWFsbCB0byBodXJ0IG9yIGhlbHAgeW91Lg==" },
+          { "They say that a black pudding is simply a brown pudding gone bad.", 
+            "VGhleSBzYXkgdGhhdCBhIGJsYWNrIHB1ZGRpbmcgaXMgc2ltcGx5IGEgYnJvd24gcHVkZGluZyBnb25lIGJhZC4=" },
+          { "They say that a black sheep has 3 bags full of wool.", 
+            "VGhleSBzYXkgdGhhdCBhIGJsYWNrIHNoZWVwIGhhcyAzIGJhZ3MgZnVsbCBvZiB3b29sLg==" },
+          { "They say that a blank scroll is like a blank check.", 
+            "VGhleSBzYXkgdGhhdCBhIGJsYW5rIHNjcm9sbCBpcyBsaWtlIGEgYmxhbmsgY2hlY2su" },
+          { "They say that a cat named Morris has nine lives.", 
+            "VGhleSBzYXkgdGhhdCBhIGNhdCBuYW1lZCBNb3JyaXMgaGFzIG5pbmUgbGl2ZXMu" },
+          { "They say that a desperate shopper might pay any price in a shop.", 
+            "VGhleSBzYXkgdGhhdCBhIGRlc3BlcmF0ZSBzaG9wcGVyIG1pZ2h0IHBheSBhbnkgcHJpY2UgaW4gYSBzaG9wLg==" },
+          { "They say that a diamond dog is everybody's best friend.", 
+            "VGhleSBzYXkgdGhhdCBhIGRpYW1vbmQgZG9nIGlzIGV2ZXJ5Ym9keSdzIGJlc3QgZnJpZW5kLg==" },
+          { "They say that a dwarf lord can carry a pick-axe because his armor is light.", 
+            "VGhleSBzYXkgdGhhdCBhIGR3YXJmIGxvcmQgY2FuIGNhcnJ5IGEgcGljay1heGUgYmVjYXVzZSBoaXMgYXJtb3IgaXMgbGlnaHQu" },
+          { "They say that a floating eye can defeat Medusa.", 
+            "VGhleSBzYXkgdGhhdCBhIGZsb2F0aW5nIGV5ZSBjYW4gZGVmZWF0IE1lZHVzYS4=" },
+          { "They say that a fortune only has 1 line and you can't read between it.", 
+            "VGhleSBzYXkgdGhhdCBhIGZvcnR1bmUgb25seSBoYXMgMSBsaW5lIGFuZCB5b3UgY2FuJ3QgcmVhZCBiZXR3ZWVuIGl0Lg==" },
+          { "They say that a fortune only has 1 line, but you can read between it.", 
+            "VGhleSBzYXkgdGhhdCBhIGZvcnR1bmUgb25seSBoYXMgMSBsaW5lLCBidXQgeW91IGNhbiByZWFkIGJldHdlZW4gaXQu" },
+          { "They say that a fountain looks nothing like a regularly erupting geyser.", 
+            "VGhleSBzYXkgdGhhdCBhIGZvdW50YWluIGxvb2tzIG5vdGhpbmcgbGlrZSBhIHJlZ3VsYXJseSBlcnVwdGluZyBnZXlzZXIu" },
+          { "They say that a gold doubloon is worth more than its weight in gold.", 
+            "VGhleSBzYXkgdGhhdCBhIGdvbGQgZG91Ymxvb24gaXMgd29ydGggbW9yZSB0aGFuIGl0cyB3ZWlnaHQgaW4gZ29sZC4=" },
+          { "They say that a grid bug won't pay a shopkeeper for zapping you in a shop.", 
+            "VGhleSBzYXkgdGhhdCBhIGdyaWQgYnVnIHdvbid0IHBheSBhIHNob3BrZWVwZXIgZm9yIHphcHBpbmcgeW91IGluIGEgc2hvcC4=" },
+          { "They say that a gypsy could tell your fortune for a price.", 
+            "VGhleSBzYXkgdGhhdCBhIGd5cHN5IGNvdWxkIHRlbGwgeW91ciBmb3J0dW5lIGZvciBhIHByaWNlLg==" },
+          { "They say that a hacker named Alice once level teleported by using a mirror.", 
+            "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBBbGljZSBvbmNlIGxldmVsIHRlbGVwb3J0ZWQgYnkgdXNpbmcgYSBtaXJyb3Iu" },
+          { "They say that a hacker named David once slew a giant with a sling and a rock.", 
+            "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBEYXZpZCBvbmNlIHNsZXcgYSBnaWFudCB3aXRoIGEgc2xpbmcgYW5kIGEgcm9jay4=" },
+          { "They say that a hacker named Dorothy once rode a fog cloud to Oz.", 
+            "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBEb3JvdGh5IG9uY2Ugcm9kZSBhIGZvZyBjbG91ZCB0byBPei4=" },
+          { "They say that a hacker named Mary once lost a white sheep in the mazes.", 
+            "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBNYXJ5IG9uY2UgbG9zdCBhIHdoaXRlIHNoZWVwIGluIHRoZSBtYXplcy4=" },
+          { "They say that a helm of brilliance is not to be taken lightly.", 
+            "VGhleSBzYXkgdGhhdCBhIGhlbG0gb2YgYnJpbGxpYW5jZSBpcyBub3QgdG8gYmUgdGFrZW4gbGlnaHRseS4=" },
+          { "They say that a hot dog and a hell hound are the same thing.", 
+            "VGhleSBzYXkgdGhhdCBhIGhvdCBkb2cgYW5kIGEgaGVsbCBob3VuZCBhcmUgdGhlIHNhbWUgdGhpbmcu" },
+          { "They say that a lamp named Aladdin's Lamp contains a djinni with 3 wishes.", 
+            "VGhleSBzYXkgdGhhdCBhIGxhbXAgbmFtZWQgQWxhZGRpbidzIExhbXAgY29udGFpbnMgYSBkamlubmkgd2l0aCAzIHdpc2hlcy4=" },
+          { "They say that a large dog named Lassie will lead you to the amulet.", 
+            "VGhleSBzYXkgdGhhdCBhIGxhcmdlIGRvZyBuYW1lZCBMYXNzaWUgd2lsbCBsZWFkIHlvdSB0byB0aGUgYW11bGV0Lg==" },
+          { "They say that a long sword is not a light sword.", 
+            "VGhleSBzYXkgdGhhdCBhIGxvbmcgc3dvcmQgaXMgbm90IGEgbGlnaHQgc3dvcmQu" },
+          { "They say that a manes won't mince words with you.", 
+            "VGhleSBzYXkgdGhhdCBhIG1hbmVzIHdvbid0IG1pbmNlIHdvcmRzIHdpdGggeW91Lg==" },
+          { "They say that a mind is a terrible thing to waste.", 
+            "VGhleSBzYXkgdGhhdCBhIG1pbmQgaXMgYSB0ZXJyaWJsZSB0aGluZyB0byB3YXN0ZS4=" },
+          { "They say that a plain nymph will only wear a wire ring in one ear.", 
+            "VGhleSBzYXkgdGhhdCBhIHBsYWluIG55bXBoIHdpbGwgb25seSB3ZWFyIGEgd2lyZSByaW5nIGluIG9uZSBlYXIu" },
+          { "They say that a plumed hat could be a previously used crested helmet.", 
+            "VGhleSBzYXkgdGhhdCBhIHBsdW1lZCBoYXQgY291bGQgYmUgYSBwcmV2aW91c2x5IHVzZWQgY3Jlc3RlZCBoZWxtZXQu" },
+          { "They say that a potion of oil is difficult to grasp.", 
+            "VGhleSBzYXkgdGhhdCBhIHBvdGlvbiBvZiBvaWwgaXMgZGlmZmljdWx0IHRvIGdyYXNwLg==" },
+          { "They say that a potion of yogurt is a cancelled potion of sickness.", 
+            "VGhleSBzYXkgdGhhdCBhIHBvdGlvbiBvZiB5b2d1cnQgaXMgYSBjYW5jZWxsZWQgcG90aW9uIG9mIHNpY2tuZXNzLg==" },
+          { "They say that a purple worm is not a baby purple dragon.", 
+            "VGhleSBzYXkgdGhhdCBhIHB1cnBsZSB3b3JtIGlzIG5vdCBhIGJhYnkgcHVycGxlIGRyYWdvbi4=" },
+          { "They say that a quivering blob tastes different than a gelatinous cube.", 
+            "VGhleSBzYXkgdGhhdCBhIHF1aXZlcmluZyBibG9iIHRhc3RlcyBkaWZmZXJlbnQgdGhhbiBhIGdlbGF0aW5vdXMgY3ViZS4=" },
+          { "They say that a runed broadsword named Stormbringer attracts vortices.", 
+            "VGhleSBzYXkgdGhhdCBhIHJ1bmVkIGJyb2Fkc3dvcmQgbmFtZWQgU3Rvcm1icmluZ2VyIGF0dHJhY3RzIHZvcnRpY2VzLg==" },
+          { "They say that a scroll of summoning has other names.", 
+            "VGhleSBzYXkgdGhhdCBhIHNjcm9sbCBvZiBzdW1tb25pbmcgaGFzIG90aGVyIG5hbWVzLg==" },
+          { "They say that a shaman can bestow blessings but usually doesn't.", 
+            "VGhleSBzYXkgdGhhdCBhIHNoYW1hbiBjYW4gYmVzdG93IGJsZXNzaW5ncyBidXQgdXN1YWxseSBkb2Vzbid0Lg==" },
+          { "They say that a shaman will bless you for an eye of newt and wing of bat.", 
+            "VGhleSBzYXkgdGhhdCBhIHNoYW1hbiB3aWxsIGJsZXNzIHlvdSBmb3IgYW4gZXllIG9mIG5ld3QgYW5kIHdpbmcgb2YgYmF0Lg==" },
+          { "They say that a shimmering gold shield is not a polished silver shield.", 
+            "VGhleSBzYXkgdGhhdCBhIHNoaW1tZXJpbmcgZ29sZCBzaGllbGQgaXMgbm90IGEgcG9saXNoZWQgc2lsdmVyIHNoaWVsZC4=" },
+          { "They say that a spear will hit a neo-otyugh. (Do YOU know what that is?)", 
+            "VGhleSBzYXkgdGhhdCBhIHNwZWFyIHdpbGwgaGl0IGEgbmVvLW90eXVnaC4gKERvIFlPVSBrbm93IHdoYXQgdGhhdCBpcz8p" },
+          { "They say that a spotted dragon is the ultimate shape changer.", 
+            "VGhleSBzYXkgdGhhdCBhIHNwb3R0ZWQgZHJhZ29uIGlzIHRoZSB1bHRpbWF0ZSBzaGFwZSBjaGFuZ2VyLg==" },
+          { "They say that a stethoscope is no good if you can only hear your heartbeat.", 
+            "VGhleSBzYXkgdGhhdCBhIHN0ZXRob3Njb3BlIGlzIG5vIGdvb2QgaWYgeW91IGNhbiBvbmx5IGhlYXIgeW91ciBoZWFydGJlYXQu" },
+          { "They say that a succubus named Suzy will sometimes warn you of danger.", 
+            "VGhleSBzYXkgdGhhdCBhIHN1Y2N1YnVzIG5hbWVkIFN1enkgd2lsbCBzb21ldGltZXMgd2FybiB5b3Ugb2YgZGFuZ2VyLg==" },
+          { "They say that a wand of cancellation is not like a wand of polymorph.", 
+            "VGhleSBzYXkgdGhhdCBhIHdhbmQgb2YgY2FuY2VsbGF0aW9uIGlzIG5vdCBsaWtlIGEgd2FuZCBvZiBwb2x5bW9ycGgu" },
+          { "They say that a wood golem named Pinocchio would be easy to control.", 
+            "VGhleSBzYXkgdGhhdCBhIHdvb2QgZ29sZW0gbmFtZWQgUGlub2NjaGlvIHdvdWxkIGJlIGVhc3kgdG8gY29udHJvbC4=" },
+          { "They say that after killing a dragon it's time for a change of scenery.", 
+            "VGhleSBzYXkgdGhhdCBhZnRlciBraWxsaW5nIGEgZHJhZ29uIGl0J3MgdGltZSBmb3IgYSBjaGFuZ2Ugb2Ygc2NlbmVyeS4=" },
+          { "They say that an amulet of strangulation is worse than ring around the collar.", 
+            "VGhleSBzYXkgdGhhdCBhbiBhbXVsZXQgb2Ygc3RyYW5ndWxhdGlvbiBpcyB3b3JzZSB0aGFuIHJpbmcgYXJvdW5kIHRoZSBjb2xsYXIu" },
+          { "They say that an attic is the best place to hide your toys.", 
+            "VGhleSBzYXkgdGhhdCBhbiBhdHRpYyBpcyB0aGUgYmVzdCBwbGFjZSB0byBoaWRlIHlvdXIgdG95cy4=" },
+          { "They say that an axe named Cleaver once belonged to a hacker named Beaver.", 
+            "VGhleSBzYXkgdGhhdCBhbiBheGUgbmFtZWQgQ2xlYXZlciBvbmNlIGJlbG9uZ2VkIHRvIGEgaGFja2VyIG5hbWVkIEJlYXZlci4=" },
+          { "They say that an eye of newt and a wing of bat are double the trouble.", 
+            "VGhleSBzYXkgdGhhdCBhbiBleWUgb2YgbmV3dCBhbmQgYSB3aW5nIG9mIGJhdCBhcmUgZG91YmxlIHRoZSB0cm91YmxlLg==" },
+          { "They say that an incubus named Izzy sometimes makes women feel sensitive.", 
+            "VGhleSBzYXkgdGhhdCBhbiBpbmN1YnVzIG5hbWVkIEl6enkgc29tZXRpbWVzIG1ha2VzIHdvbWVuIGZlZWwgc2Vuc2l0aXZlLg==" },
+          { "They say that an opulent throne room is rarely a place to wish you'd be in.", 
+            "VGhleSBzYXkgdGhhdCBhbiBvcHVsZW50IHRocm9uZSByb29tIGlzIHJhcmVseSBhIHBsYWNlIHRvIHdpc2ggeW91J2QgYmUgaW4u" },
+          { "They say that an unlucky hacker once had a nose bleed at an altar and died.", 
+            "VGhleSBzYXkgdGhhdCBhbiB1bmx1Y2t5IGhhY2tlciBvbmNlIGhhZCBhIG5vc2UgYmxlZWQgYXQgYW4gYWx0YXIgYW5kIGRpZWQu" },
+          { "They say that and they say this but they never say never, never!", 
+            "VGhleSBzYXkgdGhhdCBhbmQgdGhleSBzYXkgdGhpcyBidXQgdGhleSBuZXZlciBzYXkgbmV2ZXIsIG5ldmVyIQ==" },
+          { "They say that any quantum mechanic knows that speed kills.", 
+            "VGhleSBzYXkgdGhhdCBhbnkgcXVhbnR1bSBtZWNoYW5pYyBrbm93cyB0aGF0IHNwZWVkIGtpbGxzLg==" },
+          { "They say that applying a unicorn horn means you've missed the point.", 
+            "VGhleSBzYXkgdGhhdCBhcHBseWluZyBhIHVuaWNvcm4gaG9ybiBtZWFucyB5b3UndmUgbWlzc2VkIHRoZSBwb2ludC4=" },
+          { "They say that blue stones are radioactive, beware.", 
+            "VGhleSBzYXkgdGhhdCBibHVlIHN0b25lcyBhcmUgcmFkaW9hY3RpdmUsIGJld2FyZS4=" },
+          { "They say that building a dungeon is a team effort.", 
+            "VGhleSBzYXkgdGhhdCBidWlsZGluZyBhIGR1bmdlb24gaXMgYSB0ZWFtIGVmZm9ydC4=" },
+          { "They say that chaotic characters never get a kick out of altars.", 
+            "VGhleSBzYXkgdGhhdCBjaGFvdGljIGNoYXJhY3RlcnMgbmV2ZXIgZ2V0IGEga2ljayBvdXQgb2YgYWx0YXJzLg==" },
+          { "They say that collapsing a dungeon often creates a panic.", 
+            "VGhleSBzYXkgdGhhdCBjb2xsYXBzaW5nIGEgZHVuZ2VvbiBvZnRlbiBjcmVhdGVzIGEgcGFuaWMu" },
+          { "They say that counting your eggs before they hatch shows that you care.", 
+            "VGhleSBzYXkgdGhhdCBjb3VudGluZyB5b3VyIGVnZ3MgYmVmb3JlIHRoZXkgaGF0Y2ggc2hvd3MgdGhhdCB5b3UgY2FyZS4=" },
+          { "They say that dipping a bag of tricks in a fountain won't make it an icebox.", 
+            "VGhleSBzYXkgdGhhdCBkaXBwaW5nIGEgYmFnIG9mIHRyaWNrcyBpbiBhIGZvdW50YWluIHdvbid0IG1ha2UgaXQgYW4gaWNlYm94Lg==" },
+          { "They say that dipping an eel and brown mold in hot water makes bouillabaisse.", 
+            "VGhleSBzYXkgdGhhdCBkaXBwaW5nIGFuIGVlbCBhbmQgYnJvd24gbW9sZCBpbiBob3Qgd2F0ZXIgbWFrZXMgYm91aWxsYWJhaXNzZS4=" },
+          { "They say that donating a doubloon is extremely pious charity.", 
+            "VGhleSBzYXkgdGhhdCBkb25hdGluZyBhIGRvdWJsb29uIGlzIGV4dHJlbWVseSBwaW91cyBjaGFyaXR5Lg==" },
+          { "They say that eating royal jelly attracts grizzly owlbears.", 
+            "VGhleSBzYXkgdGhhdCBlYXRpbmcgcm95YWwgamVsbHkgYXR0cmFjdHMgZ3JpenpseSBvd2xiZWFycy4=" },
+          { "They say that eggs, pancakes and juice are just a mundane breakfast.", 
+            "VGhleSBzYXkgdGhhdCBlZ2dzLCBwYW5jYWtlcyBhbmQganVpY2UgYXJlIGp1c3QgYSBtdW5kYW5lIGJyZWFrZmFzdC4=" },
+          { "They say that everyone knows why Medusa stands alone in the dark.", 
+            "VGhleSBzYXkgdGhhdCBldmVyeW9uZSBrbm93cyB3aHkgTWVkdXNhIHN0YW5kcyBhbG9uZSBpbiB0aGUgZGFyay4=" },
+          { "They say that everyone wanted rec.games.hack to undergo a name change.", 
+            "VGhleSBzYXkgdGhhdCBldmVyeW9uZSB3YW50ZWQgcmVjLmdhbWVzLmhhY2sgdG8gdW5kZXJnbyBhIG5hbWUgY2hhbmdlLg==" },
+          { "They say that finding a winning strategy is a deliberate move on your part.", 
+            "VGhleSBzYXkgdGhhdCBmaW5kaW5nIGEgd2lubmluZyBzdHJhdGVneSBpcyBhIGRlbGliZXJhdGUgbW92ZSBvbiB5b3VyIHBhcnQu" },
+          { "They say that finding worthless glass is worth something.", 
+            "VGhleSBzYXkgdGhhdCBmaW5kaW5nIHdvcnRobGVzcyBnbGFzcyBpcyB3b3J0aCBzb21ldGhpbmcu" },
+          { "They say that fortune cookies are food for thought.", 
+            "VGhleSBzYXkgdGhhdCBmb3J0dW5lIGNvb2tpZXMgYXJlIGZvb2QgZm9yIHRob3VnaHQu" },
+          { "They say that gold is only wasted on a pet dragon.", 
+            "VGhleSBzYXkgdGhhdCBnb2xkIGlzIG9ubHkgd2FzdGVkIG9uIGEgcGV0IGRyYWdvbi4=" },
+          { "They say that good things come to those that wait.", 
+            "VGhleSBzYXkgdGhhdCBnb29kIHRoaW5ncyBjb21lIHRvIHRob3NlIHRoYXQgd2FpdC4=" },
+          { "They say that greased objects will slip out of monsters' hands.", 
+            "VGhleSBzYXkgdGhhdCBncmVhc2VkIG9iamVjdHMgd2lsbCBzbGlwIG91dCBvZiBtb25zdGVycycgaGFuZHMu" },
+          { "They say that if you can't spell then you'll wish you had a spell book.", 
+            "VGhleSBzYXkgdGhhdCBpZiB5b3UgY2FuJ3Qgc3BlbGwgdGhlbiB5b3UnbGwgd2lzaCB5b3UgaGFkIGEgc3BlbGwgYm9vay4=" },
+          { "They say that if you live by the sword, you'll die by the sword.", 
+            "VGhleSBzYXkgdGhhdCBpZiB5b3UgbGl2ZSBieSB0aGUgc3dvcmQsIHlvdSdsbCBkaWUgYnkgdGhlIHN3b3JkLg==" },
+          { "They say that if you play like a monster you'll have a better game.", 
+            "VGhleSBzYXkgdGhhdCBpZiB5b3UgcGxheSBsaWtlIGEgbW9uc3RlciB5b3UnbGwgaGF2ZSBhIGJldHRlciBnYW1lLg==" },
+          { "They say that if you sleep with a demon you might awake with a headache.", 
+            "VGhleSBzYXkgdGhhdCBpZiB5b3Ugc2xlZXAgd2l0aCBhIGRlbW9uIHlvdSBtaWdodCBhd2FrZSB3aXRoIGEgaGVhZGFjaGUu" },
+          { "They say that if you step on a crack you could break your mother's back.", 
+            "VGhleSBzYXkgdGhhdCBpZiB5b3Ugc3RlcCBvbiBhIGNyYWNrIHlvdSBjb3VsZCBicmVhayB5b3VyIG1vdGhlcidzIGJhY2su" },
+          { "They say that if you're invisible you can still be heard!", 
+            "VGhleSBzYXkgdGhhdCBpZiB5b3UncmUgaW52aXNpYmxlIHlvdSBjYW4gc3RpbGwgYmUgaGVhcmQh" },
+          { "They say that if you're lucky you can feel the runes on a scroll.", 
+            "VGhleSBzYXkgdGhhdCBpZiB5b3UncmUgbHVja3kgeW91IGNhbiBmZWVsIHRoZSBydW5lcyBvbiBhIHNjcm9sbC4=" },
+          { "They say that in the big picture gold is only small change.", 
+            "VGhleSBzYXkgdGhhdCBpbiB0aGUgYmlnIHBpY3R1cmUgZ29sZCBpcyBvbmx5IHNtYWxsIGNoYW5nZS4=" },
+          { "They say that in the dungeon it's not what you know that really matters.", 
+            "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiBpdCdzIG5vdCB3aGF0IHlvdSBrbm93IHRoYXQgcmVhbGx5IG1hdHRlcnMu" },
+          { "They say that in the dungeon moon rocks are really dilithium crystals.", 
+            "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiBtb29uIHJvY2tzIGFyZSByZWFsbHkgZGlsaXRoaXVtIGNyeXN0YWxzLg==" },
+          { "They say that in the dungeon the boorish customer is never right.", 
+            "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB0aGUgYm9vcmlzaCBjdXN0b21lciBpcyBuZXZlciByaWdodC4=" },
+          { "They say that in the dungeon you don't need a watch to tell time.", 
+            "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3UgZG9uJ3QgbmVlZCBhIHdhdGNoIHRvIHRlbGwgdGltZS4=" },
+          { "They say that in the dungeon you need something old, new, burrowed and blue.", 
+            "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3UgbmVlZCBzb21ldGhpbmcgb2xkLCBuZXcsIGJ1cnJvd2VkIGFuZCBibHVlLg==" },
+          { "They say that in the dungeon you should always count your blessings.", 
+            "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3Ugc2hvdWxkIGFsd2F5cyBjb3VudCB5b3VyIGJsZXNzaW5ncy4=" },
+          { "They say that iron golem plate mail isn't worth wishing for.", 
+            "VGhleSBzYXkgdGhhdCBpcm9uIGdvbGVtIHBsYXRlIG1haWwgaXNuJ3Qgd29ydGggd2lzaGluZyBmb3Iu" },
+          { "They say that it takes four quarterstaffs to make one staff.", 
+            "VGhleSBzYXkgdGhhdCBpdCB0YWtlcyBmb3VyIHF1YXJ0ZXJzdGFmZnMgdG8gbWFrZSBvbmUgc3RhZmYu" },
+          { "They say that it's not over till the fat ladies sing.", 
+            "VGhleSBzYXkgdGhhdCBpdCdzIG5vdCBvdmVyIHRpbGwgdGhlIGZhdCBsYWRpZXMgc2luZy4=" },
+          { "They say that it's not over till the fat lady shouts `Off with its head'.", 
+            "VGhleSBzYXkgdGhhdCBpdCdzIG5vdCBvdmVyIHRpbGwgdGhlIGZhdCBsYWR5IHNob3V0cyBgT2ZmIHdpdGggaXRzIGhlYWQnLg==" },
+          { "They say that kicking a heavy statue is really a dumb move.", 
+            "VGhleSBzYXkgdGhhdCBraWNraW5nIGEgaGVhdnkgc3RhdHVlIGlzIHJlYWxseSBhIGR1bWIgbW92ZS4=" },
+          { "They say that kicking a valuable gem doesn't seem to make sense.", 
+            "VGhleSBzYXkgdGhhdCBraWNraW5nIGEgdmFsdWFibGUgZ2VtIGRvZXNuJ3Qgc2VlbSB0byBtYWtlIHNlbnNlLg==" },
+          { "They say that leprechauns know Latin and you should too.", 
+            "VGhleSBzYXkgdGhhdCBsZXByZWNoYXVucyBrbm93IExhdGluIGFuZCB5b3Ugc2hvdWxkIHRvby4=" },
+          { "They say that minotaurs get lost outside of the mazes.", 
+            "VGhleSBzYXkgdGhhdCBtaW5vdGF1cnMgZ2V0IGxvc3Qgb3V0c2lkZSBvZiB0aGUgbWF6ZXMu" },
+          { "They say that most trolls are born again.", 
+            "VGhleSBzYXkgdGhhdCBtb3N0IHRyb2xscyBhcmUgYm9ybiBhZ2Fpbi4=" },
+          { "They say that naming your cat Garfield will make you more attractive.", 
+            "VGhleSBzYXkgdGhhdCBuYW1pbmcgeW91ciBjYXQgR2FyZmllbGQgd2lsbCBtYWtlIHlvdSBtb3JlIGF0dHJhY3RpdmUu" },
+          { "They say that no one knows everything about everything in the dungeon.", 
+            "VGhleSBzYXkgdGhhdCBubyBvbmUga25vd3MgZXZlcnl0aGluZyBhYm91dCBldmVyeXRoaW5nIGluIHRoZSBkdW5nZW9uLg==" },
+          { "They say that no one plays NetHack just for the fun of it.", 
+            "VGhleSBzYXkgdGhhdCBubyBvbmUgcGxheXMgTmV0SGFjayBqdXN0IGZvciB0aGUgZnVuIG9mIGl0Lg==" },
+          { "They say that no one really subscribes to rec.games.roguelike.nethack.", 
+            "VGhleSBzYXkgdGhhdCBubyBvbmUgcmVhbGx5IHN1YnNjcmliZXMgdG8gcmVjLmdhbWVzLnJvZ3VlbGlrZS5uZXRoYWNrLg==" },
+          { "They say that no one will admit to starting a rumor.", 
+            "VGhleSBzYXkgdGhhdCBubyBvbmUgd2lsbCBhZG1pdCB0byBzdGFydGluZyBhIHJ1bW9yLg==" },
+          { "They say that nurses sometimes carry scalpels and never use them.", 
+            "VGhleSBzYXkgdGhhdCBudXJzZXMgc29tZXRpbWVzIGNhcnJ5IHNjYWxwZWxzIGFuZCBuZXZlciB1c2UgdGhlbS4=" },
+          { "They say that once you've met one wizard you've met them all.", 
+            "VGhleSBzYXkgdGhhdCBvbmNlIHlvdSd2ZSBtZXQgb25lIHdpemFyZCB5b3UndmUgbWV0IHRoZW0gYWxsLg==" },
+          { "They say that one troll is worth 10,000 newts.", 
+            "VGhleSBzYXkgdGhhdCBvbmUgdHJvbGwgaXMgd29ydGggMTAsMDAwIG5ld3RzLg==" },
+          { "They say that only David can find the zoo!", 
+            "VGhleSBzYXkgdGhhdCBvbmx5IERhdmlkIGNhbiBmaW5kIHRoZSB6b28h" },
+          { "They say that only angels play their harps for their pets.", 
+            "VGhleSBzYXkgdGhhdCBvbmx5IGFuZ2VscyBwbGF5IHRoZWlyIGhhcnBzIGZvciB0aGVpciBwZXRzLg==" },
+          { "They say that only big spenders carry gold.", 
+            "VGhleSBzYXkgdGhhdCBvbmx5IGJpZyBzcGVuZGVycyBjYXJyeSBnb2xkLg==" },
+          { "They say that orc shamans are healthy, wealthy and wise.", 
+            "VGhleSBzYXkgdGhhdCBvcmMgc2hhbWFucyBhcmUgaGVhbHRoeSwgd2VhbHRoeSBhbmQgd2lzZS4=" },
+          { "They say that playing NetHack is like walking into a death trap.", 
+            "VGhleSBzYXkgdGhhdCBwbGF5aW5nIE5ldEhhY2sgaXMgbGlrZSB3YWxraW5nIGludG8gYSBkZWF0aCB0cmFwLg==" },
+          { "They say that problem breathing is best treated by a proper diet.", 
+            "VGhleSBzYXkgdGhhdCBwcm9ibGVtIGJyZWF0aGluZyBpcyBiZXN0IHRyZWF0ZWQgYnkgYSBwcm9wZXIgZGlldC4=" },
+          { "They say that quaffing many potions of levitation can give you a headache.", 
+            "VGhleSBzYXkgdGhhdCBxdWFmZmluZyBtYW55IHBvdGlvbnMgb2YgbGV2aXRhdGlvbiBjYW4gZ2l2ZSB5b3UgYSBoZWFkYWNoZS4=" },
+          { "They say that queen bees get that way by eating royal jelly.", 
+            "VGhleSBzYXkgdGhhdCBxdWVlbiBiZWVzIGdldCB0aGF0IHdheSBieSBlYXRpbmcgcm95YWwgamVsbHku" },
+          { "They say that reading a scare monster scroll is the same as saying Elbereth.", 
+            "VGhleSBzYXkgdGhhdCByZWFkaW5nIGEgc2NhcmUgbW9uc3RlciBzY3JvbGwgaXMgdGhlIHNhbWUgYXMgc2F5aW5nIEVsYmVyZXRoLg==" },
+          { "They say that real hackers always are controlled.", 
+            "VGhleSBzYXkgdGhhdCByZWFsIGhhY2tlcnMgYWx3YXlzIGFyZSBjb250cm9sbGVkLg==" },
+          { "They say that real hackers never sleep.", 
+            "VGhleSBzYXkgdGhhdCByZWFsIGhhY2tlcnMgbmV2ZXIgc2xlZXAu" },
+          { "They say that shopkeepers are insured by Croesus himself!", 
+            "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBhcmUgaW5zdXJlZCBieSBDcm9lc3VzIGhpbXNlbGYh" },
+          { "They say that shopkeepers never carry more than 20 gold pieces, at night.", 
+            "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBuZXZlciBjYXJyeSBtb3JlIHRoYW4gMjAgZ29sZCBwaWVjZXMsIGF0IG5pZ2h0Lg==" },
+          { "They say that shopkeepers never sell blessed potions of invisibility.", 
+            "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBuZXZlciBzZWxsIGJsZXNzZWQgcG90aW9ucyBvZiBpbnZpc2liaWxpdHku" },
+          { "They say that soldiers wear kid gloves and silly helmets.", 
+            "VGhleSBzYXkgdGhhdCBzb2xkaWVycyB3ZWFyIGtpZCBnbG92ZXMgYW5kIHNpbGx5IGhlbG1ldHMu" },
+          { "They say that some Kops are on the take.", 
+            "VGhleSBzYXkgdGhhdCBzb21lIEtvcHMgYXJlIG9uIHRoZSB0YWtlLg==" },
+          { "They say that some guards' palms can be greased.", 
+            "VGhleSBzYXkgdGhhdCBzb21lIGd1YXJkcycgcGFsbXMgY2FuIGJlIGdyZWFzZWQu" },
+          { "They say that some monsters may kiss your boots to stop your drum playing.", 
+            "VGhleSBzYXkgdGhhdCBzb21lIG1vbnN0ZXJzIG1heSBraXNzIHlvdXIgYm9vdHMgdG8gc3RvcCB5b3VyIGRydW0gcGxheWluZy4=" },
+          { "They say that sometimes you can be the hit of the party when playing a horn.", 
+            "VGhleSBzYXkgdGhhdCBzb21ldGltZXMgeW91IGNhbiBiZSB0aGUgaGl0IG9mIHRoZSBwYXJ0eSB3aGVuIHBsYXlpbmcgYSBob3JuLg==" },
+          { "They say that the NetHack gods generally welcome your sacrifices.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgTmV0SGFjayBnb2RzIGdlbmVyYWxseSB3ZWxjb21lIHlvdXIgc2FjcmlmaWNlcy4=" },
+          { "They say that the Three Rings are named Vilya, Nenya and Narya.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgVGhyZWUgUmluZ3MgYXJlIG5hbWVkIFZpbHlhLCBOZW55YSBhbmQgTmFyeWEu" },
+          { "They say that the Wizard of Yendor has a death wish.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgV2l6YXJkIG9mIFllbmRvciBoYXMgYSBkZWF0aCB3aXNoLg==" },
+          { "They say that the `hair of the dog' is sometimes an effective remedy.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgYGhhaXIgb2YgdGhlIGRvZycgaXMgc29tZXRpbWVzIGFuIGVmZmVjdGl2ZSByZW1lZHku" },
+          { "They say that the best time to save your game is now before its too late.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgYmVzdCB0aW1lIHRvIHNhdmUgeW91ciBnYW1lIGlzIG5vdyBiZWZvcmUgaXRzIHRvbyBsYXRlLg==" },
+          { "They say that the biggest obstacle in NetHack is your mind.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgYmlnZ2VzdCBvYnN0YWNsZSBpbiBOZXRIYWNrIGlzIHlvdXIgbWluZC4=" },
+          { "They say that the gods are angry when they hit you with objects.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgZ29kcyBhcmUgYW5ncnkgd2hlbiB0aGV5IGhpdCB5b3Ugd2l0aCBvYmplY3RzLg==" },
+          { "They say that the priesthood are specially favored by the gods.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgcHJpZXN0aG9vZCBhcmUgc3BlY2lhbGx5IGZhdm9yZWQgYnkgdGhlIGdvZHMu" },
+          { "They say that the way to make a unicorn happy is to give it what it wants.", 
+            "VGhleSBzYXkgdGhhdCB0aGUgd2F5IHRvIG1ha2UgYSB1bmljb3JuIGhhcHB5IGlzIHRvIGdpdmUgaXQgd2hhdCBpdCB3YW50cy4=" },
+          { "They say that there are no black or white stones, only gray.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSBhcmUgbm8gYmxhY2sgb3Igd2hpdGUgc3RvbmVzLCBvbmx5IGdyYXku" },
+          { "They say that there are no skeletons hence there are no skeleton keys.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSBhcmUgbm8gc2tlbGV0b25zIGhlbmNlIHRoZXJlIGFyZSBubyBza2VsZXRvbiBrZXlzLg==" },
+          { "They say that there is a clever rogue in every hacker just dying to escape.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBhIGNsZXZlciByb2d1ZSBpbiBldmVyeSBoYWNrZXIganVzdCBkeWluZyB0byBlc2NhcGUu" },
+          { "They say that there is no such thing as free advice.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBubyBzdWNoIHRoaW5nIGFzIGZyZWUgYWR2aWNlLg==" },
+          { "They say that there is only one way to win at NetHack.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBvbmx5IG9uZSB3YXkgdG8gd2luIGF0IE5ldEhhY2su" },
+          { "They say that there once was a fearsome chaotic samurai named Luk No.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSBvbmNlIHdhcyBhIGZlYXJzb21lIGNoYW90aWMgc2FtdXJhaSBuYW1lZCBMdWsgTm8u" },
+          { "They say that there was a time when cursed holy water wasn't water.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSB3YXMgYSB0aW1lIHdoZW4gY3Vyc2VkIGhvbHkgd2F0ZXIgd2Fzbid0IHdhdGVyLg==" },
+          { "They say that there's no point in crying over a gray ooze.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSdzIG5vIHBvaW50IGluIGNyeWluZyBvdmVyIGEgZ3JheSBvb3plLg==" },
+          { "They say that there's only hope left after you've opened Pandora's box.", 
+            "VGhleSBzYXkgdGhhdCB0aGVyZSdzIG9ubHkgaG9wZSBsZWZ0IGFmdGVyIHlvdSd2ZSBvcGVuZWQgUGFuZG9yYSdzIGJveC4=" },
+          { "They say that trapdoors should always be marked `Caution: Trap Door'.", 
+            "VGhleSBzYXkgdGhhdCB0cmFwZG9vcnMgc2hvdWxkIGFsd2F5cyBiZSBtYXJrZWQgYENhdXRpb246IFRyYXAgRG9vcicu" },
+          { "They say that using an amulet of change isn't a difficult operation.", 
+            "VGhleSBzYXkgdGhhdCB1c2luZyBhbiBhbXVsZXQgb2YgY2hhbmdlIGlzbid0IGEgZGlmZmljdWx0IG9wZXJhdGlvbi4=" },
+          { "They say that water walking boots are better if you are fast like Hermes.", 
+            "VGhleSBzYXkgdGhhdCB3YXRlciB3YWxraW5nIGJvb3RzIGFyZSBiZXR0ZXIgaWYgeW91IGFyZSBmYXN0IGxpa2UgSGVybWVzLg==" },
+          { "They say that when you wear a circular amulet you might resemble a troll.", 
+            "VGhleSBzYXkgdGhhdCB3aGVuIHlvdSB3ZWFyIGEgY2lyY3VsYXIgYW11bGV0IHlvdSBtaWdodCByZXNlbWJsZSBhIHRyb2xsLg==" },
+          { "They say that when you're hungry you can get a pizza in 30 moves or it's free.", 
+            "VGhleSBzYXkgdGhhdCB3aGVuIHlvdSdyZSBodW5ncnkgeW91IGNhbiBnZXQgYSBwaXp6YSBpbiAzMCBtb3ZlcyBvciBpdCdzIGZyZWUu" },
+          { "They say that when your god is angry you should try another one.", 
+            "VGhleSBzYXkgdGhhdCB3aGVuIHlvdXIgZ29kIGlzIGFuZ3J5IHlvdSBzaG91bGQgdHJ5IGFub3RoZXIgb25lLg==" },
+          { "They say that wielding a unicorn horn takes strength.", 
+            "VGhleSBzYXkgdGhhdCB3aWVsZGluZyBhIHVuaWNvcm4gaG9ybiB0YWtlcyBzdHJlbmd0aC4=" },
+          { "They say that with speed boots you never worry about hit and run accidents.", 
+            "VGhleSBzYXkgdGhhdCB3aXRoIHNwZWVkIGJvb3RzIHlvdSBuZXZlciB3b3JyeSBhYm91dCBoaXQgYW5kIHJ1biBhY2NpZGVudHMu" },
+          { "They say that you can defeat a killer bee with a unicorn horn.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2FuIGRlZmVhdCBhIGtpbGxlciBiZWUgd2l0aCBhIHVuaWNvcm4gaG9ybi4=" },
+          { "They say that you can only cross the River Styx in Charon's boat.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkgY3Jvc3MgdGhlIFJpdmVyIFN0eXggaW4gQ2hhcm9uJ3MgYm9hdC4=" },
+          { "They say that you can only kill a lich once and then you'd better be careful.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkga2lsbCBhIGxpY2ggb25jZSBhbmQgdGhlbiB5b3UnZCBiZXR0ZXIgYmUgY2FyZWZ1bC4=" },
+          { "They say that you can only wish for things you've already had.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkgd2lzaCBmb3IgdGhpbmdzIHlvdSd2ZSBhbHJlYWR5IGhhZC4=" },
+          { "They say that you can train a cat by talking gently to it.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRyYWluIGEgY2F0IGJ5IHRhbGtpbmcgZ2VudGx5IHRvIGl0Lg==" },
+          { "They say that you can train a dog by talking firmly to it.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRyYWluIGEgZG9nIGJ5IHRhbGtpbmcgZmlybWx5IHRvIGl0Lg==" },
+          { "They say that you can trust your gold with the king.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRydXN0IHlvdXIgZ29sZCB3aXRoIHRoZSBraW5nLg==" },
+          { "They say that you can't wipe your greasy bare hands on a blank scroll.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2FuJ3Qgd2lwZSB5b3VyIGdyZWFzeSBiYXJlIGhhbmRzIG9uIGEgYmxhbmsgc2Nyb2xsLg==" },
+          { "They say that you cannot trust scrolls of rumor.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY2Fubm90IHRydXN0IHNjcm9sbHMgb2YgcnVtb3Iu" },
+          { "They say that you could fall head over heels for an energy vortex.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgY291bGQgZmFsbCBoZWFkIG92ZXIgaGVlbHMgZm9yIGFuIGVuZXJneSB2b3J0ZXgu" },
+          { "They say that you need a key in order to open locked doors.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgbmVlZCBhIGtleSBpbiBvcmRlciB0byBvcGVuIGxvY2tlZCBkb29ycy4=" },
+          { "They say that you need a mirror to notice a mimic in an antique shop.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgbmVlZCBhIG1pcnJvciB0byBub3RpY2UgYSBtaW1pYyBpbiBhbiBhbnRpcXVlIHNob3Au" },
+          { "They say that you really can use a pick-axe unless you really can't.", 
+            "VGhleSBzYXkgdGhhdCB5b3UgcmVhbGx5IGNhbiB1c2UgYSBwaWNrLWF4ZSB1bmxlc3MgeW91IHJlYWxseSBjYW4ndC4=" },
+          { "They say that you should always store your tools in the cellar.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGFsd2F5cyBzdG9yZSB5b3VyIHRvb2xzIGluIHRoZSBjZWxsYXIu" },
+          { "They say that you should be careful while climbing the ladder to success.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGJlIGNhcmVmdWwgd2hpbGUgY2xpbWJpbmcgdGhlIGxhZGRlciB0byBzdWNjZXNzLg==" },
+          { "They say that you should call your armor `rustproof'.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGNhbGwgeW91ciBhcm1vciBgcnVzdHByb29mJy4=" },
+          { "They say that you should name your dog Spuds to have a cool pet.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5hbWUgeW91ciBkb2cgU3B1ZHMgdG8gaGF2ZSBhIGNvb2wgcGV0Lg==" },
+          { "They say that you should name your weapon after your first monster kill.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5hbWUgeW91ciB3ZWFwb24gYWZ0ZXIgeW91ciBmaXJzdCBtb25zdGVyIGtpbGwu" },
+          { "They say that you should never introduce a rope golem to a succubus.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIGludHJvZHVjZSBhIHJvcGUgZ29sZW0gdG8gYSBzdWNjdWJ1cy4=" },
+          { "They say that you should never sleep near invisible ring wraiths.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIHNsZWVwIG5lYXIgaW52aXNpYmxlIHJpbmcgd3JhaXRocy4=" },
+          { "They say that you should never try to leave the dungeon with a bag of gems.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIHRyeSB0byBsZWF2ZSB0aGUgZHVuZ2VvbiB3aXRoIGEgYmFnIG9mIGdlbXMu" },
+          { "They say that you should remove your armor before sitting on a throne.", 
+            "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIHJlbW92ZSB5b3VyIGFybW9yIGJlZm9yZSBzaXR0aW5nIG9uIGEgdGhyb25lLg==" },
+          { "This fortune cookie is copy protected.", 
+            "VGhpcyBmb3J0dW5lIGNvb2tpZSBpcyBjb3B5IHByb3RlY3RlZC4=" },
+          { "This fortune cookie is the property of Fortune Cookies, Inc.", 
+            "VGhpcyBmb3J0dW5lIGNvb2tpZSBpcyB0aGUgcHJvcGVydHkgb2YgRm9ydHVuZSBDb29raWVzLCBJbmMu" },
+          { "Tired? Try a scroll of charging on yourself.", 
+            "VGlyZWQ/IFRyeSBhIHNjcm9sbCBvZiBjaGFyZ2luZyBvbiB5b3Vyc2VsZi4=" },
+          { "To achieve the next higher rating, you need 3 more points.", 
+            "VG8gYWNoaWV2ZSB0aGUgbmV4dCBoaWdoZXIgcmF0aW5nLCB5b3UgbmVlZCAzIG1vcmUgcG9pbnRzLg==" },
+          { "To reach heaven, escape the dungeon while wearing a ring of levitation.", 
+            "VG8gcmVhY2ggaGVhdmVuLCBlc2NhcGUgdGhlIGR1bmdlb24gd2hpbGUgd2VhcmluZyBhIHJpbmcgb2YgbGV2aXRhdGlvbi4=" },
+          { "Tourists wear shirts loud enough to wake the dead.", 
+            "VG91cmlzdHMgd2VhciBzaGlydHMgbG91ZCBlbm91Z2ggdG8gd2FrZSB0aGUgZGVhZC4=" },
+          { "Try calling your katana Moulinette.", 
+            "VHJ5IGNhbGxpbmcgeW91ciBrYXRhbmEgTW91bGluZXR0ZS4=" },
+          { "Ulch! That meat was painted!", 
+            "VWxjaCEgVGhhdCBtZWF0IHdhcyBwYWludGVkIQ==" },
+          { "Unfortunately, this message was left intentionally blank.", 
+            "VW5mb3J0dW5hdGVseSwgdGhpcyBtZXNzYWdlIHdhcyBsZWZ0IGludGVudGlvbmFsbHkgYmxhbmsu" },
+          { "Using a morning star in the evening has no effect.", 
+            "VXNpbmcgYSBtb3JuaW5nIHN0YXIgaW4gdGhlIGV2ZW5pbmcgaGFzIG5vIGVmZmVjdC4=" },
+          { "Want a hint? Zap a wand of make invisible on your weapon!", 
+            "V2FudCBhIGhpbnQ/IFphcCBhIHdhbmQgb2YgbWFrZSBpbnZpc2libGUgb24geW91ciB3ZWFwb24h" },
+          { "Want to ascend in a hurry? Apply at Gizmonic Institute.", 
+            "V2FudCB0byBhc2NlbmQgaW4gYSBodXJyeT8gQXBwbHkgYXQgR2l6bW9uaWMgSW5zdGl0dXRlLg==" },
+          { "Wanted: shopkeepers. Send a scroll of mail to Mage of Yendor/Level 35/Dungeon.", 
+            "V2FudGVkOiBzaG9wa2VlcGVycy4gU2VuZCBhIHNjcm9sbCBvZiBtYWlsIHRvIE1hZ2Ugb2YgWWVuZG9yL0xldmVsIDM1L0R1bmdlb24u" },
+          { "Warning: fortune reading can be hazardous to your health.", 
+            "V2FybmluZzogZm9ydHVuZSByZWFkaW5nIGNhbiBiZSBoYXphcmRvdXMgdG8geW91ciBoZWFsdGgu" },
+          { "We have new ways of detecting treachery...", 
+            "V2UgaGF2ZSBuZXcgd2F5cyBvZiBkZXRlY3RpbmcgdHJlYWNoZXJ5Li4u" },
+          { "Wet towels make great weapons!", 
+            "V2V0IHRvd2VscyBtYWtlIGdyZWF0IHdlYXBvbnMh" },
+          { "What a pity, you cannot read it!", 
+            "V2hhdCBhIHBpdHksIHlvdSBjYW5ub3QgcmVhZCBpdCE=" },
+          { "When a piercer drops in on you, you will be tempted to hit the ceiling!", 
+            "V2hlbiBhIHBpZXJjZXIgZHJvcHMgaW4gb24geW91LCB5b3Ugd2lsbCBiZSB0ZW1wdGVkIHRvIGhpdCB0aGUgY2VpbGluZyE=" },
+          { "When in a maze follow the right wall and you will never get lost.", 
+            "V2hlbiBpbiBhIG1hemUgZm9sbG93IHRoZSByaWdodCB3YWxsIGFuZCB5b3Ugd2lsbCBuZXZlciBnZXQgbG9zdC4=" },
+          { "When you have a key, you don't have to wait for the guard.", 
+            "V2hlbiB5b3UgaGF2ZSBhIGtleSwgeW91IGRvbid0IGhhdmUgdG8gd2FpdCBmb3IgdGhlIGd1YXJkLg==" },
+          { "Why are you wasting time reading fortunes?", 
+            "V2h5IGFyZSB5b3Ugd2FzdGluZyB0aW1lIHJlYWRpbmcgZm9ydHVuZXM/" },
+          { "Wish for a master key and open the Magic Memory Vault!", 
+            "V2lzaCBmb3IgYSBtYXN0ZXIga2V5IGFuZCBvcGVuIHRoZSBNYWdpYyBNZW1vcnkgVmF1bHQh" },
+          { "Wizard expects every monster to do its duty.", 
+            "V2l6YXJkIGV4cGVjdHMgZXZlcnkgbW9uc3RlciB0byBkbyBpdHMgZHV0eS4=" },
+          { "Wow! You could've had a potion of fruit juice!", 
+            "V293ISBZb3UgY291bGQndmUgaGFkIGEgcG90aW9uIG9mIGZydWl0IGp1aWNlIQ==" },
+          { "Yet Another Silly Message (YASM).", 
+            "WWV0IEFub3RoZXIgU2lsbHkgTWVzc2FnZSAoWUFTTSku" },
+          { "You are destined to be misled by a fortune.", 
+            "WW91IGFyZSBkZXN0aW5lZCB0byBiZSBtaXNsZWQgYnkgYSBmb3J0dW5lLg==" },
+          { "You can get a genuine Amulet of Yendor by doing the following: --More--", 
+            "WW91IGNhbiBnZXQgYSBnZW51aW5lIEFtdWxldCBvZiBZZW5kb3IgYnkgZG9pbmcgdGhlIGZvbGxvd2luZzogLS1Nb3JlLS0=" },
+          { "You can protect yourself from black dragons by doing the following: --More--", 
+            "WW91IGNhbiBwcm90ZWN0IHlvdXJzZWxmIGZyb20gYmxhY2sgZHJhZ29ucyBieSBkb2luZyB0aGUgZm9sbG93aW5nOiAtLU1vcmUtLQ==" },
+          { "You can't get by the snake.", 
+            "WW91IGNhbid0IGdldCBieSB0aGUgc25ha2Uu" },
+          { "You feel like someone is pulling your leg.", 
+            "WW91IGZlZWwgbGlrZSBzb21lb25lIGlzIHB1bGxpbmcgeW91ciBsZWcu" },
+          { "You have to outwit the Sphynx or pay her.", 
+            "WW91IGhhdmUgdG8gb3V0d2l0IHRoZSBTcGh5bnggb3IgcGF5IGhlci4=" },
+          { "You hear the fortune cookie's hissing!", 
+            "WW91IGhlYXIgdGhlIGZvcnR1bmUgY29va2llJ3MgaGlzc2luZyE=" },
+          { "You may get rich selling letters, but beware of being blackmailed!", 
+            "WW91IG1heSBnZXQgcmljaCBzZWxsaW5nIGxldHRlcnMsIGJ1dCBiZXdhcmUgb2YgYmVpbmcgYmxhY2ttYWlsZWQh" },
+          { "You offend Shai-Hulud by sheathing your crysknife without having drawn blood.", 
+            "WW91IG9mZmVuZCBTaGFpLUh1bHVkIGJ5IHNoZWF0aGluZyB5b3VyIGNyeXNrbmlmZSB3aXRob3V0IGhhdmluZyBkcmF3biBibG9vZC4=" },
+          { "You swallowed the fortune!", 
+            "WW91IHN3YWxsb3dlZCB0aGUgZm9ydHVuZSE=" },
+          { "You want to regain strength? Two levels ahead is a guesthouse!", 
+            "WW91IHdhbnQgdG8gcmVnYWluIHN0cmVuZ3RoPyBUd28gbGV2ZWxzIGFoZWFkIGlzIGEgZ3Vlc3Rob3VzZSE=" },
+          { "You will encounter a tall, dark, and gruesome creature...", 
+            "WW91IHdpbGwgZW5jb3VudGVyIGEgdGFsbCwgZGFyaywgYW5kIGdydWVzb21lIGNyZWF0dXJlLi4u" },
+
+          { "The End", "VGhlIEVuZA==" }
+      };
+
+/* PL_Base64Encode, random strings */
+PRBool test_004(void)
+{
+    int i;
+    char result[ 4096 ];
+
+    printf("Test 004 (PL_Base64Encode, random strings)                            ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 plen = PL_strlen(array[i].plaintext);
+        PRUint32 clen = ((plen + 2)/3)*4;
+
+        char *rv = PL_Base64Encode(array[i].plaintext, plen, result);
+
+        if( rv != result )
+        {
+            printf("FAIL\n\t(%d): return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strncmp(result, array[i].cyphertext, clen) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", 
+                   i, array[i].plaintext, array[i].cyphertext, clen, result);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, single characters, malloc */
+PRBool test_005(void)
+{
+    PRUint32 a, b;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char *rv;
+
+    printf("Test 005 (PL_Base64Encode, single characters, malloc)                 ..."); fflush(stdout);
+
+    plain[1] = plain[2] = plain[3] = (unsigned char)0;
+    cypher[2] = cypher[3] = (unsigned char)'=';
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (unsigned char)(a * 4 + b);
+            cypher[1] = base[(b * 16)];
+
+            rv = PL_Base64Encode((char *)plain, 1, (char *)0);
+            if( (char *)0 == rv )
+            {
+                printf("FAIL\n\t(%d, %d): no return value\n", a, b);
+                return PR_FALSE;
+            }
+
+            if( 0 != PL_strcmp((char *)cypher, rv) )
+            {
+                printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n",
+                       a, b, cypher, rv);
+                PR_DELETE(rv);
+                return PR_FALSE;
+            }
+
+            PR_DELETE(rv);
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, double characters, malloc */
+PRBool test_006(void)
+{
+    PRUint32 a, b, c, d;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char *rv;
+
+    printf("Test 006 (PL_Base64Encode, double characters, malloc)                 ..."); fflush(stdout);
+
+    plain[2] = plain[3] = (unsigned char)0;
+    cypher[3] = (unsigned char)'=';
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    cypher[2] = base[d*4];
+
+                    rv = PL_Base64Encode((char *)plain, 2, (char *)0);
+                    if( (char *)0 == rv )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d);
+                        return PR_FALSE;
+                    }
+
+                    if( 0 != PL_strcmp((char *)cypher, rv) )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n",
+                               a, b, c, d, cypher, rv);
+                        PR_DELETE(rv);
+                        return PR_FALSE;
+                    }
+
+                    PR_DELETE(rv);
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, triple characters, malloc */
+PRBool test_007(void)
+{
+    PRUint32 a, b, c, d, e, f;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char *rv;
+
+    printf("Test 007 (PL_Base64Encode, triple characters, malloc)                 ..."); fflush(stdout);
+
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    for( e = 0; e < 4; e++ )
+                    {
+                        cypher[2] = base[d*4 + e];
+                        for( f = 0; f < 64; f++ )
+                        {
+                            plain[2] = e * 64 + f;
+                            cypher[3] = base[f];
+
+                            rv = PL_Base64Encode((char *)plain, 3, (char *)0);
+                            if( (char *)0 == rv )
+                            {
+                                printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): no return value\n", a, b, c, d, e, f);
+                                return PR_FALSE;
+                            }
+
+                            if( 0 != PL_strcmp((char *)cypher, rv) )
+                            {
+                                printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n",
+                                       a, b, c, d, e, f, cypher, rv);
+                                PR_DELETE(rv);
+                                return PR_FALSE;
+                            }
+
+                            PR_DELETE(rv);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings, malloc */
+PRBool test_008(void)
+{
+    int i;
+
+    printf("Test 008 (PL_Base64Encode, random strings, malloc)                    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 plen = PL_strlen(array[i].plaintext);
+        PRUint32 clen = ((plen + 2)/3)*4;
+
+        char *rv = PL_Base64Encode(array[i].plaintext, plen, (char *)0);
+
+        if( (char *)0 == rv )
+        {
+            printf("FAIL\n\t(%d): no return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strcmp(rv, array[i].cyphertext) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", 
+                   i, array[i].plaintext, array[i].cyphertext, rv);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, single characters */
+PRBool test_009(void)
+{
+    PRUint32 a, b;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char result[ 8 ];
+    char *rv;
+
+    printf("Test 009 (PL_Base64Decode, single characters, equals)                 ..."); fflush(stdout);
+
+    plain[1] = plain[2] = plain[3] = (unsigned char)0;
+    cypher[2] = cypher[3] = (unsigned char)'=';
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (unsigned char)(a * 4 + b);
+            cypher[1] = base[(b * 16)];
+
+            rv = PL_Base64Decode((char *)cypher, 4, result);
+            if( rv != result )
+            {
+                printf("FAIL\n\t(%d, %d): return value\n", a, b);
+                return PR_FALSE;
+            }
+
+            if( 0 != PL_strncmp((char *)plain, result, 1) )
+            {
+                printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.1s.\"\n",
+                       a, b, plain, result);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, single characters */
+PRBool test_010(void)
+{
+    PRUint32 a, b;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char result[ 8 ];
+    char *rv;
+
+    printf("Test 010 (PL_Base64Decode, single characters, no equals)              ..."); fflush(stdout);
+
+    plain[1] = plain[2] = plain[3] = (unsigned char)0;
+    cypher[2] = cypher[3] = (unsigned char)0;
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (unsigned char)(a * 4 + b);
+            cypher[1] = base[(b * 16)];
+
+            rv = PL_Base64Decode((char *)cypher, 2, result);
+            if( rv != result )
+            {
+                printf("FAIL\n\t(%d, %d): return value\n", a, b);
+                return PR_FALSE;
+            }
+
+            if( 0 != PL_strncmp((char *)plain, result, 1) )
+            {
+                printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.1s.\"\n",
+                       a, b, plain, result);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, double characters */
+PRBool test_011(void)
+{
+    PRUint32 a, b, c, d;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char result[ 8 ];
+    char *rv;
+
+    printf("Test 011 (PL_Base64Decode, double characters, equals)                 ..."); fflush(stdout);
+
+    plain[2] = plain[3] = (unsigned char)0;
+    cypher[3] = (unsigned char)'=';
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    cypher[2] = base[d*4];
+
+                    rv = PL_Base64Decode((char *)cypher, 4, result);
+                    if( rv != result )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d);
+                        return PR_FALSE;
+                    }
+
+                    if( 0 != PL_strncmp((char *)plain, result, 2) )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.2s.\"\n",
+                               a, b, c, d, plain, result);
+                        return PR_FALSE;
+                    }
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, double characters */
+PRBool test_012(void)
+{
+    PRUint32 a, b, c, d;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char result[ 8 ];
+    char *rv;
+
+    printf("Test 012 (PL_Base64Decode, double characters, no equals)              ..."); fflush(stdout);
+
+    plain[2] = plain[3] = (unsigned char)0;
+    cypher[3] = (unsigned char)0;
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    cypher[2] = base[d*4];
+
+                    rv = PL_Base64Decode((char *)cypher, 3, result);
+                    if( rv != result )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d);
+                        return PR_FALSE;
+                    }
+
+                    if( 0 != PL_strncmp((char *)plain, result, 2) )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.2s.\"\n",
+                               a, b, c, d, cypher, result);
+                        return PR_FALSE;
+                    }
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, triple characters */
+PRBool test_013(void)
+{
+    PRUint32 a, b, c, d, e, f;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char result[ 8 ];
+    char *rv;
+
+    printf("Test 013 (PL_Base64Decode, triple characters)                         ..."); fflush(stdout);
+
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    for( e = 0; e < 4; e++ )
+                    {
+                        cypher[2] = base[d*4 + e];
+                        for( f = 0; f < 64; f++ )
+                        {
+                            plain[2] = e * 64 + f;
+                            cypher[3] = base[f];
+
+                            rv = PL_Base64Decode((char *)cypher, 4, result);
+                            if( rv != result )
+                            {
+                                printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): return value\n", a, b, c, d, e, f);
+                                return PR_FALSE;
+                            }
+
+                            if( 0 != PL_strncmp((char *)plain, result, 3) )
+                            {
+                                printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.3s.\"\n",
+                                       a, b, c, d, e, f, plain, result);
+                                return PR_FALSE;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings */
+PRBool test_014(void)
+{
+    int i;
+    char result[ 4096 ];
+
+    printf("Test 014 (PL_Base64Decode, random strings, equals)                    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 clen = PL_strlen(array[i].cyphertext);
+        PRUint32 plen = (clen * 3) / 4;
+
+        char *rv = PL_Base64Decode(array[i].cyphertext, clen, result);
+
+        if( rv != result )
+        {
+            printf("FAIL\n\t(%d): return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 == (clen & 3) )
+        {
+            if( '=' == array[i].cyphertext[clen-1] )
+            {
+                if( '=' == array[i].cyphertext[clen-2] )
+                {
+                    plen -= 2;
+                }
+                else
+                {
+                    plen -= 1;
+                }
+            }
+        }
+
+        if( 0 != PL_strncmp(result, array[i].plaintext, plen) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", 
+                   i, array[i].cyphertext, array[i].plaintext, plen, result);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings */
+PRBool test_015(void)
+{
+    int i;
+    char buffer[ 4096 ];
+    char result[ 4096 ];
+    char *rv;
+
+    printf("Test 015 (PL_Base64Decode, random strings, no equals)                 ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 clen, plen;
+
+        PL_strcpy(buffer, array[i].cyphertext);
+        clen = PL_strlen(buffer);
+
+        if( 0 == (clen & 3) )
+        {
+            if( '=' == buffer[clen-1] )
+            {
+                if( '=' == buffer[clen-2] )
+                {
+                    buffer[clen-2] = buffer[clen-1] = (char)0;
+                    clen -= 2;
+                }
+                else
+                {
+                    buffer[clen-1] = (char)0;
+                    clen -= 1;
+                }
+            }
+        }
+
+        plen = (clen * 3) / 4;
+
+        rv = PL_Base64Decode(buffer, clen, result);
+
+        if( rv != result )
+        {
+            printf("FAIL\n\t(%d): return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strncmp(result, array[i].plaintext, plen) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", 
+                   i, array[i].cyphertext, array[i].plaintext, plen, result);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, single characters, malloc */
+PRBool test_016(void)
+{
+    PRUint32 a, b;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char *rv;
+
+    printf("Test 016 (PL_Base64Decode, single characters, equals, malloc)         ..."); fflush(stdout);
+
+    plain[1] = plain[2] = plain[3] = (unsigned char)0;
+    cypher[2] = cypher[3] = (unsigned char)'=';
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (unsigned char)(a * 4 + b);
+            cypher[1] = base[(b * 16)];
+
+            rv = PL_Base64Decode((char *)cypher, 4, (char *)0);
+            if( (char *)0 == rv )
+            {
+                printf("FAIL\n\t(%d, %d): no return value\n", a, b);
+                return PR_FALSE;
+            }
+
+            if( 0 != PL_strcmp((char *)plain, rv) )
+            {
+                printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n",
+                       a, b, plain, rv);
+                PR_DELETE(rv);
+                return PR_FALSE;
+            }
+
+            PR_DELETE(rv);
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, single characters, malloc */
+PRBool test_017(void)
+{
+    PRUint32 a, b;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char *rv;
+
+    printf("Test 017 (PL_Base64Decode, single characters, no equals, malloc)      ..."); fflush(stdout);
+
+    plain[1] = plain[2] = plain[3] = (unsigned char)0;
+    cypher[2] = cypher[3] = (unsigned char)0;
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (unsigned char)(a * 4 + b);
+            cypher[1] = base[(b * 16)];
+
+            rv = PL_Base64Decode((char *)cypher, 2, (char *)0);
+            if( (char *)0 == rv )
+            {
+                printf("FAIL\n\t(%d, %d): no return value\n", a, b);
+                return PR_FALSE;
+            }
+
+            if( 0 != PL_strcmp((char *)plain, rv) )
+            {
+                printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n",
+                       a, b, plain, rv);
+                PR_DELETE(rv);
+                return PR_FALSE;
+            }
+
+            PR_DELETE(rv);
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, double characters, malloc */
+PRBool test_018(void)
+{
+    PRUint32 a, b, c, d;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char *rv;
+
+    printf("Test 018 (PL_Base64Decode, double characters, equals, malloc)         ..."); fflush(stdout);
+
+    plain[2] = plain[3] = (unsigned char)0;
+    cypher[3] = (unsigned char)'=';
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    cypher[2] = base[d*4];
+
+                    rv = PL_Base64Decode((char *)cypher, 4, (char *)0);
+                    if( (char *)0 == rv )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d);
+                        return PR_FALSE;
+                    }
+
+                    if( 0 != PL_strcmp((char *)plain, rv) )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n",
+                               a, b, c, d, plain, rv);
+                        PR_DELETE(rv);
+                        return PR_FALSE;
+                    }
+
+                    PR_DELETE(rv);
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, double characters, malloc */
+PRBool test_019(void)
+{
+    PRUint32 a, b, c, d;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char *rv;
+
+    printf("Test 019 (PL_Base64Decode, double characters, no equals, malloc)      ..."); fflush(stdout);
+
+    plain[2] = plain[3] = (unsigned char)0;
+    cypher[3] = (unsigned char)0;
+    cypher[4] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    cypher[2] = base[d*4];
+
+                    rv = PL_Base64Decode((char *)cypher, 3, (char *)0);
+                    if( (char *)0 == rv )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d);
+                        return PR_FALSE;
+                    }
+
+                    if( 0 != PL_strcmp((char *)plain, rv) )
+                    {
+                        printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n",
+                               a, b, c, d, cypher, rv);
+                        PR_DELETE(rv);
+                        return PR_FALSE;
+                    }
+
+                    PR_DELETE(rv);
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, triple characters, malloc */
+PRBool test_020(void)
+{
+    PRUint32 a, b, c, d, e, f;
+    unsigned char plain[ 4 ];
+    unsigned char cypher[ 5 ];
+    char *rv;
+
+    printf("Test 020 (PL_Base64Decode, triple characters, malloc)                 ..."); fflush(stdout);
+
+    cypher[4] = (unsigned char)0;
+    plain[3] = (unsigned char)0;
+
+    for( a = 0; a < 64; a++ )
+    {
+        cypher[0] = base[a];
+        for( b = 0; b < 4; b++ )
+        {
+            plain[0] = (a*4) + b;
+            for( c = 0; c < 16; c++ )
+            {
+                cypher[1] = base[b*16 + c];
+                for( d = 0; d < 16; d++ )
+                {
+                    plain[1] = c*16 + d;
+                    for( e = 0; e < 4; e++ )
+                    {
+                        cypher[2] = base[d*4 + e];
+                        for( f = 0; f < 64; f++ )
+                        {
+                            plain[2] = e * 64 + f;
+                            cypher[3] = base[f];
+
+                            rv = PL_Base64Decode((char *)cypher, 4, (char *)0);
+                            if( (char *)0 == rv )
+                            {
+                                printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): no return value\n", a, b, c, d, e, f);
+                                return PR_FALSE;
+                            }
+
+                            if( 0 != PL_strcmp((char *)plain, rv) )
+                            {
+                                printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.3s.\"\n",
+                                       a, b, c, d, e, f, plain, rv);
+                                PR_DELETE(rv);
+                                return PR_FALSE;
+                            }
+
+                            PR_DELETE(rv);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings, malloc */
+PRBool test_021(void)
+{
+    int i;
+
+    printf("Test 021 (PL_Base64Decode, random strings, equals, malloc)            ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 clen = PL_strlen(array[i].cyphertext);
+
+        char *rv = PL_Base64Decode(array[i].cyphertext, clen, (char *)0);
+
+        if( (char *)0 == rv )
+        {
+            printf("FAIL\n\t(%d): no return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strcmp(rv, array[i].plaintext) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", 
+                   i, array[i].cyphertext, array[i].plaintext, rv);
+            PR_DELETE(rv);
+            return PR_FALSE;
+        }
+
+        PR_DELETE(rv);
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings, malloc */
+PRBool test_022(void)
+{
+    int i;
+    char buffer[ 4096 ];
+    char *rv;
+
+    printf("Test 022 (PL_Base64Decode, random strings, no equals, malloc)         ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 clen;
+
+        PL_strcpy(buffer, array[i].cyphertext);
+        clen = PL_strlen(buffer);
+
+        if( 0 == (clen & 3) )
+        {
+            if( '=' == buffer[clen-1] )
+            {
+                if( '=' == buffer[clen-2] )
+                {
+                    buffer[clen-2] = buffer[clen-1] = (char)0;
+                    clen -= 2;
+                }
+                else
+                {
+                    buffer[clen-1] = (char)0;
+                    clen -= 1;
+                }
+            }
+        }
+
+        rv = PL_Base64Decode(buffer, clen, (char *)0);
+
+        if( (char *)0 == rv )
+        {
+            printf("FAIL\n\t(%d): no return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strcmp(rv, array[i].plaintext) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", 
+                   i, array[i].cyphertext, array[i].plaintext, rv);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings */
+PRBool test_023(void)
+{
+    int i;
+    char result[ 4096 ];
+
+    printf("Test 023 (PL_Base64Encode, random strings, strlen)                    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 plen = PL_strlen(array[i].plaintext);
+        PRUint32 clen = ((plen + 2)/3)*4;
+
+        char *rv = PL_Base64Encode(array[i].plaintext, 0, result);
+
+        if( rv != result )
+        {
+            printf("FAIL\n\t(%d): return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strncmp(result, array[i].cyphertext, clen) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", 
+                   i, array[i].plaintext, array[i].cyphertext, clen, result);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings, malloc */
+PRBool test_024(void)
+{
+    int i;
+
+    printf("Test 024 (PL_Base64Encode, random strings, malloc, strlen)            ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 plen = PL_strlen(array[i].plaintext);
+        PRUint32 clen = ((plen + 2)/3)*4;
+
+        char *rv = PL_Base64Encode(array[i].plaintext, 0, (char *)0);
+
+        if( (char *)0 == rv )
+        {
+            printf("FAIL\n\t(%d): no return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strcmp(rv, array[i].cyphertext) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", 
+                   i, array[i].plaintext, array[i].cyphertext, rv);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings */
+PRBool test_025(void)
+{
+    int i;
+    char result[ 4096 ];
+
+    printf("Test 025 (PL_Base64Decode, random strings, equals, strlen)            ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 clen = PL_strlen(array[i].cyphertext);
+        PRUint32 plen = (clen * 3) / 4;
+
+        char *rv = PL_Base64Decode(array[i].cyphertext, 0, result);
+
+        if( rv != result )
+        {
+            printf("FAIL\n\t(%d): return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 == (clen & 3) )
+        {
+            if( '=' == array[i].cyphertext[clen-1] )
+            {
+                if( '=' == array[i].cyphertext[clen-2] )
+                {
+                    plen -= 2;
+                }
+                else
+                {
+                    plen -= 1;
+                }
+            }
+        }
+
+        if( 0 != PL_strncmp(result, array[i].plaintext, plen) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", 
+                   i, array[i].cyphertext, array[i].plaintext, plen, result);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings */
+PRBool test_026(void)
+{
+    int i;
+    char buffer[ 4096 ];
+    char result[ 4096 ];
+    char *rv;
+
+    printf("Test 026 (PL_Base64Decode, random strings, no equals, strlen)         ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 clen, plen;
+
+        PL_strcpy(buffer, array[i].cyphertext);
+        clen = PL_strlen(buffer);
+
+        if( 0 == (clen & 3) )
+        {
+            if( '=' == buffer[clen-1] )
+            {
+                if( '=' == buffer[clen-2] )
+                {
+                    buffer[clen-2] = buffer[clen-1] = (char)0;
+                    clen -= 2;
+                }
+                else
+                {
+                    buffer[clen-1] = (char)0;
+                    clen -= 1;
+                }
+            }
+        }
+
+        plen = (clen * 3) / 4;
+
+        rv = PL_Base64Decode(buffer, 0, result);
+
+        if( rv != result )
+        {
+            printf("FAIL\n\t(%d): return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strncmp(result, array[i].plaintext, plen) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", 
+                   i, array[i].cyphertext, array[i].plaintext, plen, result);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings, malloc */
+PRBool test_027(void)
+{
+    int i;
+
+    printf("Test 027 (PL_Base64Decode, random strings, equals, malloc, strlen)    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 clen = PL_strlen(array[i].cyphertext);
+
+        char *rv = PL_Base64Decode(array[i].cyphertext, 0, (char *)0);
+
+        if( (char *)0 == rv )
+        {
+            printf("FAIL\n\t(%d): no return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strcmp(rv, array[i].plaintext) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", 
+                   i, array[i].cyphertext, array[i].plaintext, rv);
+            PR_DELETE(rv);
+            return PR_FALSE;
+        }
+
+        PR_DELETE(rv);
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings, malloc */
+PRBool test_028(void)
+{
+    int i;
+    char buffer[ 4096 ];
+    char *rv;
+
+    printf("Test 028 (PL_Base64Decode, random strings, no equals, malloc, strlen) ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRUint32 clen;
+
+        PL_strcpy(buffer, array[i].cyphertext);
+        clen = PL_strlen(buffer);
+
+        if( 0 == (clen & 3) )
+        {
+            if( '=' == buffer[clen-1] )
+            {
+                if( '=' == buffer[clen-2] )
+                {
+                    buffer[clen-2] = buffer[clen-1] = (char)0;
+                    clen -= 2;
+                }
+                else
+                {
+                    buffer[clen-1] = (char)0;
+                    clen -= 1;
+                }
+            }
+        }
+
+        rv = PL_Base64Decode(buffer, 0, (char *)0);
+
+        if( (char *)0 == rv )
+        {
+            printf("FAIL\n\t(%d): no return value\n", i);
+            return PR_FALSE;
+        }
+
+        if( 0 != PL_strcmp(rv, array[i].plaintext) )
+        {
+            printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", 
+                   i, array[i].cyphertext, array[i].plaintext, rv);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+int
+main
+(
+    int     argc,
+    char   *argv[]
+)
+{
+    printf("Testing the Portable Library base64 functions:\n");
+    printf("(warning: the \"triple characters\" tests are slow)\n");
+
+    if( 1
+        && test_001()
+        && test_002()
+        && test_003()
+        && test_004()
+        && test_005()
+        && test_006()
+        && test_007()
+        && test_008()
+        && test_009()
+        && test_010()
+        && test_011()
+        && test_012()
+        && test_013()
+        && test_014()
+        && test_015()
+        && test_016()
+        && test_017()
+        && test_018()
+        && test_019()
+        && test_020()
+        && test_021()
+        && test_022()
+        && test_023()
+        && test_024()
+        && test_025()
+        && test_026()
+        && test_027()
+        && test_028()
+      )
+    {
+        printf("Suite passed.\n");
+        return 0;
+    }
+    else
+    {
+        printf("Suite failed.\n");
+        return 1;
+    }
+
+    /*NOTREACHED*/
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/tests/getopt.c b/nspr-4.8.6/mozilla/nsprpub/lib/tests/getopt.c
new file mode 100644
index 0000000..52b9719
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/tests/getopt.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+
+
+static const PLLongOpt optArray[] = {
+    { "longa", 'a'        , PR_TRUE  },
+    { "longb", 'b'        , PR_TRUE  },
+    { "longc", 'c'        , PR_FALSE },
+    { "longd", 'd' | 0x100, PR_TRUE  },
+    { "longe", 'e' | 0x100, PR_FALSE },
+    {    NULL,                       }
+};
+
+int
+main(int argc, char **argv) 
+{
+    PLOptState *opt;
+    PLOptStatus ostat;
+
+    opt = PL_CreateLongOptState(argc, argv, "a:b:c", optArray);
+
+    while (PL_OPT_OK == (ostat = PL_GetNextOpt(opt))) {
+	if (opt->option == 0 && opt->longOptIndex < 0) 
+	    printf("Positional parameter: \"%s\"\n", opt->value);
+	else
+	    printf("%s option: %x (\'%c\', index %d), argument: \"%s\"\n",
+		   (ostat == PL_OPT_BAD) ? "BAD" : "GOOD",
+		   opt->longOption, opt->option ? opt->option : ' ',
+		   opt->longOptIndex, opt->value);
+
+    }
+    printf("last result was %s\n", (ostat == PL_OPT_BAD) ? "BAD" : "EOL");
+    PL_DestroyOptState(opt);
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/lib/tests/string.c b/nspr-4.8.6/mozilla/nsprpub/lib/tests/string.c
new file mode 100644
index 0000000..482e17b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/lib/tests/string.c
@@ -0,0 +1,3116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include "nspr.h"
+
+#include <stdio.h>
+
+/* PL_strlen */
+PRBool test_001(void)
+{
+    static struct
+    {
+        const char *str;
+        PRUint32    len;
+    } array[] =
+      {
+          { (const char *)0, 0 },
+          { "", 0 },
+          { "a", 1 },
+          { "abcdefg", 7 },
+          { "abcdefg\0hijk", 7 }
+      };
+
+    int i;
+
+    printf("Test 001 (PL_strlen)      ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        if( PL_strlen(array[i].str) != array[i].len )
+        {
+            printf("FAIL (%d: %s->%d, %d)\n", i, 
+                   array[i].str ? array[i].str : "(null)",
+                   PL_strlen(array[i].str), array[i].len);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strnlen */
+PRBool test_002(void)
+{
+    static struct
+    {
+        const char *str;
+        PRUint32    max;
+        PRUint32    len;
+    } array[] =
+      {
+          { (const char *)0, 0, 0 },
+          { (const char *)0, 12, 0 },
+          { "", 0, 0 },
+          { "", 12, 0 },
+          { "a", 0, 0 },
+          { "a", 1, 1 },
+          { "a", 12, 1 },
+          { "abcdefg", 0, 0 },
+          { "abcdefg", 1, 1 },
+          { "abcdefg", 7, 7 },
+          { "abcdefg", 12, 7 },
+          { "abcdefg\0hijk", 0, 0 },
+          { "abcdefg\0hijk", 1, 1 },
+          { "abcdefg\0hijk", 7, 7 },
+          { "abcdefg\0hijk", 12, 7 },
+      };
+
+    int i;
+
+    printf("Test 002 (PL_strnlen)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        if( PL_strnlen(array[i].str, array[i].max) != array[i].len )
+        {
+            printf("FAIL (%d: %s,%d->%d, %d)\n", i,
+                   array[i].str ? array[i].str : "(null)", array[i].max,
+                   PL_strnlen(array[i].str, array[i].max), array[i].len);
+            return PR_FALSE;
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strcpy */
+PRBool test_003(void)
+{
+    static char buffer[ 1024 ];
+
+    static struct
+    {
+        const char *str;
+        char       *dest;
+        char       *rv;
+        PRBool      comp;
+    } array[] =
+      {
+          { (const char *)0, (char *)0, (char *)0, PR_FALSE },
+          { (const char *)0, buffer, (char *)0, PR_FALSE },
+          { "", (char *)0, (char *)0, PR_FALSE },
+          { "", buffer, buffer, PR_TRUE },
+          { "a", (char *)0, (char *)0, PR_FALSE },
+          { "a", buffer, buffer, PR_TRUE },
+          { "abcdefg", (char *)0, (char *)0, PR_FALSE },
+          { "abcdefg", buffer, buffer, PR_TRUE },
+          { "wxyz\0abcdefg", (char *)0, (char *)0, PR_FALSE },
+          { "wxyz\0abcdefg", buffer, buffer, PR_TRUE }
+      };
+
+    int i;
+
+    printf("Test 003 (PL_strcpy)      ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv;
+        const char *a = array[i].str;
+        const char *b = (const char *)array[i].dest;
+
+        rv = PL_strcpy(array[i].dest, array[i].str);
+        if( array[i].rv != rv )
+        {
+            printf("FAIL %d: (0x%x, %s)->0x%x\n", i, array[i].dest,
+                   array[i].str ? array[i].str : "(null)", rv);
+            return PR_FALSE;
+        }
+
+        if( array[i].comp )
+        {
+            while( 1 )
+            {
+                if( *a != *b )
+                {
+                    printf("FAIL %d: %s->%.32s\n", i, 
+                           array[i].str ? array[i].str : "(null)", 
+                           array[i].dest ? array[i].dest : "(null)");
+                    return PR_FALSE;
+                }
+
+                if( (char)0 == *a ) break;
+
+                a++;
+                b++;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strncpy */
+PRBool test_004(void)
+{
+    static char buffer[ 1024 ];
+
+    static struct
+    {
+        const char *str;
+        PRUint32    len;
+        char       *dest;
+        char       *rv;
+        PRBool      comp;
+        const char *result;
+        PRBool      nulled;
+    } array[] =
+      {
+          { (const char *)0, 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { (const char *)0, 0, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { (const char *)0, 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { (const char *)0, 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { (const char *)0, 1, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { (const char *)0, 7, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+          { "", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "", 1, buffer, buffer, PR_TRUE, "", PR_TRUE },
+          { "", 7, buffer, buffer, PR_TRUE, "", PR_TRUE },
+          { "a", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "a", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+          { "a", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "a", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "b", 1, buffer, buffer, PR_TRUE, "b", PR_FALSE },
+          { "c", 7, buffer, buffer, PR_TRUE, "c", PR_TRUE },
+          { "de", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "de", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+          { "de", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "de", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "fg", 1, buffer, buffer, PR_TRUE, "f", PR_FALSE },
+          { "hi", 7, buffer, buffer, PR_TRUE, "hi", PR_TRUE },
+          { "jklmnopq", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "jklmnopq", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+          { "jklmnopq", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "jklmnopq", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "rstuvwxy", 1, buffer, buffer, PR_TRUE, "r", PR_FALSE },
+          { "zABCDEFG", 7, buffer, buffer, PR_TRUE, "zABCDEF", PR_FALSE },
+          { "a\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "a\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+          { "a\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "a\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "b\0XXX", 1, buffer, buffer, PR_TRUE, "b", PR_FALSE },
+          { "c\0XXX", 7, buffer, buffer, PR_TRUE, "c", PR_TRUE },
+          { "de\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "de\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+          { "de\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "de\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "fg\0XXX", 1, buffer, buffer, PR_TRUE, "f", PR_FALSE },
+          { "hi\0XXX", 7, buffer, buffer, PR_TRUE, "hi", PR_TRUE },
+          { "jklmnopq\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "jklmnopq\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+          { "jklmnopq\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "jklmnopq\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+          { "rstuvwxy\0XXX", 1, buffer, buffer, PR_TRUE, "r", PR_FALSE },
+          { "zABCDEFG\0XXX", 7, buffer, buffer, PR_TRUE, "zABCDEF", PR_FALSE },
+      };
+
+    int i;
+
+    printf("Test 004 (PL_strncpy)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv;
+        int j;
+
+        for( j = 0; j < sizeof(buffer); j++ )
+            buffer[j] = '-';
+
+        rv = PL_strncpy(array[i].dest, array[i].str, array[i].len);
+        if( array[i].rv != rv )
+        {
+            printf("FAIL %d: (0x%x, %s, %lu)->0x%x\n", i, array[i].dest,
+                   array[i].str ? array[i].str : "(null)", array[i].len, rv);
+            return PR_FALSE;
+        }
+
+        if( array[i].comp )
+        {
+            const char *a = array[i].result;
+            const char *b = array[i].dest;
+
+            while( *a )
+            {
+                if( *a != *b )
+                {
+                    printf("FAIL %d: %s != %.32s\n", i, 
+                           array[i].result, array[i].dest);
+                    return PR_FALSE;
+                }
+
+                a++;
+                b++;
+            }
+
+            if( array[i].nulled )
+            {
+                if( *b != '\0' )
+                {
+                    printf("FAIL %d: not terminated\n", i);
+                    return PR_FALSE;
+                }
+            }
+            else
+            {
+                if( *b != '-' )
+                {
+                    printf("FAIL %d: overstepped\n", i);
+                    return PR_FALSE;
+                }
+            }
+        }
+    }
+                
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strncpyz */
+PRBool test_005(void)
+{
+    static char buffer[ 1024 ];
+
+    static struct
+    {
+        const char *str;
+        PRUint32    len;
+        char       *dest;
+        char       *rv;
+        PRBool      comp;
+        const char *result;
+    } array[] =
+      {
+          { (const char *)0, 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { (const char *)0, 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { (const char *)0, 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { (const char *)0, 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { (const char *)0, 1, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { (const char *)0, 7, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { "", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { "", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "", 1, buffer, buffer, PR_TRUE, "" },
+          { "", 7, buffer, buffer, PR_TRUE, "" },
+          { "a", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "a", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { "a", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "a", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "b", 1, buffer, buffer, PR_TRUE, "" },
+          { "c", 7, buffer, buffer, PR_TRUE, "c" },
+          { "de", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "de", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { "de", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "de", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "fg", 1, buffer, buffer, PR_TRUE, "" },
+          { "hi", 7, buffer, buffer, PR_TRUE, "hi" },
+          { "jklmnopq", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "jklmnopq", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { "jklmnopq", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "jklmnopq", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "rstuvwxy", 1, buffer, buffer, PR_TRUE, "" },
+          { "zABCDEFG", 7, buffer, buffer, PR_TRUE, "zABCDE" },
+          { "a\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "a\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { "a\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "a\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "b\0XXX", 1, buffer, buffer, PR_TRUE, "" },
+          { "c\0XXX", 7, buffer, buffer, PR_TRUE, "c" },
+          { "de\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "de\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { "de\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "de\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "fg\0XXX", 1, buffer, buffer, PR_TRUE, "" },
+          { "hi\0XXX", 7, buffer, buffer, PR_TRUE, "hi" },
+          { "jklmnopq\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "jklmnopq\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+          { "jklmnopq\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "jklmnopq\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+          { "rstuvwxy\0XXX", 1, buffer, buffer, PR_TRUE, "" },
+          { "zABCDEFG\0XXX", 7, buffer, buffer, PR_TRUE, "zABCDE" },
+      };
+
+    int i;
+
+    printf("Test 005 (PL_strncpyz)    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv;
+        int j;
+
+        for( j = 0; j < sizeof(buffer); j++ )
+            buffer[j] = '-';
+
+        rv = PL_strncpyz(array[i].dest, array[i].str, array[i].len);
+        if( array[i].rv != rv )
+        {
+            printf("FAIL %d: (0x%x, %s, %lu)->0x%x\n", i, array[i].dest,
+                   array[i].str ? array[i].str : "(null)", array[i].len, rv);
+            return PR_FALSE;
+        }
+
+        if( array[i].comp )
+        {
+            const char *a = array[i].result;
+            const char *b = array[i].dest;
+
+            while( 1 )
+            {
+                if( *a != *b )
+                {
+                    printf("FAIL %d: %s != %.32s\n", i, 
+                           array[i].result, array[i].dest);
+                    return PR_FALSE;
+                }
+
+                if( (char)0 == *a ) break;
+
+                a++;
+                b++;
+            }
+        }
+    }
+                
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strdup */
+PRBool test_006(void)
+{
+    static const char *array[] =
+    {
+        (const char *)0,
+        "",
+        "a",
+        "abcdefg"
+    };
+
+    int i;
+
+    printf("Test 006 (PL_strdup)      ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strdup(array[i]);
+
+        if( (char *)0 == rv )
+        {
+            printf("FAIL %d: 0x%x -> 0\n", i, array[i]);
+            return PR_FALSE;
+        }
+
+        if( (const char *)0 == array[i] )
+        {
+            if( (char)0 != *rv )
+            {
+                printf("FAIL %d: (const char *)0 -> %.32s\n", i, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            const char *a = array[i];
+            const char *b = (const char *)rv;
+
+            while( 1 )
+            {
+                if( *a != *b )
+                {
+                    printf("FAIL %d: %s != %.32s\n", i, array[i], rv);
+                    return PR_FALSE;
+                }
+
+                if( (char)0 == *a ) break;
+
+                a++;
+                b++;
+            }
+
+        }
+        PL_strfree(rv);
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strndup */
+PRBool test_007(void)
+{
+    static struct
+    {
+        const char *str;
+        PRUint32    len;
+        const char *result;
+    } array[] =
+      {
+          { (const char *)0, 0, "" },
+          { (const char *)0, 1, "" },
+          { (const char *)0, 7, "" },
+          { "", 0, "" },
+          { "", 1, "" },
+          { "", 7, "" },
+          { "a", 0, "" },
+          { "a", 1, "a" },
+          { "a", 7, "a" },
+          { "ab", 0, "" },
+          { "ab", 1, "a" },
+          { "ab", 7, "ab" },
+          { "abcdefg", 0, "" },
+          { "abcdefg", 1, "a" },
+          { "abcdefg", 7, "abcdefg" },
+          { "abcdefghijk", 0, "" },
+          { "abcdefghijk", 1, "a" },
+          { "abcdefghijk", 7, "abcdefg" },
+          { "abcdef\0ghijk", 0, "" },
+          { "abcdef\0ghijk", 1, "a" },
+          { "abcdef\0ghijk", 7, "abcdef" }
+      };
+
+    int i;
+
+    printf("Test 007 (PL_strndup)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strndup(array[i].str, array[i].len);
+        const char *a;
+        const char *b;
+
+        if( (char *)0 == rv )
+        {
+            printf("FAIL %d: %s,%lu -> 0\n", i, 
+                   array[i].str ? array[i].str : "(null)", array[i].len);
+            return PR_FALSE;
+        }
+
+        a = array[i].result;
+        b = (const char *)rv;
+
+        while( 1 )
+        {
+            if( *a != *b )
+            {
+                printf("FAIL %d: %s != %.32s\n", i, array[i].result, rv);
+                return PR_FALSE;
+            }
+
+            if( (char)0 == *a ) break;
+
+            a++;
+            b++;
+        }
+
+        free(rv);
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strcat */
+PRBool test_008(void)
+{
+    static struct
+    {
+        const char *first;
+        const char *second;
+        const char *result;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, (const char *)0 },
+          { (const char *)0, "xyz", (const char *)0 },
+          { "", (const char *)0, "" },
+          { "", "", "" },
+          { "ab", "", "ab" },
+          { "cd", "ef", "cdef" },
+          { "gh\0X", "", "gh" },
+          { "ij\0X", "kl", "ijkl" },
+          { "mn\0X", "op\0X", "mnop" },
+          { "qr", "st\0X", "qrst" },
+          { "uv\0X", "wx\0X", "uvwx" }
+      };
+
+    int i;
+
+    printf("Test 008 (PL_strcat)      ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char buffer[ 1024 ];
+        int j;
+        char *rv;
+
+        for( j = 0; j < sizeof(buffer); j++ )
+            buffer[j] = '-';
+
+        if( (const char *)0 != array[i].first )
+            (void)PL_strcpy(buffer, array[i].first);
+
+        rv = PL_strcat(((const char *)0 == array[i].first) ? (char *)0 : buffer,
+                       array[i].second);
+
+        if( (const char *)0 == array[i].result )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s+%s -> %.32s, not zero\n", i,
+                       array[i].first ? array[i].first : "(null)",
+                       array[i].second ? array[i].second : "(null)",
+                       rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s+%s -> null, not %s\n", i,
+                       array[i].first ? array[i].first : "(null)",
+                       array[i].second ? array[i].second : "(null)",
+                       array[i].result);
+                return PR_FALSE;
+            }
+            else
+            {
+                const char *a = array[i].result;
+                const char *b = (const char *)rv;
+
+                while( 1 )
+                {
+                    if( *a != *b )
+                    {
+                        printf("FAIL %d: %s+%s -> %.32s, not %s\n", i,
+                               array[i].first ? array[i].first : "(null)",
+                               array[i].second ? array[i].second : "(null)",
+                               rv, array[i].result);
+                        return PR_FALSE;
+                    }
+
+                    if( (char)0 == *a ) break;
+
+                    a++;
+                    b++;
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strncat */
+PRBool test_009(void)
+{
+    static struct
+    {
+        const char *first;
+        const char *second;
+        PRUint32    length;
+        PRBool      nulled;
+        const char *result;
+    } array[] = 
+      {
+          { (const char *)0, (const char *)0, 0, PR_FALSE, (const char *)0 },
+          { (const char *)0, (const char *)0, 1, PR_FALSE, (const char *)0 },
+          { (const char *)0, (const char *)0, 7, PR_FALSE, (const char *)0 },
+          { (const char *)0, "", 0, PR_FALSE, (const char *)0 },
+          { (const char *)0, "", 1, PR_FALSE, (const char *)0 },
+          { (const char *)0, "", 7, PR_FALSE, (const char *)0 },
+          { (const char *)0, "stuff", 0, PR_FALSE, (const char *)0 },
+          { (const char *)0, "stuff", 1, PR_FALSE, (const char *)0 },
+          { (const char *)0, "stuff", 7, PR_FALSE, (const char *)0 },
+          { "", (const char *)0, 0, PR_TRUE, "" },
+          { "", (const char *)0, 1, PR_TRUE, "" },
+          { "", (const char *)0, 7, PR_TRUE, "" },
+          { "", "", 0, PR_TRUE, "" },
+          { "", "", 1, PR_TRUE, "" },
+          { "", "", 7, PR_TRUE, "" },
+          { "", "abcdefgh", 0, PR_TRUE, "" },
+          { "", "abcdefgh", 1, PR_FALSE, "a" },
+          { "", "abcdefgh", 7, PR_FALSE, "abcdefg" },
+          { "xyz", (const char *)0, 0, PR_TRUE, "xyz" },
+          { "xyz", (const char *)0, 1, PR_TRUE, "xyz" },
+          { "xyz", (const char *)0, 7, PR_TRUE, "xyz" },
+          { "xyz", "", 0, PR_TRUE, "xyz" },
+          { "xyz", "", 1, PR_TRUE, "xyz" },
+          { "xyz", "", 7, PR_TRUE, "xyz" },
+          { "xyz", "abcdefgh", 0, PR_TRUE, "xyz" },
+          { "xyz", "abcdefgh", 1, PR_FALSE, "xyza" },
+          { "xyz", "abcdefgh", 7, PR_FALSE, "xyzabcdefg" }
+      };
+
+    int i;
+
+    printf("Test 009 (PL_strncat)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char buffer[ 1024 ];
+        int j;
+        char *rv;
+
+        for( j = 0; j < sizeof(buffer); j++ )
+            buffer[j] = '-';
+
+        if( (const char *)0 != array[i].first )
+            (void)PL_strcpy(buffer, array[i].first);
+
+        rv = PL_strncat(((const char *)0 == array[i].first) ? (char *)0 : buffer,
+                         array[i].second, array[i].length);
+
+        if( (const char *)0 == array[i].result )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s+%s/%lu -> %.32s, not zero\n", i,
+                       array[i].first ? array[i].first : "(null)",
+                       array[i].second ? array[i].second : "(null)",
+                       array[i].length, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s+%s/%lu -> null, not %s\n", i,
+                       array[i].first ? array[i].first : "(null)",
+                       array[i].second ? array[i].second : "(null)",
+                       array[i].length, array[i].result);
+                return PR_FALSE;
+            }
+            else
+            {
+                const char *a = array[i].result;
+                const char *b = (const char *)rv;
+
+                while( *a )
+                {
+                    if( *a != *b )
+                    {
+                        printf("FAIL %d: %s+%s/%lu -> %.32s, not %s\n", i,
+                               array[i].first ? array[i].first : "(null)",
+                               array[i].second ? array[i].second : "(null)",
+                               array[i].length, rv, array[i].result);
+                        return PR_FALSE;
+                    }
+
+                    a++;
+                    b++;
+                }
+
+                if( array[i].nulled )
+                {
+                    if( (char)0 != *b )
+                    {
+                        printf("FAIL %d: %s+%s/%lu -> not nulled\n", i,
+                               array[i].first ? array[i].first : "(null)",
+                               array[i].second ? array[i].second : "(null)",
+                               array[i].length);
+                        return PR_FALSE;
+                    }
+                }
+                else
+                {
+                    if( (char)0 == *b )
+                    {
+                        printf("FAIL %d: %s+%s/%lu -> overrun\n", i,
+                               array[i].first ? array[i].first : "(null)",
+                               array[i].second ? array[i].second : "(null)",
+                               array[i].length);
+                        return PR_FALSE;
+                    }
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strcatn */
+PRBool test_010(void)
+{
+    static struct
+    {
+        const char *first;
+        const char *second;
+        PRUint32    length;
+        const char *result;
+    } array[] = 
+      {
+          { (const char *)0, (const char *)0, 0, (const char *)0 },
+          { (const char *)0, (const char *)0, 1, (const char *)0 },
+          { (const char *)0, (const char *)0, 7, (const char *)0 },
+          { (const char *)0, "", 0, (const char *)0 },
+          { (const char *)0, "", 1, (const char *)0 },
+          { (const char *)0, "", 7, (const char *)0 },
+          { (const char *)0, "stuff", 0, (const char *)0 },
+          { (const char *)0, "stuff", 1, (const char *)0 },
+          { (const char *)0, "stuff", 7, (const char *)0 },
+          { "", (const char *)0, 0, "" },
+          { "", (const char *)0, 1, "" },
+          { "", (const char *)0, 7, "" },
+          { "", "", 0, "" },
+          { "", "", 1, "" },
+          { "", "", 7, "" },
+          { "", "abcdefgh", 0, "" },
+          { "", "abcdefgh", 1, "" },
+          { "", "abcdefgh", 7, "abcdef" },
+          { "xyz", (const char *)0, 0, "xyz" },
+          { "xyz", (const char *)0, 1, "xyz" },
+          { "xyz", (const char *)0, 7, "xyz" },
+          { "xyz", "", 0, "xyz" },
+          { "xyz", "", 1, "xyz" },
+          { "xyz", "", 7, "xyz" },
+          { "xyz", "abcdefgh", 0, "xyz" },
+          { "xyz", "abcdefgh", 1, "xyz" },
+          { "xyz", "abcdefgh", 7, "xyzabc" }
+      };
+
+    int i;
+
+    printf("Test 010 (PL_strcatn)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char buffer[ 1024 ];
+        int j;
+        char *rv;
+
+        for( j = 0; j < sizeof(buffer); j++ )
+            buffer[j] = '-';
+
+        if( (const char *)0 != array[i].first )
+            (void)PL_strcpy(buffer, array[i].first);
+
+        rv = PL_strcatn(((const char *)0 == array[i].first) ? (char *)0 : buffer,
+                        array[i].length, array[i].second);
+
+        if( (const char *)0 == array[i].result )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s+%s/%lu -> %.32s, not zero\n", i,
+                       array[i].first ? array[i].first : "(null)",
+                       array[i].second ? array[i].second : "(null)",
+                       array[i].length, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s+%s/%lu -> null, not %s\n", i,
+                       array[i].first ? array[i].first : "(null)",
+                       array[i].second ? array[i].second : "(null)",
+                       array[i].length, array[i].result);
+                return PR_FALSE;
+            }
+            else
+            {
+                const char *a = array[i].result;
+                const char *b = (const char *)rv;
+
+                while( 1 )
+                {
+                    if( *a != *b )
+                    {
+                        printf("FAIL %d: %s+%s/%lu -> %.32s, not %s\n", i,
+                               array[i].first ? array[i].first : "(null)",
+                               array[i].second ? array[i].second : "(null)",
+                               array[i].length, rv, array[i].result);
+                        return PR_FALSE;
+                    }
+
+                    if( (char)0 == *a ) break;
+
+                    a++;
+                    b++;
+                }
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strcmp */
+PRBool test_011(void)
+{
+    static struct
+    {
+        const char *one;
+        const char *two;
+        PRIntn      sign;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 0 },
+          { (const char *)0, "word", -1 },
+          { "word", (const char *)0, 1 },
+          { "word", "word", 0 },
+          { "aZYXVUT", "bZYXVUT", -1 },
+          { "aZYXVUT", "bAAAAAA", -1 },
+          { "a", "aa", -1 },
+          { "a", "a", 0 },
+          { "a", "A", 1 },
+          { "aaaaa", "baaaa", -1 },
+          { "aaaaa", "abaaa", -1 },
+          { "aaaaa", "aabaa", -1 },
+          { "aaaaa", "aaaba", -1 },
+          { "aaaaa", "aaaab", -1 },
+          { "bZYXVUT", "aZYXVUT", 1 },
+          { "bAAAAAA", "aZYXVUT", 1 },
+          { "aa", "a", 1 },
+          { "A", "a", -1 },
+          { "baaaa", "aaaaa", 1 },
+          { "abaaa", "aaaaa", 1 },
+          { "aabaa", "aaaaa", 1 },
+          { "aaaba", "aaaaa", 1 },
+          { "aaaab", "aaaaa", 1 },
+          { "word", "Word", 1 },
+          { "word", "wOrd", 1 },
+          { "word", "woRd", 1 },
+          { "word", "worD", 1 },
+          { "WORD", "wORD", -1 },
+          { "WORD", "WoRD", -1 },
+          { "WORD", "WOrD", -1 },
+          { "WORD", "WORd", -1 }
+      };
+
+    int i;
+
+    printf("Test 011 (PL_strcmp)      ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRIntn rv = PL_strcmp(array[i].one, array[i].two);
+
+        switch( array[i].sign )
+        {
+            case -1:
+                if( rv < 0 ) continue;
+                break;
+            case 1:
+                if( rv > 0 ) continue;
+                break;
+            case 0:
+                if( 0 == rv ) continue;
+                break;
+            default:
+                PR_NOT_REACHED("static data inconsistancy");
+                break;
+        }
+
+        printf("FAIL %d: %s-%s -> %d, not %d\n", i,
+               array[i].one ? array[i].one : "(null)",
+               array[i].two ? array[i].two : "(null)",
+               rv, array[i].sign);
+        return PR_FALSE;
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strncmp */
+PRBool test_012(void)
+{
+    static struct
+    {
+        const char *one;
+        const char *two;
+        PRUint32    max;
+        PRIntn      sign;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 0, 0 },
+          { (const char *)0, (const char *)0, 1, 0 },
+          { (const char *)0, (const char *)0, 4, 0 },
+          { (const char *)0, "word", 0, -1 },
+          { (const char *)0, "word", 1, -1 },
+          { (const char *)0, "word", 4, -1 },
+          { "word", (const char *)0, 0, 1 },
+          { "word", (const char *)0, 1, 1 },
+          { "word", (const char *)0, 4, 1 },
+          { "word", "word", 0, 0 },
+          { "word", "word", 1, 0 },
+          { "word", "word", 3, 0 },
+          { "word", "word", 5, 0 },
+          { "aZYXVUT", "bZYXVUT", 0, 0 },
+          { "aZYXVUT", "bZYXVUT", 1, -1 },
+          { "aZYXVUT", "bZYXVUT", 4, -1 },
+          { "aZYXVUT", "bZYXVUT", 9, -1 },
+          { "aZYXVUT", "bAAAAAA", 0, 0 },
+          { "aZYXVUT", "bAAAAAA", 1, -1 },
+          { "aZYXVUT", "bAAAAAA", 4, -1 },
+          { "aZYXVUT", "bAAAAAA", 5, -1 },
+          { "a", "aa", 0, 0 },
+          { "a", "aa", 1, 0 },
+          { "a", "aa", 4, -1 },
+          { "a", "a", 0, 0 },
+          { "a", "a", 1, 0 },
+          { "a", "a", 4, 0 },
+          { "a", "A", 0, 0 },
+          { "a", "A", 1, 1 },
+          { "a", "A", 4, 1 },
+          { "aaaaa", "baaaa", 0, 0 },
+          { "aaaaa", "baaaa", 1, -1 },
+          { "aaaaa", "baaaa", 4, -1 },
+          { "aaaaa", "abaaa", 0, 0 },
+          { "aaaaa", "abaaa", 1, 0 },
+          { "aaaaa", "abaaa", 4, -1 },
+          { "aaaaa", "aabaa", 0, 0 },
+          { "aaaaa", "aabaa", 1, 0 },
+          { "aaaaa", "aabaa", 4, -1 },
+          { "aaaaa", "aaaba", 0, 0 },
+          { "aaaaa", "aaaba", 1, 0 },
+          { "aaaaa", "aaaba", 4, -1 },
+          { "aaaaa", "aaaab", 0, 0 },
+          { "aaaaa", "aaaab", 1, 0 },
+          { "aaaaa", "aaaab", 4, 0 },
+          { "bZYXVUT", "aZYXVUT", 0, 0 },
+          { "bZYXVUT", "aZYXVUT", 1, 1 },
+          { "bZYXVUT", "aZYXVUT", 4, 1 },
+          { "bAAAAAA", "aZYXVUT", 0, 0 },
+          { "bAAAAAA", "aZYXVUT", 1, 1 },
+          { "bAAAAAA", "aZYXVUT", 4, 1 },
+          { "aa", "a", 0, 0 },
+          { "aa", "a", 1, 0 },
+          { "aa", "a", 4, 1 },
+          { "A", "a", 0, 0 },
+          { "A", "a", 1, -1 },
+          { "A", "a", 4, -1 },
+          { "baaaa", "aaaaa", 0, 0 },
+          { "baaaa", "aaaaa", 1, 1 },
+          { "baaaa", "aaaaa", 4, 1 },
+          { "abaaa", "aaaaa", 0, 0 },
+          { "abaaa", "aaaaa", 1, 0 },
+          { "abaaa", "aaaaa", 4, 1 },
+          { "aabaa", "aaaaa", 0, 0 },
+          { "aabaa", "aaaaa", 1, 0 },
+          { "aabaa", "aaaaa", 4, 1 },
+          { "aaaba", "aaaaa", 0, 0 },
+          { "aaaba", "aaaaa", 1, 0 },
+          { "aaaba", "aaaaa", 4, 1 },
+          { "aaaab", "aaaaa", 0, 0 },
+          { "aaaab", "aaaaa", 1, 0 },
+          { "aaaab", "aaaaa", 4, 0 },
+          { "word", "Word", 0, 0 },
+          { "word", "Word", 1, 1 },
+          { "word", "Word", 3, 1 },
+          { "word", "wOrd", 0, 0 },
+          { "word", "wOrd", 1, 0 },
+          { "word", "wOrd", 3, 1 },
+          { "word", "woRd", 0, 0 },
+          { "word", "woRd", 1, 0 },
+          { "word", "woRd", 3, 1 },
+          { "word", "worD", 0, 0 },
+          { "word", "worD", 1, 0 },
+          { "word", "worD", 3, 0 },
+          { "WORD", "wORD", 0, 0 },
+          { "WORD", "wORD", 1, -1 },
+          { "WORD", "wORD", 3, -1 },
+          { "WORD", "WoRD", 0, 0 },
+          { "WORD", "WoRD", 1, 0 },
+          { "WORD", "WoRD", 3, -1 },
+          { "WORD", "WOrD", 0, 0 },
+          { "WORD", "WOrD", 1, 0 },
+          { "WORD", "WOrD", 3, -1 },
+          { "WORD", "WORd", 0, 0 },
+          { "WORD", "WORd", 1, 0 },
+          { "WORD", "WORd", 3, 0 }
+
+      };
+
+    int i;
+
+    printf("Test 012 (PL_strncmp)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRIntn rv = PL_strncmp(array[i].one, array[i].two, array[i].max);
+
+        switch( array[i].sign )
+        {
+            case -1:
+                if( rv < 0 ) continue;
+                break;
+            case 1:
+                if( rv > 0 ) continue;
+                break;
+            case 0:
+                if( 0 == rv ) continue;
+                break;
+            default:
+                PR_NOT_REACHED("static data inconsistancy");
+                break;
+        }
+
+        printf("FAIL %d: %s-%s/%ld -> %d, not %d\n", i,
+               array[i].one ? array[i].one : "(null)",
+               array[i].two ? array[i].two : "(null)",
+               array[i].max, rv, array[i].sign);
+        return PR_FALSE;
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strcasecmp */
+PRBool test_013(void)
+{
+    static struct
+    {
+        const char *one;
+        const char *two;
+        PRIntn      sign;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 0 },
+          { (const char *)0, "word", -1 },
+          { "word", (const char *)0, 1 },
+          { "word", "word", 0 },
+          { "aZYXVUT", "bZYXVUT", -1 },
+          { "aZYXVUT", "bAAAAAA", -1 },
+          { "a", "aa", -1 },
+          { "a", "a", 0 },
+          { "a", "A", 0 },
+          { "aaaaa", "baaaa", -1 },
+          { "aaaaa", "abaaa", -1 },
+          { "aaaaa", "aabaa", -1 },
+          { "aaaaa", "aaaba", -1 },
+          { "aaaaa", "aaaab", -1 },
+          { "bZYXVUT", "aZYXVUT", 1 },
+          { "bAAAAAA", "aZYXVUT", 1 },
+          { "aa", "a", 1 },
+          { "A", "a", 0 },
+          { "baaaa", "aaaaa", 1 },
+          { "abaaa", "aaaaa", 1 },
+          { "aabaa", "aaaaa", 1 },
+          { "aaaba", "aaaaa", 1 },
+          { "aaaab", "aaaaa", 1 },
+          { "word", "Word", 0 },
+          { "word", "wOrd", 0 },
+          { "word", "woRd", 0 },
+          { "word", "worD", 0 },
+          { "WORD", "wORD", 0 },
+          { "WORD", "WoRD", 0 },
+          { "WORD", "WOrD", 0 },
+          { "WORD", "WORd", 0 }
+      };
+
+    int i;
+
+    printf("Test 013 (PL_strcasecmp)  ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRIntn rv = PL_strcasecmp(array[i].one, array[i].two);
+
+        switch( array[i].sign )
+        {
+            case -1:
+                if( rv < 0 ) continue;
+                break;
+            case 1:
+                if( rv > 0 ) continue;
+                break;
+            case 0:
+                if( 0 == rv ) continue;
+                break;
+            default:
+                PR_NOT_REACHED("static data inconsistancy");
+                break;
+        }
+
+        printf("FAIL %d: %s-%s -> %d, not %d\n", i,
+               array[i].one ? array[i].one : "(null)",
+               array[i].two ? array[i].two : "(null)",
+               rv, array[i].sign);
+        return PR_FALSE;
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strncasecmp */
+PRBool test_014(void)
+{
+    static struct
+    {
+        const char *one;
+        const char *two;
+        PRUint32    max;
+        PRIntn      sign;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 0, 0 },
+          { (const char *)0, (const char *)0, 1, 0 },
+          { (const char *)0, (const char *)0, 4, 0 },
+          { (const char *)0, "word", 0, -1 },
+          { (const char *)0, "word", 1, -1 },
+          { (const char *)0, "word", 4, -1 },
+          { "word", (const char *)0, 0, 1 },
+          { "word", (const char *)0, 1, 1 },
+          { "word", (const char *)0, 4, 1 },
+          { "word", "word", 0, 0 },
+          { "word", "word", 1, 0 },
+          { "word", "word", 3, 0 },
+          { "word", "word", 5, 0 },
+          { "aZYXVUT", "bZYXVUT", 0, 0 },
+          { "aZYXVUT", "bZYXVUT", 1, -1 },
+          { "aZYXVUT", "bZYXVUT", 4, -1 },
+          { "aZYXVUT", "bZYXVUT", 9, -1 },
+          { "aZYXVUT", "bAAAAAA", 0, 0 },
+          { "aZYXVUT", "bAAAAAA", 1, -1 },
+          { "aZYXVUT", "bAAAAAA", 4, -1 },
+          { "aZYXVUT", "bAAAAAA", 5, -1 },
+          { "a", "aa", 0, 0 },
+          { "a", "aa", 1, 0 },
+          { "a", "aa", 4, -1 },
+          { "a", "a", 0, 0 },
+          { "a", "a", 1, 0 },
+          { "a", "a", 4, 0 },
+          { "a", "A", 0, 0 },
+          { "a", "A", 1, 0 },
+          { "a", "A", 4, 0 },
+          { "aaaaa", "baaaa", 0, 0 },
+          { "aaaaa", "baaaa", 1, -1 },
+          { "aaaaa", "baaaa", 4, -1 },
+          { "aaaaa", "abaaa", 0, 0 },
+          { "aaaaa", "abaaa", 1, 0 },
+          { "aaaaa", "abaaa", 4, -1 },
+          { "aaaaa", "aabaa", 0, 0 },
+          { "aaaaa", "aabaa", 1, 0 },
+          { "aaaaa", "aabaa", 4, -1 },
+          { "aaaaa", "aaaba", 0, 0 },
+          { "aaaaa", "aaaba", 1, 0 },
+          { "aaaaa", "aaaba", 4, -1 },
+          { "aaaaa", "aaaab", 0, 0 },
+          { "aaaaa", "aaaab", 1, 0 },
+          { "aaaaa", "aaaab", 4, 0 },
+          { "bZYXVUT", "aZYXVUT", 0, 0 },
+          { "bZYXVUT", "aZYXVUT", 1, 1 },
+          { "bZYXVUT", "aZYXVUT", 4, 1 },
+          { "bAAAAAA", "aZYXVUT", 0, 0 },
+          { "bAAAAAA", "aZYXVUT", 1, 1 },
+          { "bAAAAAA", "aZYXVUT", 4, 1 },
+          { "aa", "a", 0, 0 },
+          { "aa", "a", 1, 0 },
+          { "aa", "a", 4, 1 },
+          { "A", "a", 0, 0 },
+          { "A", "a", 1, 0 },
+          { "A", "a", 4, 0 },
+          { "baaaa", "aaaaa", 0, 0 },
+          { "baaaa", "aaaaa", 1, 1 },
+          { "baaaa", "aaaaa", 4, 1 },
+          { "abaaa", "aaaaa", 0, 0 },
+          { "abaaa", "aaaaa", 1, 0 },
+          { "abaaa", "aaaaa", 4, 1 },
+          { "aabaa", "aaaaa", 0, 0 },
+          { "aabaa", "aaaaa", 1, 0 },
+          { "aabaa", "aaaaa", 4, 1 },
+          { "aaaba", "aaaaa", 0, 0 },
+          { "aaaba", "aaaaa", 1, 0 },
+          { "aaaba", "aaaaa", 4, 1 },
+          { "aaaab", "aaaaa", 0, 0 },
+          { "aaaab", "aaaaa", 1, 0 },
+          { "aaaab", "aaaaa", 4, 0 },
+          { "word", "Word", 0, 0 },
+          { "word", "Word", 1, 0 },
+          { "word", "Word", 3, 0 },
+          { "word", "wOrd", 0, 0 },
+          { "word", "wOrd", 1, 0 },
+          { "word", "wOrd", 3, 0 },
+          { "word", "woRd", 0, 0 },
+          { "word", "woRd", 1, 0 },
+          { "word", "woRd", 3, 0 },
+          { "word", "worD", 0, 0 },
+          { "word", "worD", 1, 0 },
+          { "word", "worD", 3, 0 },
+          { "WORD", "wORD", 0, 0 },
+          { "WORD", "wORD", 1, 0 },
+          { "WORD", "wORD", 3, 0 },
+          { "WORD", "WoRD", 0, 0 },
+          { "WORD", "WoRD", 1, 0 },
+          { "WORD", "WoRD", 3, 0 },
+          { "WORD", "WOrD", 0, 0 },
+          { "WORD", "WOrD", 1, 0 },
+          { "WORD", "WOrD", 3, 0 },
+          { "WORD", "WORd", 0, 0 },
+          { "WORD", "WORd", 1, 0 },
+          { "WORD", "WORd", 3, 0 }
+      };
+
+    int i;
+
+    printf("Test 014 (PL_strncasecmp) ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        PRIntn rv = PL_strncasecmp(array[i].one, array[i].two, array[i].max);
+
+        switch( array[i].sign )
+        {
+            case -1:
+                if( rv < 0 ) continue;
+                break;
+            case 1:
+                if( rv > 0 ) continue;
+                break;
+            case 0:
+                if( 0 == rv ) continue;
+                break;
+            default:
+                PR_NOT_REACHED("static data inconsistancy");
+                break;
+        }
+
+        printf("FAIL %d: %s-%s/%ld -> %d, not %d\n", i,
+               array[i].one ? array[i].one : "(null)",
+               array[i].two ? array[i].two : "(null)",
+               array[i].max, rv, array[i].sign);
+        return PR_FALSE;
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strchr */
+PRBool test_015(void)
+{
+    static struct
+    {
+        const char *str;
+        char        chr;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, 'a', PR_FALSE, 0 },
+          { (const char *)0, '\0', PR_FALSE, 0 },
+          { "abcdefg", 'a', PR_TRUE, 0 },
+          { "abcdefg", 'b', PR_TRUE, 1 },
+          { "abcdefg", 'c', PR_TRUE, 2 },
+          { "abcdefg", 'd', PR_TRUE, 3 },
+          { "abcdefg", 'e', PR_TRUE, 4 },
+          { "abcdefg", 'f', PR_TRUE, 5 },
+          { "abcdefg", 'g', PR_TRUE, 6 },
+          { "abcdefg", 'h', PR_FALSE, 0 },
+          { "abcdefg", '\0', PR_TRUE, 7 },
+          { "abcdefg", 'A', PR_FALSE, 0 },
+          { "abcdefg", 'B', PR_FALSE, 0 },
+          { "abcdefg", 'C', PR_FALSE, 0 },
+          { "abcdefg", 'D', PR_FALSE, 0 },
+          { "abcdefg", 'E', PR_FALSE, 0 },
+          { "abcdefg", 'F', PR_FALSE, 0 },
+          { "abcdefg", 'G', PR_FALSE, 0 },
+          { "abcdefg", 'H', PR_FALSE, 0 },
+          { "abcdefgabcdefg", 'a', PR_TRUE, 0 },
+          { "abcdefgabcdefg", 'b', PR_TRUE, 1 },
+          { "abcdefgabcdefg", 'c', PR_TRUE, 2 },
+          { "abcdefgabcdefg", 'd', PR_TRUE, 3 },
+          { "abcdefgabcdefg", 'e', PR_TRUE, 4 },
+          { "abcdefgabcdefg", 'f', PR_TRUE, 5 },
+          { "abcdefgabcdefg", 'g', PR_TRUE, 6 },
+          { "abcdefgabcdefg", 'h', PR_FALSE, 0 },
+          { "abcdefgabcdefg", '\0', PR_TRUE, 14 }
+      };
+
+    int i;
+
+    printf("Test 015 (PL_strchr)      ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strchr(array[i].str, array[i].chr);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%c -> %.32s, not zero\n", i, array[i].str,
+                       array[i].chr, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%c -> null, not +%lu\n", i, array[i].str,
+                       array[i].chr, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%c -> 0x%x, not 0x%x+%lu\n", i, array[i].str,
+                       array[i].chr, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strrchr */
+PRBool test_016(void)
+{
+    static struct
+    {
+        const char *str;
+        char        chr;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, 'a', PR_FALSE, 0 },
+          { (const char *)0, '\0', PR_FALSE, 0 },
+          { "abcdefg", 'a', PR_TRUE, 0 },
+          { "abcdefg", 'b', PR_TRUE, 1 },
+          { "abcdefg", 'c', PR_TRUE, 2 },
+          { "abcdefg", 'd', PR_TRUE, 3 },
+          { "abcdefg", 'e', PR_TRUE, 4 },
+          { "abcdefg", 'f', PR_TRUE, 5 },
+          { "abcdefg", 'g', PR_TRUE, 6 },
+          { "abcdefg", 'h', PR_FALSE, 0 },
+          { "abcdefg", '\0', PR_TRUE, 7 },
+          { "abcdefg", 'A', PR_FALSE, 0 },
+          { "abcdefg", 'B', PR_FALSE, 0 },
+          { "abcdefg", 'C', PR_FALSE, 0 },
+          { "abcdefg", 'D', PR_FALSE, 0 },
+          { "abcdefg", 'E', PR_FALSE, 0 },
+          { "abcdefg", 'F', PR_FALSE, 0 },
+          { "abcdefg", 'G', PR_FALSE, 0 },
+          { "abcdefg", 'H', PR_FALSE, 0 },
+          { "abcdefgabcdefg", 'a', PR_TRUE, 7 },
+          { "abcdefgabcdefg", 'b', PR_TRUE, 8 },
+          { "abcdefgabcdefg", 'c', PR_TRUE, 9 },
+          { "abcdefgabcdefg", 'd', PR_TRUE, 10 },
+          { "abcdefgabcdefg", 'e', PR_TRUE, 11 },
+          { "abcdefgabcdefg", 'f', PR_TRUE, 12 },
+          { "abcdefgabcdefg", 'g', PR_TRUE, 13 },
+          { "abcdefgabcdefg", 'h', PR_FALSE, 0 },
+          { "abcdefgabcdefg", '\0', PR_TRUE, 14 }
+      };
+
+    int i;
+
+    printf("Test 016 (PL_strrchr)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strrchr(array[i].str, array[i].chr);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%c -> %.32s, not zero\n", i, array[i].str,
+                       array[i].chr, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%c -> null, not +%lu\n", i, array[i].str,
+                       array[i].chr, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%c -> 0x%x, not 0x%x+%lu\n", i, array[i].str,
+                       array[i].chr, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strnchr */
+PRBool test_017(void)
+{
+    static struct
+    {
+        const char *str;
+        char        chr;
+        PRUint32    max;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, 'a', 2, PR_FALSE, 0 },
+          { (const char *)0, '\0', 2, PR_FALSE, 0 },
+          { "abcdefg", 'a', 5, PR_TRUE, 0 },
+          { "abcdefg", 'b', 5, PR_TRUE, 1 },
+          { "abcdefg", 'c', 5, PR_TRUE, 2 },
+          { "abcdefg", 'd', 5, PR_TRUE, 3 },
+          { "abcdefg", 'e', 5, PR_TRUE, 4 },
+          { "abcdefg", 'f', 5, PR_FALSE, 0 },
+          { "abcdefg", 'g', 5, PR_FALSE, 0 },
+          { "abcdefg", 'h', 5, PR_FALSE, 0 },
+          { "abcdefg", '\0', 5, PR_FALSE, 0 },
+          { "abcdefg", '\0', 15, PR_TRUE, 7 },
+          { "abcdefg", 'A', 5, PR_FALSE, 0 },
+          { "abcdefg", 'B', 5, PR_FALSE, 0 },
+          { "abcdefg", 'C', 5, PR_FALSE, 0 },
+          { "abcdefg", 'D', 5, PR_FALSE, 0 },
+          { "abcdefg", 'E', 5, PR_FALSE, 0 },
+          { "abcdefg", 'F', 5, PR_FALSE, 0 },
+          { "abcdefg", 'G', 5, PR_FALSE, 0 },
+          { "abcdefg", 'H', 5, PR_FALSE, 0 },
+          { "abcdefgabcdefg", 'a', 10, PR_TRUE, 0 },
+          { "abcdefgabcdefg", 'b', 10, PR_TRUE, 1 },
+          { "abcdefgabcdefg", 'c', 10, PR_TRUE, 2 },
+          { "abcdefgabcdefg", 'd', 10, PR_TRUE, 3 },
+          { "abcdefgabcdefg", 'e', 10, PR_TRUE, 4 },
+          { "abcdefgabcdefg", 'f', 10, PR_TRUE, 5 },
+          { "abcdefgabcdefg", 'g', 10, PR_TRUE, 6 },
+          { "abcdefgabcdefg", 'h', 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", '\0', 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", '\0', 14, PR_FALSE, 0 },
+          { "abcdefgabcdefg", '\0', 15, PR_TRUE, 14 }
+      };
+
+    int i;
+
+    printf("Test 017 (PL_strnchr)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strnchr(array[i].str, array[i].chr, array[i].max);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%c/%lu -> %.32s, not zero\n", i, array[i].str,
+                       array[i].chr, array[i].max, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%c/%lu -> null, not +%lu\n", i, array[i].str,
+                       array[i].chr, array[i].max, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%c/%lu -> 0x%x, not 0x%x+%lu\n", i, array[i].str,
+                       array[i].chr, array[i].max, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strnrchr */
+PRBool test_018(void)
+{
+    static struct
+    {
+        const char *str;
+        char        chr;
+        PRUint32    max;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, 'a', 2, PR_FALSE, 0 },
+          { (const char *)0, '\0', 2, PR_FALSE, 0 },
+          { "abcdefg", 'a', 5, PR_TRUE, 0 },
+          { "abcdefg", 'b', 5, PR_TRUE, 1 },
+          { "abcdefg", 'c', 5, PR_TRUE, 2 },
+          { "abcdefg", 'd', 5, PR_TRUE, 3 },
+          { "abcdefg", 'e', 5, PR_TRUE, 4 },
+          { "abcdefg", 'f', 5, PR_FALSE, 0 },
+          { "abcdefg", 'g', 5, PR_FALSE, 0 },
+          { "abcdefg", 'h', 5, PR_FALSE, 0 },
+          { "abcdefg", '\0', 5, PR_FALSE, 0 },
+          { "abcdefg", '\0', 15, PR_TRUE, 7 },
+          { "abcdefg", 'A', 5, PR_FALSE, 0 },
+          { "abcdefg", 'B', 5, PR_FALSE, 0 },
+          { "abcdefg", 'C', 5, PR_FALSE, 0 },
+          { "abcdefg", 'D', 5, PR_FALSE, 0 },
+          { "abcdefg", 'E', 5, PR_FALSE, 0 },
+          { "abcdefg", 'F', 5, PR_FALSE, 0 },
+          { "abcdefg", 'G', 5, PR_FALSE, 0 },
+          { "abcdefg", 'H', 5, PR_FALSE, 0 },
+          { "abcdefgabcdefg", 'a', 10, PR_TRUE, 7 },
+          { "abcdefgabcdefg", 'b', 10, PR_TRUE, 8 },
+          { "abcdefgabcdefg", 'c', 10, PR_TRUE, 9 },
+          { "abcdefgabcdefg", 'd', 10, PR_TRUE, 3 },
+          { "abcdefgabcdefg", 'e', 10, PR_TRUE, 4 },
+          { "abcdefgabcdefg", 'f', 10, PR_TRUE, 5 },
+          { "abcdefgabcdefg", 'g', 10, PR_TRUE, 6 },
+          { "abcdefgabcdefg", 'h', 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", '\0', 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", '\0', 14, PR_FALSE, 0 },
+          { "abcdefgabcdefg", '\0', 15, PR_TRUE, 14 }
+      };
+
+    int i;
+
+    printf("Test 018 (PL_strnrchr)    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strnrchr(array[i].str, array[i].chr, array[i].max);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%c/%lu -> %.32s, not zero\n", i, array[i].str,
+                       array[i].chr, array[i].max, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%c/%lu -> null, not +%lu\n", i, array[i].str,
+                       array[i].chr, array[i].max, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%c/%lu -> 0x%x, not 0x%x+%lu\n", i, array[i].str,
+                       array[i].chr, array[i].max, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strpbrk */
+PRBool test_019(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *chrs;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, PR_FALSE, 0 },
+          { (const char *)0, "abc", PR_FALSE, 0 },
+          { "abc", (const char *)0, PR_FALSE, 0 },
+          { "abcdefg", "", PR_FALSE, 0 },
+          { "", "aeiou", PR_FALSE, 0 },
+          { "abcdefg", "ae", PR_TRUE, 0 },
+          { "abcdefg", "ei", PR_TRUE, 4 },
+          { "abcdefg", "io", PR_FALSE, 0 },
+          { "abcdefg", "bcd", PR_TRUE, 1 },
+          { "abcdefg", "cbd", PR_TRUE, 1 },
+          { "abcdefg", "dbc", PR_TRUE, 1 },
+          { "abcdefg", "ghi", PR_TRUE, 6 },
+          { "abcdefg", "AE", PR_FALSE, 0 },
+          { "abcdefg", "EI", PR_FALSE, 0 },
+          { "abcdefg", "IO", PR_FALSE, 0 },
+          { "abcdefg", "BCD", PR_FALSE, 0 },
+          { "abcdefg", "CBD", PR_FALSE, 0 },
+          { "abcdefg", "DBC", PR_FALSE, 0 },
+          { "abcdefg", "GHI", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ae", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "ei", PR_TRUE, 4 },
+          { "abcdefgabcdefg", "io", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "bcd", PR_TRUE, 1 },
+          { "abcdefgabcdefg", "cbd", PR_TRUE, 1 },
+          { "abcdefgabcdefg", "dbc", PR_TRUE, 1 },
+          { "abcdefgabcdefg", "ghi", PR_TRUE, 6 },
+          { "abcdefgabcdefg", "AE", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "EI", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "IO", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "BCD", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "CBD", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "DBC", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "GHI", PR_FALSE, 0 }
+      };
+
+    int i;
+
+    printf("Test 019 (PL_strpbrk)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strpbrk(array[i].str, array[i].chrs);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s -> %.32s, not null\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s -> null, not +%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strprbrk */
+PRBool test_020(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *chrs;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, PR_FALSE, 0 },
+          { (const char *)0, "abc", PR_FALSE, 0 },
+          { "abc", (const char *)0, PR_FALSE, 0 },
+          { "abcdefg", "", PR_FALSE, 0 },
+          { "", "aeiou", PR_FALSE, 0 },
+          { "abcdefg", "ae", PR_TRUE, 4 },
+          { "abcdefg", "ei", PR_TRUE, 4 },
+          { "abcdefg", "io", PR_FALSE, 0 },
+          { "abcdefg", "bcd", PR_TRUE, 3 },
+          { "abcdefg", "cbd", PR_TRUE, 3 },
+          { "abcdefg", "dbc", PR_TRUE, 3 },
+          { "abcdefg", "ghi", PR_TRUE, 6 },
+          { "abcdefg", "AE", PR_FALSE, 0 },
+          { "abcdefg", "EI", PR_FALSE, 0 },
+          { "abcdefg", "IO", PR_FALSE, 0 },
+          { "abcdefg", "BCD", PR_FALSE, 0 },
+          { "abcdefg", "CBD", PR_FALSE, 0 },
+          { "abcdefg", "DBC", PR_FALSE, 0 },
+          { "abcdefg", "GHI", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ae", PR_TRUE, 11 },
+          { "abcdefgabcdefg", "ei", PR_TRUE, 11 },
+          { "abcdefgabcdefg", "io", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "bcd", PR_TRUE, 10 },
+          { "abcdefgabcdefg", "cbd", PR_TRUE, 10 },
+          { "abcdefgabcdefg", "dbc", PR_TRUE, 10 },
+          { "abcdefgabcdefg", "ghi", PR_TRUE, 13 },
+          { "abcdefgabcdefg", "AE", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "EI", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "IO", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "BCD", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "CBD", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "DBC", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "GHI", PR_FALSE, 0 }
+      };
+
+    int i;
+
+    printf("Test 020 (PL_strprbrk)    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strprbrk(array[i].str, array[i].chrs);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s -> %.32s, not null\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s -> null, not +%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+                       
+/* PL_strnpbrk */
+PRBool test_021(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *chrs;
+        PRUint32    max;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 3, PR_FALSE, 0 },
+          { (const char *)0, "abc", 3, PR_FALSE, 0 },
+          { "abc", (const char *)0, 3, PR_FALSE, 0 },
+          { "abcdefg", "", 3, PR_FALSE, 0 },
+          { "", "aeiou", 3, PR_FALSE, 0 },
+          { "abcdefg", "ae", 0, PR_FALSE, 0 },
+          { "abcdefg", "ae", 1, PR_TRUE, 0 },
+          { "abcdefg", "ae", 4, PR_TRUE, 0 },
+          { "abcdefg", "ae", 5, PR_TRUE, 0 },
+          { "abcdefg", "ae", 6, PR_TRUE, 0 },
+          { "abcdefg", "ei", 4, PR_FALSE, 0 },
+          { "abcdefg", "io", 10, PR_FALSE, 0 },
+          { "abcdefg", "bcd", 2, PR_TRUE, 1 },
+          { "abcdefg", "cbd", 2, PR_TRUE, 1 },
+          { "abcdefg", "dbc", 2, PR_TRUE, 1 },
+          { "abcdefg", "ghi", 6, PR_FALSE, 0 },
+          { "abcdefg", "ghi", 7, PR_TRUE, 6 },
+          { "abcdefg", "AE", 9, PR_FALSE, 0 },
+          { "abcdefg", "EI", 9, PR_FALSE, 0 },
+          { "abcdefg", "IO", 9, PR_FALSE, 0 },
+          { "abcdefg", "BCD", 9, PR_FALSE, 0 },
+          { "abcdefg", "CBD", 9, PR_FALSE, 0 },
+          { "abcdefg", "DBC", 9, PR_FALSE, 0 },
+          { "abcdefg", "GHI", 9, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ae", 10, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "ei", 10, PR_TRUE, 4 },
+          { "abcdefgabcdefg", "io", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "bcd", 10, PR_TRUE, 1 },
+          { "abcdefgabcdefg", "cbd", 10, PR_TRUE, 1 },
+          { "abcdefgabcdefg", "dbc", 10, PR_TRUE, 1 },
+          { "abcdefgabcdefg", "ghi", 10, PR_TRUE, 6 },
+          { "abcdefgabcdefg", "AE", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "EI", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "IO", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "BCD", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "CBD", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "DBC", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "GHI", 10, PR_FALSE, 0 }
+      };
+
+    int i;
+
+    printf("Test 021 (PL_strnpbrk)    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strnpbrk(array[i].str, array[i].chrs, array[i].max);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       array[i].max, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> null, not +%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       array[i].max, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       array[i].max, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strnprbrk */
+PRBool test_022(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *chrs;
+        PRUint32    max;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 3, PR_FALSE, 0 },
+          { (const char *)0, "abc", 3, PR_FALSE, 0 },
+          { "abc", (const char *)0, 3, PR_FALSE, 0 },
+          { "abcdefg", "", 3, PR_FALSE, 0 },
+          { "", "aeiou", 3, PR_FALSE, 0 },
+          { "abcdefg", "ae", 0, PR_FALSE, 0 },
+          { "abcdefg", "ae", 1, PR_TRUE, 0 },
+          { "abcdefg", "ae", 4, PR_TRUE, 0 },
+          { "abcdefg", "ae", 5, PR_TRUE, 4 },
+          { "abcdefg", "ae", 6, PR_TRUE,  4 },
+          { "abcdefg", "ei", 4, PR_FALSE, 0 },
+          { "abcdefg", "io", 10, PR_FALSE, 0 },
+          { "abcdefg", "bcd", 2, PR_TRUE, 1 },
+          { "abcdefg", "cbd", 2, PR_TRUE, 1 },
+          { "abcdefg", "dbc", 2, PR_TRUE, 1 },
+          { "abcdefg", "bcd", 3, PR_TRUE, 2 },
+          { "abcdefg", "cbd", 3, PR_TRUE, 2 },
+          { "abcdefg", "dbc", 3, PR_TRUE, 2 },
+          { "abcdefg", "bcd", 5, PR_TRUE, 3 },
+          { "abcdefg", "cbd", 5, PR_TRUE, 3 },
+          { "abcdefg", "dbc", 5, PR_TRUE, 3 },
+          { "abcdefg", "bcd", 15, PR_TRUE, 3 },
+          { "abcdefg", "cbd", 15, PR_TRUE, 3 },
+          { "abcdefg", "dbc", 15, PR_TRUE, 3 },
+          { "abcdefg", "ghi", 6, PR_FALSE, 0 },
+          { "abcdefg", "ghi", 7, PR_TRUE, 6 },
+          { "abcdefg", "AE", 9, PR_FALSE, 0 },
+          { "abcdefg", "EI", 9, PR_FALSE, 0 },
+          { "abcdefg", "IO", 9, PR_FALSE, 0 },
+          { "abcdefg", "BCD", 9, PR_FALSE, 0 },
+          { "abcdefg", "CBD", 9, PR_FALSE, 0 },
+          { "abcdefg", "DBC", 9, PR_FALSE, 0 },
+          { "abcdefg", "GHI", 9, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ae", 10, PR_TRUE, 7 },
+          { "abcdefgabcdefg", "ei", 10, PR_TRUE, 4 },
+          { "abcdefgabcdefg", "io", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "bcd", 10, PR_TRUE, 9 },
+          { "abcdefgabcdefg", "cbd", 10, PR_TRUE, 9 },
+          { "abcdefgabcdefg", "dbc", 10, PR_TRUE, 9 },
+          { "abcdefgabcdefg", "ghi", 10, PR_TRUE, 6 },
+          { "abcdefgabcdefg", "AE", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "EI", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "IO", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "BCD", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "CBD", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "DBC", 10, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "GHI", 10, PR_FALSE, 0 }
+      };
+
+    int i;
+
+    printf("Test 022 (PL_strnprbrk)   ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strnprbrk(array[i].str, array[i].chrs, array[i].max);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       array[i].max, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> null, not +%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       array[i].max, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].chrs ? array[i].chrs : "(null)", 
+                       array[i].max, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strstr */
+PRBool test_023(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *sub;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, PR_FALSE, 0 },
+          { (const char *)0, "blah", PR_FALSE, 0 },
+          { "blah-de-blah", (const char *)0, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", PR_TRUE, 0 },
+          { "", "blah", PR_FALSE, 0 },
+          { "blah-de-blah", "", PR_FALSE, 0 },
+          { "abcdefg", "a", PR_TRUE, 0 },
+          { "abcdefg", "c", PR_TRUE, 2 },
+          { "abcdefg", "e", PR_TRUE, 4 },
+          { "abcdefg", "g", PR_TRUE, 6 },
+          { "abcdefg", "i", PR_FALSE, 0 },
+          { "abcdefg", "ab", PR_TRUE, 0 },
+          { "abcdefg", "cd", PR_TRUE, 2 },
+          { "abcdefg", "ef", PR_TRUE, 4 },
+          { "abcdefg", "gh", PR_FALSE, 0 },
+          { "abcdabc", "bc", PR_TRUE, 1 },
+          { "abcdefg", "abcdefg", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "a", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "c", PR_TRUE, 2 },
+          { "abcdefgabcdefg", "e", PR_TRUE, 4 },
+          { "abcdefgabcdefg", "g", PR_TRUE, 6 },
+          { "abcdefgabcdefg", "i", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ab", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "cd", PR_TRUE, 2 },
+          { "abcdefgabcdefg", "ef", PR_TRUE, 4 },
+          { "abcdefgabcdefg", "gh", PR_FALSE, 0 },
+          { "abcdabcabcdabc", "bc", PR_TRUE, 1 },
+          { "abcdefgabcdefg", "abcdefg", PR_TRUE, 0 },
+          { "ABCDEFG", "a", PR_FALSE, 0 },
+          { "ABCDEFG", "c", PR_FALSE, 0 },
+          { "ABCDEFG", "e", PR_FALSE, 0 },
+          { "ABCDEFG", "g", PR_FALSE, 0 },
+          { "ABCDEFG", "i", PR_FALSE, 0 },
+          { "ABCDEFG", "ab", PR_FALSE, 0 },
+          { "ABCDEFG", "cd", PR_FALSE, 0 },
+          { "ABCDEFG", "ef", PR_FALSE, 0 },
+          { "ABCDEFG", "gh", PR_FALSE, 0 },
+          { "ABCDABC", "bc", PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "a", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "c", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "e", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "g", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ab", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "cd", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ef", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", PR_FALSE, 0 }
+      };
+
+    int i;
+
+    printf("Test 023 (PL_strstr)      ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strstr(array[i].str, array[i].sub);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strrstr */
+PRBool test_024(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *sub;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, PR_FALSE, 0 },
+          { (const char *)0, "blah", PR_FALSE, 0 },
+          { "blah-de-blah", (const char *)0, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", PR_TRUE, 8 },
+          { "", "blah", PR_FALSE, 0 },
+          { "blah-de-blah", "", PR_FALSE, 0 },
+          { "abcdefg", "a", PR_TRUE, 0 },
+          { "abcdefg", "c", PR_TRUE, 2 },
+          { "abcdefg", "e", PR_TRUE, 4 },
+          { "abcdefg", "g", PR_TRUE, 6 },
+          { "abcdefg", "i", PR_FALSE, 0 },
+          { "abcdefg", "ab", PR_TRUE, 0 },
+          { "abcdefg", "cd", PR_TRUE, 2 },
+          { "abcdefg", "ef", PR_TRUE, 4 },
+          { "abcdefg", "gh", PR_FALSE, 0 },
+          { "abcdabc", "bc", PR_TRUE, 5 },
+          { "abcdefg", "abcdefg", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "a", PR_TRUE, 7 },
+          { "abcdefgabcdefg", "c", PR_TRUE, 9 },
+          { "abcdefgabcdefg", "e", PR_TRUE, 11 },
+          { "abcdefgabcdefg", "g", PR_TRUE, 13 },
+          { "abcdefgabcdefg", "i", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ab", PR_TRUE, 7 },
+          { "abcdefgabcdefg", "cd", PR_TRUE, 9 },
+          { "abcdefgabcdefg", "ef", PR_TRUE, 11 },
+          { "abcdefgabcdefg", "gh", PR_FALSE, 0 },
+          { "abcdabcabcdabc", "bc", PR_TRUE, 12 },
+          { "abcdefgabcdefg", "abcdefg", PR_TRUE, 7 },
+          { "ABCDEFG", "a", PR_FALSE, 0 },
+          { "ABCDEFG", "c", PR_FALSE, 0 },
+          { "ABCDEFG", "e", PR_FALSE, 0 },
+          { "ABCDEFG", "g", PR_FALSE, 0 },
+          { "ABCDEFG", "i", PR_FALSE, 0 },
+          { "ABCDEFG", "ab", PR_FALSE, 0 },
+          { "ABCDEFG", "cd", PR_FALSE, 0 },
+          { "ABCDEFG", "ef", PR_FALSE, 0 },
+          { "ABCDEFG", "gh", PR_FALSE, 0 },
+          { "ABCDABC", "bc", PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "a", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "c", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "e", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "g", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ab", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "cd", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ef", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", PR_FALSE, 0 }
+      };
+
+    int i;
+
+    printf("Test 024 (PL_strrstr)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strrstr(array[i].str, array[i].sub);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strnstr */
+PRBool test_025(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *sub;
+        PRUint32    max;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 12, PR_FALSE, 0 },
+          { (const char *)0, "blah", 12, PR_FALSE, 0 },
+          { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 0, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 2, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 3, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 4, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 5, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 12, PR_TRUE, 0 },
+          { "", "blah", 12, PR_FALSE, 0 },
+          { "blah-de-blah", "", 12, PR_FALSE, 0 },
+          { "abcdefg", "a", 5, PR_TRUE, 0 },
+          { "abcdefg", "c", 5, PR_TRUE, 2 },
+          { "abcdefg", "e", 5, PR_TRUE, 4 },
+          { "abcdefg", "g", 5, PR_FALSE, 0 },
+          { "abcdefg", "i", 5, PR_FALSE, 0 },
+          { "abcdefg", "ab", 5, PR_TRUE, 0 },
+          { "abcdefg", "cd", 5, PR_TRUE, 2 },
+          { "abcdefg", "ef", 5, PR_FALSE, 0 },
+          { "abcdefg", "gh", 5, PR_FALSE, 0 },
+          { "abcdabc", "bc", 5, PR_TRUE, 1 },
+          { "abcdabc", "bc", 6, PR_TRUE, 1 },
+          { "abcdabc", "bc", 7, PR_TRUE, 1 },
+          { "abcdefg", "abcdefg", 6, PR_FALSE, 0 },
+          { "abcdefg", "abcdefg", 7, PR_TRUE, 0 },
+          { "abcdefg", "abcdefg", 8, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "a", 12, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "c", 12, PR_TRUE, 2 },
+          { "abcdefgabcdefg", "e", 12, PR_TRUE, 4 },
+          { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 },
+          { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ab", 12, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "cd", 12, PR_TRUE, 2 },
+          { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 },
+          { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 },
+          { "abcdabcabcdabc", "bc", 5, PR_TRUE, 1 },
+          { "abcdabcabcdabc", "bc", 6, PR_TRUE, 1 },
+          { "abcdabcabcdabc", "bc", 7, PR_TRUE, 1 },
+          { "abcdefgabcdefg", "abcdefg", 6, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "abcdefg", 7, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "abcdefg", 8, PR_TRUE, 0 },
+          { "ABCDEFG", "a", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "c", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "e", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "g", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "i", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "ab", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "cd", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "ef", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "gh", 5, PR_FALSE, 0 },
+          { "ABCDABC", "bc", 5, PR_FALSE, 0 },
+          { "ABCDABC", "bc", 6, PR_FALSE, 0 },
+          { "ABCDABC", "bc", 7, PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", 7, PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", 8, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "a", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "c", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "e", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "g", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ab", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "cd", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ef", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", 5, PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", 6, PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", 7, PR_FALSE,  },
+          { "ABCDEFGABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", 7, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", 8, PR_FALSE, 0 }
+      };
+
+    int i;
+
+    printf("Test 025 (PL_strnstr)     ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strnstr(array[i].str, array[i].sub, array[i].max);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strnrstr */
+PRBool test_026(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *sub;
+        PRUint32    max;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 12, PR_FALSE, 0 },
+          { (const char *)0, "blah", 12, PR_FALSE, 0 },
+          { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 0, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 2, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 3, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 4, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 5, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 11, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 12, PR_TRUE, 8 },
+          { "blah-de-blah", "blah", 13, PR_TRUE, 8 },
+          { "", "blah", 12, PR_FALSE, 0 },
+          { "blah-de-blah", "", 12, PR_FALSE, 0 },
+          { "abcdefg", "a", 5, PR_TRUE, 0 },
+          { "abcdefg", "c", 5, PR_TRUE, 2 },
+          { "abcdefg", "e", 5, PR_TRUE, 4 },
+          { "abcdefg", "g", 5, PR_FALSE, 0 },
+          { "abcdefg", "i", 5, PR_FALSE, 0 },
+          { "abcdefg", "ab", 5, PR_TRUE, 0 },
+          { "abcdefg", "cd", 5, PR_TRUE, 2 },
+          { "abcdefg", "ef", 5, PR_FALSE, 0 },
+          { "abcdefg", "gh", 5, PR_FALSE, 0 },
+          { "abcdabc", "bc", 5, PR_TRUE, 1 },
+          { "abcdabc", "bc", 6, PR_TRUE, 1 },
+          { "abcdabc", "bc", 7, PR_TRUE, 5 },
+          { "abcdefg", "abcdefg", 6, PR_FALSE, 0 },
+          { "abcdefg", "abcdefg", 7, PR_TRUE, 0 },
+          { "abcdefg", "abcdefg", 8, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "a", 12, PR_TRUE, 7 },
+          { "abcdefgabcdefg", "c", 12, PR_TRUE, 9 },
+          { "abcdefgabcdefg", "e", 12, PR_TRUE, 11 },
+          { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 },
+          { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ab", 12, PR_TRUE, 7 },
+          { "abcdefgabcdefg", "cd", 12, PR_TRUE, 9 },
+          { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 },
+          { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 },
+          { "abcdabcabcdabc", "bc", 12, PR_TRUE, 8 },
+          { "abcdabcabcdabc", "bc", 13, PR_TRUE, 8 },
+          { "abcdabcabcdabc", "bc", 14, PR_TRUE, 12 },
+          { "abcdefgabcdefg", "abcdefg", 13, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "abcdefg", 14, PR_TRUE, 7 },
+          { "abcdefgabcdefg", "abcdefg", 15, PR_TRUE, 7 },
+          { "ABCDEFG", "a", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "c", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "e", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "g", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "i", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "ab", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "cd", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "ef", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "gh", 5, PR_FALSE, 0 },
+          { "ABCDABC", "bc", 5, PR_FALSE, 0 },
+          { "ABCDABC", "bc", 6, PR_FALSE, 0 },
+          { "ABCDABC", "bc", 7, PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", 7, PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", 8, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "a", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "c", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "e", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "g", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ab", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "cd", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ef", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", 12, PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", 13, PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", 14, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", 13, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", 14, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", 15, PR_FALSE, 0 }
+      };
+
+    int i;
+
+    printf("Test 026 (PL_strnrstr)    ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strnrstr(array[i].str, array[i].sub, array[i].max);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strcasestr */
+PRBool test_027(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *sub;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, PR_FALSE, 0 },
+          { (const char *)0, "blah", PR_FALSE, 0 },
+          { "blah-de-blah", (const char *)0, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", PR_TRUE, 0 },
+          { "", "blah", PR_FALSE, 0 },
+          { "blah-de-blah", "", PR_FALSE, 0 },
+          { "abcdefg", "a", PR_TRUE, 0 },
+          { "abcdefg", "c", PR_TRUE, 2 },
+          { "abcdefg", "e", PR_TRUE, 4 },
+          { "abcdefg", "g", PR_TRUE, 6 },
+          { "abcdefg", "i", PR_FALSE, 0 },
+          { "abcdefg", "ab", PR_TRUE, 0 },
+          { "abcdefg", "cd", PR_TRUE, 2 },
+          { "abcdefg", "ef", PR_TRUE, 4 },
+          { "abcdefg", "gh", PR_FALSE, 0 },
+          { "abcdabc", "bc", PR_TRUE, 1 },
+          { "abcdefg", "abcdefg", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "a", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "c", PR_TRUE, 2 },
+          { "abcdefgabcdefg", "e", PR_TRUE, 4 },
+          { "abcdefgabcdefg", "g", PR_TRUE, 6 },
+          { "abcdefgabcdefg", "i", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ab", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "cd", PR_TRUE, 2 },
+          { "abcdefgabcdefg", "ef", PR_TRUE, 4 },
+          { "abcdefgabcdefg", "gh", PR_FALSE, 0 },
+          { "abcdabcabcdabc", "bc", PR_TRUE, 1 },
+          { "abcdefgabcdefg", "abcdefg", PR_TRUE, 0 },
+          { "ABCDEFG", "a", PR_TRUE, 0 },
+          { "ABCDEFG", "c", PR_TRUE, 2 },
+          { "ABCDEFG", "e", PR_TRUE, 4 },
+          { "ABCDEFG", "g", PR_TRUE, 6 },
+          { "ABCDEFG", "i", PR_FALSE, 0 },
+          { "ABCDEFG", "ab", PR_TRUE, 0 },
+          { "ABCDEFG", "cd", PR_TRUE, 2 },
+          { "ABCDEFG", "ef", PR_TRUE, 4 },
+          { "ABCDEFG", "gh", PR_FALSE, 0 },
+          { "ABCDABC", "bc", PR_TRUE, 1 },
+          { "ABCDEFG", "abcdefg", PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "a", PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "c", PR_TRUE, 2 },
+          { "ABCDEFGABCDEFG", "e", PR_TRUE, 4 },
+          { "ABCDEFGABCDEFG", "g", PR_TRUE, 6 },
+          { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ab", PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "cd", PR_TRUE, 2 },
+          { "ABCDEFGABCDEFG", "ef", PR_TRUE, 4 },
+          { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", PR_TRUE, 1 },
+          { "ABCDEFGABCDEFG", "abcdefg", PR_TRUE, 0 }
+      };
+
+    int i;
+
+    printf("Test 027 (PL_strcasestr)  ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strcasestr(array[i].str, array[i].sub);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strcaserstr */
+PRBool test_028(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *sub;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, PR_FALSE, 0 },
+          { (const char *)0, "blah", PR_FALSE, 0 },
+          { "blah-de-blah", (const char *)0, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", PR_TRUE, 8 },
+          { "", "blah", PR_FALSE, 0 },
+          { "blah-de-blah", "", PR_FALSE, 0 },
+          { "abcdefg", "a", PR_TRUE, 0 },
+          { "abcdefg", "c", PR_TRUE, 2 },
+          { "abcdefg", "e", PR_TRUE, 4 },
+          { "abcdefg", "g", PR_TRUE, 6 },
+          { "abcdefg", "i", PR_FALSE, 0 },
+          { "abcdefg", "ab", PR_TRUE, 0 },
+          { "abcdefg", "cd", PR_TRUE, 2 },
+          { "abcdefg", "ef", PR_TRUE, 4 },
+          { "abcdefg", "gh", PR_FALSE, 0 },
+          { "abcdabc", "bc", PR_TRUE, 5 },
+          { "abcdefg", "abcdefg", PR_TRUE, 0 },
+          { "abcdefgabcdefg", "a", PR_TRUE, 7 },
+          { "abcdefgabcdefg", "c", PR_TRUE, 9 },
+          { "abcdefgabcdefg", "e", PR_TRUE, 11 },
+          { "abcdefgabcdefg", "g", PR_TRUE, 13 },
+          { "abcdefgabcdefg", "i", PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ab", PR_TRUE, 7 },
+          { "abcdefgabcdefg", "cd", PR_TRUE, 9 },
+          { "abcdefgabcdefg", "ef", PR_TRUE, 11 },
+          { "abcdefgabcdefg", "gh", PR_FALSE, 0 },
+          { "abcdabcabcdabc", "bc", PR_TRUE, 12 },
+          { "abcdefgabcdefg", "abcdefg", PR_TRUE, 7 },
+          { "ABCDEFG", "a", PR_TRUE, 0 },
+          { "ABCDEFG", "c", PR_TRUE, 2 },
+          { "ABCDEFG", "e", PR_TRUE, 4 },
+          { "ABCDEFG", "g", PR_TRUE, 6 },
+          { "ABCDEFG", "i", PR_FALSE, 0 },
+          { "ABCDEFG", "ab", PR_TRUE, 0 },
+          { "ABCDEFG", "cd", PR_TRUE, 2 },
+          { "ABCDEFG", "ef", PR_TRUE, 4 },
+          { "ABCDEFG", "gh", PR_FALSE, 0 },
+          { "ABCDABC", "bc", PR_TRUE, 5 },
+          { "ABCDEFG", "abcdefg", PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "a", PR_TRUE, 7 },
+          { "ABCDEFGABCDEFG", "c", PR_TRUE, 9 },
+          { "ABCDEFGABCDEFG", "e", PR_TRUE, 11 },
+          { "ABCDEFGABCDEFG", "g", PR_TRUE, 13 },
+          { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ab", PR_TRUE, 7 },
+          { "ABCDEFGABCDEFG", "cd", PR_TRUE, 9 },
+          { "ABCDEFGABCDEFG", "ef", PR_TRUE, 11 },
+          { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", PR_TRUE, 12 },
+          { "ABCDEFGABCDEFG", "abcdefg", PR_TRUE, 7 }
+      };
+
+    int i;
+
+    printf("Test 028 (PL_strcaserstr) ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strcaserstr(array[i].str, array[i].sub);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strncasestr */
+PRBool test_029(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *sub;
+        PRUint32    max;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 12, PR_FALSE, 0 },
+          { (const char *)0, "blah", 12, PR_FALSE, 0 },
+          { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 0, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 2, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 3, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 4, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 5, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 12, PR_TRUE, 0 },
+          { "", "blah", 12, PR_FALSE, 0 },
+          { "blah-de-blah", "", 12, PR_FALSE, 0 },
+          { "abcdefg", "a", 5, PR_TRUE, 0 },
+          { "abcdefg", "c", 5, PR_TRUE, 2 },
+          { "abcdefg", "e", 5, PR_TRUE, 4 },
+          { "abcdefg", "g", 5, PR_FALSE, 0 },
+          { "abcdefg", "i", 5, PR_FALSE, 0 },
+          { "abcdefg", "ab", 5, PR_TRUE, 0 },
+          { "abcdefg", "cd", 5, PR_TRUE, 2 },
+          { "abcdefg", "ef", 5, PR_FALSE, 0 },
+          { "abcdefg", "gh", 5, PR_FALSE, 0 },
+          { "abcdabc", "bc", 5, PR_TRUE, 1 },
+          { "abcdabc", "bc", 6, PR_TRUE, 1 },
+          { "abcdabc", "bc", 7, PR_TRUE, 1 },
+          { "abcdefg", "abcdefg", 6, PR_FALSE, 0 },
+          { "abcdefg", "abcdefg", 7, PR_TRUE, 0 },
+          { "abcdefg", "abcdefg", 8, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "a", 12, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "c", 12, PR_TRUE, 2 },
+          { "abcdefgabcdefg", "e", 12, PR_TRUE, 4 },
+          { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 },
+          { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ab", 12, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "cd", 12, PR_TRUE, 2 },
+          { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 },
+          { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 },
+          { "abcdabcabcdabc", "bc", 5, PR_TRUE, 1 },
+          { "abcdabcabcdabc", "bc", 6, PR_TRUE, 1 },
+          { "abcdabcabcdabc", "bc", 7, PR_TRUE, 1 },
+          { "abcdefgabcdefg", "abcdefg", 6, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "abcdefg", 7, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "abcdefg", 8, PR_TRUE, 0 },
+          { "ABCDEFG", "a", 5, PR_TRUE, 0 },
+          { "ABCDEFG", "c", 5, PR_TRUE, 2 },
+          { "ABCDEFG", "e", 5, PR_TRUE, 4 },
+          { "ABCDEFG", "g", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "i", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "ab", 5, PR_TRUE, 0 },
+          { "ABCDEFG", "cd", 5, PR_TRUE, 2 },
+          { "ABCDEFG", "ef", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "gh", 5, PR_FALSE, 0 },
+          { "ABCDABC", "bc", 5, PR_TRUE, 1 },
+          { "ABCDABC", "bc", 6, PR_TRUE, 1 },
+          { "ABCDABC", "bc", 7, PR_TRUE, 1 },
+          { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", 7, PR_TRUE, 0 },
+          { "ABCDEFG", "abcdefg", 8, PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "a", 12, PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "c", 12, PR_TRUE, 2 },
+          { "ABCDEFGABCDEFG", "e", 12, PR_TRUE, 4 },
+          { "ABCDEFGABCDEFG", "g", 12, PR_TRUE, 6 },
+          { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ab", 12, PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "cd", 12, PR_TRUE, 2 },
+          { "ABCDEFGABCDEFG", "ef", 12, PR_TRUE, 4 },
+          { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", 5, PR_TRUE, 1 },
+          { "ABCDABCABCDABC", "bc", 6, PR_TRUE, 1 },
+          { "ABCDABCABCDABC", "bc", 7, PR_TRUE, 1 },
+          { "ABCDEFGABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", 7, PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", 8, PR_TRUE, 0 }
+      };
+
+    int i;
+
+    printf("Test 029 (PL_strncasestr) ..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strncasestr(array[i].str, array[i].sub, array[i].max);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strncaserstr */
+PRBool test_030(void)
+{
+    static struct
+    {
+        const char *str;
+        const char *sub;
+        PRUint32    max;
+        PRBool      ret;
+        PRUint32    off;
+    } array[] =
+      {
+          { (const char *)0, (const char *)0, 12, PR_FALSE, 0 },
+          { (const char *)0, "blah", 12, PR_FALSE, 0 },
+          { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 0, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 2, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 3, PR_FALSE, 0 },
+          { "blah-de-blah", "blah", 4, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 5, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 11, PR_TRUE, 0 },
+          { "blah-de-blah", "blah", 12, PR_TRUE, 8 },
+          { "blah-de-blah", "blah", 13, PR_TRUE, 8 },
+          { "", "blah", 12, PR_FALSE, 0 },
+          { "blah-de-blah", "", 12, PR_FALSE, 0 },
+          { "abcdefg", "a", 5, PR_TRUE, 0 },
+          { "abcdefg", "c", 5, PR_TRUE, 2 },
+          { "abcdefg", "e", 5, PR_TRUE, 4 },
+          { "abcdefg", "g", 5, PR_FALSE, 0 },
+          { "abcdefg", "i", 5, PR_FALSE, 0 },
+          { "abcdefg", "ab", 5, PR_TRUE, 0 },
+          { "abcdefg", "cd", 5, PR_TRUE, 2 },
+          { "abcdefg", "ef", 5, PR_FALSE, 0 },
+          { "abcdefg", "gh", 5, PR_FALSE, 0 },
+          { "abcdabc", "bc", 5, PR_TRUE, 1 },
+          { "abcdabc", "bc", 6, PR_TRUE, 1 },
+          { "abcdabc", "bc", 7, PR_TRUE, 5 },
+          { "abcdefg", "abcdefg", 6, PR_FALSE, 0 },
+          { "abcdefg", "abcdefg", 7, PR_TRUE, 0 },
+          { "abcdefg", "abcdefg", 8, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "a", 12, PR_TRUE, 7 },
+          { "abcdefgabcdefg", "c", 12, PR_TRUE, 9 },
+          { "abcdefgabcdefg", "e", 12, PR_TRUE, 11 },
+          { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 },
+          { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 },
+          { "abcdefgabcdefg", "ab", 12, PR_TRUE, 7 },
+          { "abcdefgabcdefg", "cd", 12, PR_TRUE, 9 },
+          { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 },
+          { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 },
+          { "abcdabcabcdabc", "bc", 12, PR_TRUE, 8 },
+          { "abcdabcabcdabc", "bc", 13, PR_TRUE, 8 },
+          { "abcdabcabcdabc", "bc", 14, PR_TRUE, 12 },
+          { "abcdefgabcdefg", "abcdefg", 13, PR_TRUE, 0 },
+          { "abcdefgabcdefg", "abcdefg", 14, PR_TRUE, 7 },
+          { "abcdefgabcdefg", "abcdefg", 15, PR_TRUE, 7 },
+          { "ABCDEFG", "a", 5, PR_TRUE, 0 },
+          { "ABCDEFG", "c", 5, PR_TRUE, 2 },
+          { "ABCDEFG", "e", 5, PR_TRUE, 4 },
+          { "ABCDEFG", "g", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "i", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "ab", 5, PR_TRUE, 0 },
+          { "ABCDEFG", "cd", 5, PR_TRUE, 2 },
+          { "ABCDEFG", "ef", 5, PR_FALSE, 0 },
+          { "ABCDEFG", "gh", 5, PR_FALSE, 0 },
+          { "ABCDABC", "bc", 5, PR_TRUE, 1 },
+          { "ABCDABC", "bc", 6, PR_TRUE, 1 },
+          { "ABCDABC", "bc", 7, PR_TRUE, 5 },
+          { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+          { "ABCDEFG", "abcdefg", 7, PR_TRUE, 0 },
+          { "ABCDEFG", "abcdefg", 8, PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "a", 12, PR_TRUE, 7 },
+          { "ABCDEFGABCDEFG", "c", 12, PR_TRUE, 9 },
+          { "ABCDEFGABCDEFG", "e", 12, PR_TRUE, 11 },
+          { "ABCDEFGABCDEFG", "g", 12, PR_TRUE, 6 },
+          { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 },
+          { "ABCDEFGABCDEFG", "ab", 12, PR_TRUE, 7 },
+          { "ABCDEFGABCDEFG", "cd", 12, PR_TRUE, 9 },
+          { "ABCDEFGABCDEFG", "ef", 12, PR_TRUE, 4 },
+          { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 },
+          { "ABCDABCABCDABC", "bc", 12, PR_TRUE, 8 },
+          { "ABCDABCABCDABC", "bc", 13, PR_TRUE, 8 },
+          { "ABCDABCABCDABC", "bc", 14, PR_TRUE, 12 },
+          { "ABCDEFGABCDEFG", "abcdefg", 13, PR_TRUE, 0 },
+          { "ABCDEFGABCDEFG", "abcdefg", 14, PR_TRUE, 7 },
+          { "ABCDEFGABCDEFG", "abcdefg", 15, PR_TRUE, 7 }
+      };
+
+    int i;
+
+    printf("Test 030 (PL_strncaserstr)..."); fflush(stdout);
+
+    for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+    {
+        char *rv = PL_strncaserstr(array[i].str, array[i].sub, array[i].max);
+
+        if( PR_FALSE == array[i].ret )
+        {
+            if( (char *)0 != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, rv);
+                return PR_FALSE;
+            }
+        }
+        else
+        {
+            if( (char *)0 == rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i,
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+
+            if( &array[i].str[ array[i].off ] != rv )
+            {
+                printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, 
+                       array[i].str ? array[i].str : "(null)",
+                       array[i].sub ? array[i].sub : "(null)",
+                       array[i].max, rv, array[i].str, array[i].off);
+                return PR_FALSE;
+            }
+        }
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+/* PL_strtok_r */
+PRBool test_031(void)
+{
+    static const char *tokens[] = {
+        "wtc", "relyea", "nelsonb", "jpierre", "nicolson",
+        "ian.mcgreer", "kirk.erickson", "sonja.mirtitsch", "mhein"
+    };
+
+    static const char *seps[] = {
+        ", ", ",", " ", "\t", ",,,", " ,", "    ", " \t\t", ","
+    };
+
+    static const char s2[] = ", \t";
+
+    char string[ 1024 ];
+    char *s1;
+    char *token;
+    char *lasts;
+    unsigned int i;
+
+    printf("Test 031 (PL_strtok_r)    ..."); fflush(stdout);
+
+    /* Build the string. */
+    string[0] = '\0';
+    for( i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++ )
+    {
+        PL_strcat(string, tokens[i]);
+        PL_strcat(string, seps[i]);
+    }
+    
+    /* Scan the string for tokens. */
+    i = 0;
+    s1 = string;
+    while( (token = PL_strtok_r(s1, s2, &lasts)) != NULL)
+    {
+        if( PL_strcmp(token, tokens[i]) != 0 )
+        {
+            printf("FAIL wrong token scanned\n");
+            return PR_FALSE;
+        }
+        i++;
+        s1 = NULL;
+    }
+    if( i != sizeof(tokens)/sizeof(tokens[0]) )
+    {
+        printf("FAIL wrong number of tokens scanned\n");
+        return PR_FALSE;
+    }
+
+    printf("PASS\n");
+    return PR_TRUE;
+}
+
+int
+main
+(
+    int     argc,
+    char   *argv[]
+)
+{
+    printf("Testing the Portable Library string functions:\n");
+
+    if( 1
+        && test_001()
+        && test_001()
+        && test_002()
+        && test_003()
+        && test_004()
+        && test_005()
+        && test_006()
+        && test_007()
+        && test_008()
+        && test_009()
+        && test_010()
+        && test_011()
+        && test_012()
+        && test_013()
+        && test_014()
+        && test_015()
+        && test_016()
+        && test_017()
+        && test_018()
+        && test_019()
+        && test_020()
+        && test_021()
+        && test_022()
+        && test_023()
+        && test_024()
+        && test_025()
+        && test_026()
+        && test_027()
+        && test_028()
+        && test_029()
+        && test_030()
+        && test_031()
+      )
+    {
+        printf("Suite passed.\n");
+        return 0;
+    }
+    else
+    {
+        printf("Suite failed.\n");
+        return 1;
+    }
+
+    /*NOTREACHED*/
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pkg/Makefile.in
new file mode 100644
index 0000000..d181bf6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/Makefile.in
@@ -0,0 +1,61 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+DIRS = 
+ifeq ($(OS_TARGET),Linux)
+DIRS = linux
+endif
+ifeq ($(OS_TARGET),SunOS)
+DIRS = solaris
+endif
+
+publish::
+	+$(LOOP_OVER_DIRS)
+
+include $(topsrcdir)/config/rules.mk
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/linux/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pkg/linux/Makefile.in
new file mode 100644
index 0000000..401f492
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/linux/Makefile.in
@@ -0,0 +1,112 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: Makefile.in,v 1.11 2008/10/20 22:38:45 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MOD_DEPTH = ../..
+topsrcdir   = @top_srcdir@
+srcdir	    = @srcdir@
+VPATH	    = @srcdir@
+
+NAME        = sun-nspr
+ifndef RPM_RELEASE
+RPM_RELEASE = 1
+endif
+TOPDIR      = /usr/src/redhat
+VERSION     = `grep PR_VERSION $(dist_includedir)/prinit.h \
+                  | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'`
+
+SPECFILE    = $(NAME).spec
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+# Force i386 for non 64 bit build
+ifneq ($(USE_64),1)
+	RPMTARGET = "--target=i386"
+	RPMLIBDIR = lib
+else
+	RPMLIBDIR = lib64
+endif
+
+publish:
+	$(MAKE) clean
+	mkdir -p SOURCES SRPMS RPMS BUILD
+	(cd $(dist_libdir) && tar cphf - libnspr4.so libplds4.so libplc4.so) \
+	| (mkdir -p opt/sun/private/$(RPMLIBDIR) && cd opt/sun/private/$(RPMLIBDIR) && tar xvfBp -)
+	(cd $(dist_includedir) && tar cphf - .) \
+	| (mkdir -p opt/sun/private/include/nspr && cd opt/sun/private/include/nspr && tar xvfBp -)
+	(cd opt/sun/private/include/nspr && \
+		rm -rf md)
+	tar czvf SOURCES/$(NAME)-$(VERSION).tar.gz opt
+	echo "%define name $(NAME)" >$(SPECFILE)
+	echo "%define version $(VERSION)" >>$(SPECFILE)
+	echo "%define release $(RPM_RELEASE)" >>$(SPECFILE)
+	echo "%define buildroot `pwd`/$(NAME)-root" >>$(SPECFILE)
+	echo "%define _topdir `pwd`" >>$(SPECFILE)
+	echo "%define _unpackaged_files_terminate_build 0" >>$(SPECFILE)
+	cat $(srcdir)/$(NAME).spec >>$(SPECFILE)
+	echo "" >>$(SPECFILE)
+	echo "%files" >>$(SPECFILE)
+	echo "%defattr(-,root,root)" >>$(SPECFILE)
+	echo "%dir /opt" >>$(SPECFILE)
+	echo "%dir /opt/sun" >>$(SPECFILE)
+	echo "%dir /opt/sun/private" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/$(RPMLIBDIR)" >>$(SPECFILE)
+	find opt \( -name "*.so" \) | sed -e "s-^-/-" >>$(SPECFILE)
+	echo "" >>$(SPECFILE)
+	echo "%files devel" >>$(SPECFILE)
+	echo "%defattr(-,root,root)" >>$(SPECFILE)
+	echo "%dir /opt" >>$(SPECFILE)
+	echo "%dir /opt/sun" >>$(SPECFILE)
+	echo "%dir /opt/sun/private" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/include" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/include/nspr" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/include/nspr/obsolete" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/include/nspr/private" >>$(SPECFILE)
+	find opt -type f \( -name "*.h" \) \
+		| sed -e "s-^-/-" >>$(SPECFILE)
+	rpmbuild $(RPMTARGET) -bb $(SPECFILE)
+
+clean:
+	rm -rf $(TOPDIR)/BUILD/$(NAME)
+	rm -rf SOURCES SRPMS RPMS BUILD
+	rm -rf RPMS SRPMS opt
+	rm -f $(NAME)-$(VERSION).tar.gz
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/linux/sun-nspr.spec b/nspr-4.8.6/mozilla/nsprpub/pkg/linux/sun-nspr.spec
new file mode 100644
index 0000000..f914736
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/linux/sun-nspr.spec
@@ -0,0 +1,81 @@
+Summary: Netscape Portable Runtime
+Name: %{name}
+Vendor: Sun Microsystems, Inc.
+Version: %{version}
+Release: %{release}
+Copyright: Copyright 2005 Sun Microsystems, Inc.  All rights reserved.  Use is subject to license terms.  Also under other license(s) as shown at the Description field.
+Distribution: Sun Java(TM) Enterprise System
+URL: http://www.sun.com
+Group: System Environment/Base
+Source: %{name}-%{version}.tar.gz
+ExclusiveOS: Linux
+BuildRoot: /var/tmp/%{name}-root
+        
+%description
+
+NSPR provides platform independence for non-GUI operating system
+facilities. These facilities include threads, thread synchronization,
+normal file and network I/O, interval timing and calendar time, basic
+memory management (malloc and free) and shared library linking. 
+
+See: http://www.mozilla.org/projects/nspr/about-nspr.html
+
+***** BEGIN LICENSE BLOCK *****
+Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+The contents of this file are subject to the Mozilla Public License Version
+1.1 (the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the Netscape security libraries.
+
+The Initial Developer of the Original Code is
+Netscape Communications Corporation.
+Portions created by the Initial Developer are Copyright (C) 1994-2000
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+
+***** END LICENSE BLOCK *****
+
+%package devel
+Summary: Development Libraries for the Netscape Portable Runtime
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Header files for doing development with the Netscape Portable Runtime.
+
+Under "MPL/GPL" license.
+
+%prep
+%setup -c
+
+%build
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir $RPM_BUILD_ROOT
+cd $RPM_BUILD_ROOT
+tar xvzf $RPM_SOURCE_DIR/%{name}-%{version}.tar.gz
+
+%clean
+rm -rf $RPM_BUILD_ROOT
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile-devl.com b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile-devl.com
new file mode 100755
index 0000000..fa47f5b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile-devl.com
@@ -0,0 +1,66 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: Makefile-devl.com,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MACH = $(shell mach)
+
+PUBLISH_ROOT = $(DIST)
+ifeq ($(MOD_DEPTH),../..)
+ROOT = ROOT
+else
+ROOT = $(subst ../../,,$(MOD_DEPTH))/ROOT
+endif
+
+PKGARCHIVE = $(dist_prefix)/pkgarchive
+DATAFILES = copyright
+FILES = $(DATAFILES) pkginfo
+
+PACKAGE = $(shell basename `pwd`)
+
+PRODUCT_VERSION = "$(MOD_VERSION).$(MOD_MINOR).$(MOD_PATCH)$(MOD_BETA)"
+LN = /usr/bin/ln
+
+CLOBBERFILES = $(FILES)
+
+include $(topsrcdir)/config/rules.mk
+
+# vim: ft=make
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile-devl.targ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile-devl.targ
new file mode 100755
index 0000000..da52e3a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile-devl.targ
@@ -0,0 +1,66 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: Makefile-devl.targ,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+include $(srcdir)/../proto64.mk
+
+pkginfo: pkginfo.tmpl ../awk_pkginfo
+	$(RM) $@; nawk -f ../awk_pkginfo $(srcdir)/$@.tmpl > $@
+
+pkg: $(PKGARCHIVE)
+	cat $(srcdir)/prototype | sed $(sed_proto64) > prototype
+	cp $(srcdir)/depend .
+	pkgmk -f prototype -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE)
+
+$(PKGARCHIVE):
+	[ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE)
+
+$(DATAFILES): %: $(srcdir)/../common_files/%
+	$(RM) $@; cp $(srcdir)/../common_files/$@ $@
+
+$(MACHDATAFILES): %: $(srcdir)/../common_files/%_$(MACH)
+	$(RM) $@; cp $(srcdir)/../common_files/$@_$(MACH) $@
+
+clobber clean::
+	-$(RM) $(CLOBBERFILES) $(CLEANFILES)
+
+.PHONY: pkg
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.com b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.com
new file mode 100644
index 0000000..32640ab
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.com
@@ -0,0 +1,69 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: Makefile.com,v 1.8 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MACH = $(shell mach)
+
+PUBLISH_ROOT = $(DIST)
+ifeq ($(MOD_DEPTH),../..)
+ROOT = ROOT
+else
+ROOT = $(subst ../../,,$(MOD_DEPTH))/ROOT
+endif
+
+PKGARCHIVE = $(dist_prefix)/pkgarchive
+DATAFILES = copyright
+FILES = $(DATAFILES) pkginfo
+
+PACKAGE = $(shell basename `pwd`)
+
+PRODUCT_VERSION = $(shell grep PR_VERSION $(dist_includedir)/prinit.h \
+		   | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//')
+
+LN = /usr/bin/ln
+CP = /usr/bin/cp
+
+CLOBBERFILES = $(FILES)
+
+include $(topsrcdir)/config/rules.mk
+
+# vim: ft=make
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.in
new file mode 100644
index 0000000..1fa7258
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.in
@@ -0,0 +1,121 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: Makefile.in,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MOD_DEPTH = ../..
+topsrcdir   = @top_srcdir@
+srcdir	    = @srcdir@
+VPATH	    = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+abs_dist_libdir := $(shell (cd $(dist_libdir);pwd))
+abs_dist_includedir := $(shell (cd $(dist_includedir);pwd))
+
+%: %.ksh
+	$(RM) $@
+	cp $< $@
+	chmod +x $@
+
+DIRS = \
+	SUNWpr \
+	SUNWprd
+
+include $(srcdir)/Makefile.com
+
+PROTO = \
+	$(ROOT) \
+	$(ROOT)/usr/lib/mps \
+	$(ROOT)/usr/include/mps
+
+ifeq ($(MACH), sparc)
+	PROTO += $(ROOT)/usr/lib/mps/cpu/sparcv8plus
+endif
+
+ifeq ($(USE_64), 1)
+ifeq ($(MACH), sparc)
+# Sparc
+	PROTO += $(ROOT)/usr/lib/mps/sparcv9
+else
+# AMD64
+	PROTO += $(ROOT)/usr/lib/mps/amd64
+endif
+	abs_dist64_libdir = $(abs_dist_libdir)
+	abs_dist32_libdir = $(shell echo $(abs_dist_libdir) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g")
+	abs_dist64_includedir = $(abs_dist_includedir)
+	abs_dist32_includedir = $(shell echo $(abs_dist_includedir) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g")
+else
+	abs_dist32_libdir = $(abs_dist_libdir)
+	abs_dist64_libdir = $(shell echo $(abs_dist_libdir) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g")
+	abs_dist32_includedir = $(abs_dist_includedir)
+	abs_dist64_includedir = $(shell echo $(abs_dist_includedir) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g")
+endif
+
+awk_pkginfo: bld_awk_pkginfo
+	./bld_awk_pkginfo -m $(MACH) -p "$(PRODUCT_VERSION)" -o $@ -v $(PRODUCT_VERSION)
+
+all:: awk_pkginfo $(PROTO)
+publish: awk_pkginfo $(PROTO)
+	+$(LOOP_OVER_DIRS)
+
+clean clobber::
+	$(RM) awk_pkginfo bld_awk_pkginfo
+	$(RM) -r $(ROOT)
+
+$(ROOT):
+	mkdir -p $@
+
+$(ROOT)/usr/lib/mps/sparcv9:
+	mkdir -p $@
+	$(CP) -r $(abs_dist64_libdir)/*.so $@
+$(ROOT)/usr/lib/mps/amd64:
+	mkdir -p $@
+	$(CP) -r $(abs_dist64_libdir)/*.so $@
+$(ROOT)/usr/lib/mps:
+	mkdir -p $@
+	$(CP) -r $(abs_dist32_libdir)/*.so $@
+$(ROOT)/usr/lib/mps/cpu/sparcv8plus:
+	mkdir -p $@
+	$(CP) -r $(abs_dist32_libdir)/cpu/sparcv8plus/*.so $@
+$(ROOT)/usr/include/mps:
+	mkdir -p $@
+	$(CP) -r $(abs_dist32_includedir)/* $@
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.targ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.targ
new file mode 100644
index 0000000..ca17a80
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/Makefile.targ
@@ -0,0 +1,64 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: Makefile.targ,v 1.6 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+include $(srcdir)/../proto64.mk
+
+pkginfo: pkginfo.tmpl ../awk_pkginfo
+	$(RM) $@; nawk -f ../awk_pkginfo $< > $@
+
+pkg: $(PKGARCHIVE) prototype_$(MACH)
+	cp $(srcdir)/prototype_com .
+	cat $(srcdir)/prototype_$(MACH) | sed $(sed_proto64) > prototype_$(MACH)
+	cp $(srcdir)/depend .
+	pkgmk -f prototype_$(MACH) -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE)
+
+$(PKGARCHIVE):
+	[ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE)
+
+$(DATAFILES): %: $(srcdir)/../common_files/%
+	$(RM) $@; cp $(srcdir)/../common_files/$@ $@
+
+clobber clean::
+	-$(RM) $(CLOBBERFILES) $(CLEANFILES)
+
+.PHONY: pkg
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/Makefile.in
new file mode 100644
index 0000000..3cd5669
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/Makefile.in
@@ -0,0 +1,58 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: Makefile.in,v 1.2 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MOD_DEPTH = ../../..
+topsrcdir   = @top_srcdir@
+srcdir	    = @srcdir@
+VPATH	    = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(srcdir)/../Makefile.com
+
+DATAFILES += 
+
+all:: $(FILES)
+publish:: all pkg
+
+include $(srcdir)/../Makefile.targ
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/depend b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/depend
new file mode 100644
index 0000000..f5b1b70
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/depend
@@ -0,0 +1,64 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#	$Id: depend,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $
+#
+# This package information file defines software dependencies associated
+# with the pkg.  You can define three types of pkg dependencies with this file:
+#	 P indicates a prerequisite for installation
+#	 I indicates an incompatible package
+#	 R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# 	(<arch>)<version>
+# 	(<arch>)<version>
+# 	...
+# <type> <pkg.abbr> <name>
+# ...
+
+P SUNWcar	Core Architecture, (Root)
+P SUNWkvm	Core Architecture, (Kvm)
+P SUNWcsr	Core Solaris, (Root)
+P SUNWcsu	Core Solaris, (Usr)
+P SUNWcsd	Core Solaris Devices
+P SUNWcsl	Core Solaris Libraries
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl
new file mode 100644
index 0000000..9652051
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl
@@ -0,0 +1,70 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: pkginfo.tmpl,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWpr"
+NAME="Netscape Portable Runtime"
+ARCH="ISA"
+VERSION="NSPRVERS,REV=0.0.0"
+SUNW_PRODNAME="Netscape Portable Runtime"
+SUNW_PRODVERS="NSPRVERS"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Netscape Portable Runtime Interface"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_com b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_com
new file mode 100644
index 0000000..881fdb5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_com
@@ -0,0 +1,71 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: prototype_com,v 1.4 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>	# where to find pkg objects
+#!include <filename>			# include another 'prototype' file
+#!default <mode> <owner> <group>	# default used if not specified on entry
+#!<param>=<value>			# puts parameter in pkg environment
+
+# packaging files
+i copyright
+i pkginfo
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWpr
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+d none usr/lib/mps 755 root bin
+d none usr/lib/mps/secv1 755 root bin
+f none usr/lib/mps/libnspr4.so 755 root bin
+f none usr/lib/mps/libplc4.so 755 root bin
+f none usr/lib/mps/libplds4.so 755 root bin
+s none usr/lib/mps/secv1/libnspr4.so=../libnspr4.so
+s none usr/lib/mps/secv1/libplc4.so=../libplc4.so
+s none usr/lib/mps/secv1/libplds4.so=../libplds4.so
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_i386 b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_i386
new file mode 100644
index 0000000..9cbb7ed
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_i386
@@ -0,0 +1,77 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: prototype_i386,v 1.4 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>	# where to find pkg objects
+#!include <filename>			# include another 'prototype' file
+#!default <mode> <owner> <group>	# default used if not specified on entry
+#!<param>=<value>			# puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are i386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpr
+#
+#64#s none usr/lib/mps/64=amd64
+#64#s none usr/lib/mps/secv1/64=amd64
+#64#d none usr/lib/mps/amd64 755 root bin
+#64#d none usr/lib/mps/secv1/amd64 755 root bin
+#64#f none usr/lib/mps/amd64/libnspr4.so 755 root bin
+#64#f none usr/lib/mps/amd64/libplc4.so 755 root bin
+#64#f none usr/lib/mps/amd64/libplds4.so 755 root bin
+#64#s none usr/lib/mps/secv1/amd64/libnspr4.so=../../amd64/libnspr4.so
+#64#s none usr/lib/mps/secv1/amd64/libplc4.so=../../amd64/libplc4.so
+#64#s none usr/lib/mps/secv1/amd64/libplds4.so=../../amd64/libplds4.so
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_sparc b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_sparc
new file mode 100644
index 0000000..c141e6c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_sparc
@@ -0,0 +1,83 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: prototype_sparc,v 1.4 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>	# where to find pkg objects
+#!include <filename>			# include another 'prototype' file
+#!default <mode> <owner> <group>	# default used if not specified on entry
+#!<param>=<value>			# puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpr
+#
+d none usr/lib/mps/cpu 755 root bin
+d none usr/lib/mps/cpu/sparcv8plus 755 root bin
+d none usr/lib/mps/secv1/cpu 755 root bin
+d none usr/lib/mps/secv1/cpu/sparcv8plus 755 root bin
+f none usr/lib/mps/cpu/sparcv8plus/libnspr_flt4.so 755 root bin
+s none usr/lib/mps/secv1/cpu/sparcv8plus/libnspr_flt4.so=../../../cpu/sparcv8plus/libnspr_flt4.so
+#64#s none usr/lib/mps/64=sparcv9
+#64#s none usr/lib/mps/secv1/64=sparcv9
+#64#d none usr/lib/mps/sparcv9 755 root bin
+#64#d none usr/lib/mps/secv1/sparcv9 755 root bin
+#64#f none usr/lib/mps/sparcv9/libnspr4.so 755 root bin
+#64#f none usr/lib/mps/sparcv9/libplc4.so 755 root bin
+#64#f none usr/lib/mps/sparcv9/libplds4.so 755 root bin
+#64#s none usr/lib/mps/secv1/sparcv9/libnspr4.so=../../sparcv9/libnspr4.so
+#64#s none usr/lib/mps/secv1/sparcv9/libplc4.so=../../sparcv9/libplc4.so
+#64#s none usr/lib/mps/secv1/sparcv9/libplds4.so=../../sparcv9/libplds4.so
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/Makefile.in
new file mode 100755
index 0000000..3c6d059
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/Makefile.in
@@ -0,0 +1,58 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: Makefile.in,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MOD_DEPTH = ../../..
+topsrcdir   = @top_srcdir@
+srcdir      = @srcdir@
+VPATH       = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(srcdir)/../Makefile-devl.com
+
+DATAFILES += 
+
+all:: $(FILES)
+publish:: all pkg
+
+include $(srcdir)/../Makefile-devl.targ
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/depend b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/depend
new file mode 100755
index 0000000..fee5a2a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/depend
@@ -0,0 +1,59 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#	$Id: depend,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $
+#
+# This package information file defines software dependencies associated
+# with the pkg.  You can define three types of pkg dependencies with this file:
+#	 P indicates a prerequisite for installation
+#	 I indicates an incompatible package
+#	 R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# 	(<arch>)<version>
+# 	(<arch>)<version>
+# 	...
+# <type> <pkg.abbr> <name>
+# ...
+
+P SUNWpr	Netscape Portable Runtime
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl
new file mode 100755
index 0000000..6eea9fe
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl
@@ -0,0 +1,70 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: pkginfo.tmpl,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWprd"
+NAME="Netscape Portable Runtime Development"
+ARCH="ISA"
+VERSION="NSPRVERS,REV=0.0.0"
+SUNW_PRODNAME="Netscape Portable Runtime Development"
+SUNW_PRODVERS="NSPRVERS"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Netscape Portable Runtime Interface Files for Development"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/prototype b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/prototype
new file mode 100755
index 0000000..c823497
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/SUNWprd/prototype
@@ -0,0 +1,121 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident  "$Id: prototype,v 1.6 2010/01/27 22:20:40 wtc%google.com Exp $"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>        # where to find pkg objects
+#!include <filename>                    # include another 'prototype' file
+#!default <mode> <owner> <group>        # default used if not specified on entry
+#!<param>=<value>                       # puts parameter in pkg environment
+
+# packaging files
+i copyright
+i pkginfo
+i depend
+#
+# source locations relative to .h 0644 root bine prototype file
+#
+# SUNWprd
+#
+d none usr 0755 root sys
+d none usr/include 0755 root bin
+d none usr/include/mps 0755 root bin
+d none usr/include/mps/obsolete 0755 root bin
+d none usr/include/mps/private 0755 root bin
+f none usr/include/mps/obsolete/pralarm.h 0644 root bin
+f none usr/include/mps/obsolete/probslet.h 0644 root bin
+f none usr/include/mps/obsolete/protypes.h 0644 root bin
+f none usr/include/mps/obsolete/prsem.h 0644 root bin
+f none usr/include/mps/prcpucfg.h 0644 root bin
+f none usr/include/mps/nspr.h 0644 root bin
+f none usr/include/mps/pratom.h 0644 root bin
+f none usr/include/mps/prbit.h 0644 root bin
+f none usr/include/mps/prclist.h 0644 root bin
+f none usr/include/mps/prcmon.h 0644 root bin
+f none usr/include/mps/prcountr.h 0644 root bin
+f none usr/include/mps/prcvar.h 0644 root bin
+f none usr/include/mps/prdtoa.h 0644 root bin
+f none usr/include/mps/prenv.h 0644 root bin
+f none usr/include/mps/prerr.h 0644 root bin
+f none usr/include/mps/prerror.h 0644 root bin
+f none usr/include/mps/prinet.h 0644 root bin
+f none usr/include/mps/prinit.h 0644 root bin
+f none usr/include/mps/prinrval.h 0644 root bin
+f none usr/include/mps/prio.h 0644 root bin
+f none usr/include/mps/pripcsem.h 0644 root bin
+f none usr/include/mps/private/pprio.h 0644 root bin
+f none usr/include/mps/private/pprthred.h 0644 root bin
+f none usr/include/mps/private/prpriv.h 0644 root bin
+f none usr/include/mps/prlink.h 0644 root bin
+f none usr/include/mps/prlock.h 0644 root bin
+f none usr/include/mps/prlog.h 0644 root bin
+f none usr/include/mps/prlong.h 0644 root bin
+f none usr/include/mps/prmem.h 0644 root bin
+f none usr/include/mps/prmon.h 0644 root bin
+f none usr/include/mps/prmwait.h 0644 root bin
+f none usr/include/mps/prnetdb.h 0644 root bin
+f none usr/include/mps/prolock.h 0644 root bin
+f none usr/include/mps/prpdce.h 0644 root bin
+f none usr/include/mps/prprf.h 0644 root bin
+f none usr/include/mps/prproces.h 0644 root bin
+f none usr/include/mps/prrng.h 0644 root bin
+f none usr/include/mps/prrwlock.h 0644 root bin
+f none usr/include/mps/prshm.h 0644 root bin
+f none usr/include/mps/prshma.h 0644 root bin
+f none usr/include/mps/prsystem.h 0644 root bin
+f none usr/include/mps/prthread.h 0644 root bin
+f none usr/include/mps/prtime.h 0644 root bin
+f none usr/include/mps/prtpool.h 0644 root bin
+f none usr/include/mps/prtrace.h 0644 root bin
+f none usr/include/mps/prtypes.h 0644 root bin
+f none usr/include/mps/prvrsion.h 0644 root bin
+f none usr/include/mps/prwin16.h 0644 root bin
+f none usr/include/mps/plarenas.h 0644 root bin
+f none usr/include/mps/plarena.h 0644 root bin
+f none usr/include/mps/plbase64.h 0644 root bin
+f none usr/include/mps/plerror.h 0644 root bin
+f none usr/include/mps/plgetopt.h 0644 root bin
+f none usr/include/mps/plhash.h 0644 root bin
+f none usr/include/mps/plstr.h 0644 root bin
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh
new file mode 100644
index 0000000..11063c8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh
@@ -0,0 +1,141 @@
+#!/usr/bin/ksh -p
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident	"$Id: bld_awk_pkginfo.ksh,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# Simple script which builds the awk_pkginfo awk script.  This awk script
+# is used to convert the pkginfo.tmpl files into pkginfo files
+# for the build.
+#
+
+usage()
+{
+   cat <<-EOF
+usage: bld_awk_pkginfo -p <prodver> -m <mach> -o <awk_script> [-v <version>]
+EOF
+}
+
+#
+# Awk strings
+#
+# two VERSION patterns: one for Dewey decimal, one for Dewey plus ,REV=n
+# the first has one '=' the second has two or more '='
+#
+VERSION1="VERSION=[^=]*$"
+VERSION2="VERSION=[^=]*=.*$"
+PRODVERS="^SUNW_PRODVERS="
+ARCH='ARCH=\"ISA\"'
+
+#
+# parse command line
+#
+mach=""
+prodver=""
+awk_script=""
+version="NSPRVERS"
+
+while getopts o:p:m:v: c
+do
+   case $c in
+   o)
+      awk_script=$OPTARG
+      ;;
+   m)
+      mach=$OPTARG
+      ;;
+   p)
+      prodver=$OPTARG
+      ;;
+   v)
+      version=$OPTARG
+      ;;
+   \?)
+      usage
+      exit 1
+      ;;
+   esac
+done
+
+if [[ ( -z $prodver ) || ( -z $mach ) || ( -z $awk_script ) ]]
+then
+   usage
+   exit 1
+fi
+
+if [[ -f $awk_script ]]
+then
+	rm -f $awk_script
+fi
+
+#
+# Build REV= field based on date
+#
+rev=$(date "+%Y.%m.%d.%H.%M")
+
+#
+# Build awk script which will process all the
+# pkginfo.tmpl files.
+#
+# the first VERSION pattern is replaced with a leading quotation mark
+#
+rm -f $awk_script
+cat << EOF > $awk_script
+/$VERSION1/ {
+      sub(/\=[^=]*$/,"=\"$rev\"")
+      print
+      next
+   }
+/$VERSION2/ {
+      sub(/\=[^=]*$/,"=$rev\"")
+      sub(/NSPRVERS/,"$version")
+      print
+      next
+   }
+/$PRODVERS/ { 
+      printf "SUNW_PRODVERS=\"%s\"\n", "$prodver" 
+      next
+   }
+/$ARCH/ {
+      printf "ARCH=\"%s\"\n", "$mach"
+      next
+   }
+{ print }
+EOF
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/common_files/copyright b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/common_files/copyright
new file mode 100644
index 0000000..988939b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/common_files/copyright
@@ -0,0 +1,38 @@
+Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+Use is subject to license terms.
+
+***** BEGIN LICENSE BLOCK *****
+Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+The contents of this package are subject to the Mozilla Public License Version
+1.1 (the "License"); you may not use this package except in compliance with
+the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the Netscape Portable Runtime (NSPR).
+
+The Initial Developer of the Original Code is
+Netscape Communications Corporation.
+Portions created by the Initial Developer are Copyright (C) 1998-2000
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+
+***** END LICENSE BLOCK *****
diff --git a/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/proto64.mk b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/proto64.mk
new file mode 100644
index 0000000..c14dc09
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pkg/solaris/proto64.mk
@@ -0,0 +1,50 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+#ident  "$Id: proto64.mk,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+ifeq ($(USE_64), 1)
+  # Remove 64 tag
+  sed_proto64='s/\#64\#//g'
+else
+  # Strip 64 lines
+  sed_proto64='/\#64\#/d'
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/Makefile.in
new file mode 100644
index 0000000..e060f19
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/Makefile.in
@@ -0,0 +1,49 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+DIRS = include src
+
+include $(topsrcdir)/config/rules.mk
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/include/Makefile.in
new file mode 100644
index 0000000..5dc9686
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/Makefile.in
@@ -0,0 +1,59 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+DIRS = md private obsolete
+
+include $(topsrcdir)/config/config.mk
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(RELEASE_HEADERS)
+	$(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/gencfg.c b/nspr-4.8.6/mozilla/nsprpub/pr/include/gencfg.c
new file mode 100644
index 0000000..e67c130
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/gencfg.c
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+
+#if defined(sgi)
+#ifndef IRIX
+	error - IRIX is not defined
+#endif
+#endif
+
+#if defined(__sun)
+#if defined(__svr4) || defined(__svr4__) || defined(__SVR4)
+#ifndef SOLARIS
+	error - SOLARIS is not defined
+#endif
+#else
+#ifndef SUNOS4
+	error - SUNOS4 is not defined
+#endif
+#endif
+#endif
+
+#if defined(__hpux)
+#ifndef HPUX
+	error - HPUX is not defined
+#endif
+#endif
+
+#if defined(__alpha) 
+#if !(defined(_WIN32)) && !(defined(OSF1)) && !(defined(__linux)) && !(defined(__FreeBSD__))
+	error - None of OSF1, _WIN32, __linux, or __FreeBSD__ is defined
+#endif
+#endif
+
+#if defined(_IBMR2)
+#ifndef AIX
+	error - AIX is not defined
+#endif
+#endif
+
+#if defined(linux)
+#ifndef LINUX
+	error - LINUX is not defined
+#endif
+#endif
+
+#if defined(bsdi)
+#ifndef BSDI
+	error - BSDI is not defined
+#endif
+#endif
+
+#if defined(M_UNIX)
+#ifndef SCO
+      error - SCO is not defined
+#endif
+#endif
+#if !defined(M_UNIX) && defined(_USLC_)
+#ifndef UNIXWARE
+      error - UNIXWARE is not defined
+#endif
+#endif
+
+#if defined(__APPLE__)
+#ifndef DARWIN
+      error - DARWIN is not defined
+#endif
+#endif
+
+#if defined(__NeXT__)
+#ifndef NEXTSTEP
+      error - NEXTSTEP is not defined
+#endif
+#endif
+
+/************************************************************************/
+
+/* Generate cpucfg.h */
+
+#ifdef XP_PC
+#ifdef WIN32
+#define INT64	_PRInt64
+#else
+#define INT64	long
+#endif
+#else
+#if defined(HPUX) || defined(NECSVR4) || defined(SCO) || defined(UNIXWARE) || defined (NCR)
+#define INT64	long
+#else
+#define INT64	long long
+#endif
+#endif
+
+struct align_short {
+    char c;
+    short a;
+};
+struct align_int {
+    char c;
+    int a;
+};
+struct align_long {
+    char c;
+    long a;
+};
+struct align_PRInt64 {
+    char c;
+    INT64 a;
+};
+struct align_fakelonglong {
+    char c;
+    struct {
+	long hi, lo;
+    } a;
+};
+struct align_float {
+    char c;
+    float a;
+};
+struct align_double {
+    char c;
+    double a;
+};
+struct align_pointer {
+    char c;
+    void *a;
+};
+
+#define ALIGN_OF(type) \
+    (((char*)&(((struct align_##type *)0)->a)) - ((char*)0))
+
+int bpb;
+
+/* Used if shell doesn't support redirection. By default, assume it does. */
+FILE *stream;
+
+static int Log2(int n)
+{
+    int log2 = 0;
+
+    if (n & (n-1))
+	log2++;
+    if (n >> 16)
+	log2 += 16, n >>= 16;
+    if (n >> 8)
+	log2 += 8, n >>= 8;
+    if (n >> 4)
+	log2 += 4, n >>= 4;
+    if (n >> 2)
+	log2 += 2, n >>= 2;
+    if (n >> 1)
+	log2++;
+    return log2;
+}
+
+/* We assume that int's are 32 bits */
+static void do64(void)
+{
+    union {
+	int i;
+	char c[4];
+    } u;
+
+    u.i = 0x01020304;
+    if (u.c[0] == 0x01) {
+	fprintf(stream, "#undef  IS_LITTLE_ENDIAN\n");
+	fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n");
+    } else {
+	fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n");
+	fprintf(stream, "#undef  IS_BIG_ENDIAN\n\n");
+    }
+}
+
+static void do32(void)
+{
+    union {
+	long i;
+	char c[4];
+    } u;
+
+    u.i = 0x01020304;
+    if (u.c[0] == 0x01) {
+	fprintf(stream, "#undef  IS_LITTLE_ENDIAN\n");
+	fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n");
+    } else {
+	fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n");
+	fprintf(stream, "#undef  IS_BIG_ENDIAN\n\n");
+    }
+}
+
+/*
+** Concievably this could actually be used; but there is lots of code out
+** there with and's and shift's in it that assumes a byte is 8 bits, so
+** forget about porting THIS code to those non 8 bit byte machines.
+*/
+static void BitsPerByte(void)
+{
+    bpb = 8;
+}
+
+int main(int argc, char **argv)
+{
+    BitsPerByte();
+
+    /* If we got a command line argument, try to use it as the stream. */
+    ++argv;
+    if(*argv) {
+        if(!(stream = fopen ( *argv, "wt" ))) {
+            fprintf(stderr, "Could not write to output file %s.\n", *argv);
+            return 1;
+        }
+    } else {
+		stream = stdout;
+	}
+
+    fprintf(stream, "#ifndef nspr_cpucfg___\n");
+    fprintf(stream, "#define nspr_cpucfg___\n\n");
+
+    fprintf(stream, "/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n");
+
+    if (sizeof(long) == 8) {
+	do64();
+    } else {
+	do32();
+    }
+    fprintf(stream, "#define PR_BYTES_PER_BYTE   %d\n", sizeof(char));
+    fprintf(stream, "#define PR_BYTES_PER_SHORT  %d\n", sizeof(short));
+    fprintf(stream, "#define PR_BYTES_PER_INT    %d\n", sizeof(int));
+    fprintf(stream, "#define PR_BYTES_PER_INT64  %d\n", 8);
+    fprintf(stream, "#define PR_BYTES_PER_LONG   %d\n", sizeof(long));
+    fprintf(stream, "#define PR_BYTES_PER_FLOAT  %d\n", sizeof(float));
+    fprintf(stream, "#define PR_BYTES_PER_DOUBLE %d\n\n", sizeof(double));
+
+    fprintf(stream, "#define PR_BITS_PER_BYTE    %d\n", bpb);
+    fprintf(stream, "#define PR_BITS_PER_SHORT   %d\n", bpb * sizeof(short));
+    fprintf(stream, "#define PR_BITS_PER_INT     %d\n", bpb * sizeof(int));
+    fprintf(stream, "#define PR_BITS_PER_INT64   %d\n", bpb * 8);
+    fprintf(stream, "#define PR_BITS_PER_LONG    %d\n", bpb * sizeof(long));
+    fprintf(stream, "#define PR_BITS_PER_FLOAT   %d\n", bpb * sizeof(float));
+    fprintf(stream, "#define PR_BITS_PER_DOUBLE  %d\n\n", 
+            bpb * sizeof(double));
+
+    fprintf(stream, "#define PR_BITS_PER_BYTE_LOG2   %d\n", Log2(bpb));
+    fprintf(stream, "#define PR_BITS_PER_SHORT_LOG2  %d\n", 
+            Log2(bpb * sizeof(short)));
+    fprintf(stream, "#define PR_BITS_PER_INT_LOG2    %d\n", 
+            Log2(bpb * sizeof(int)));
+    fprintf(stream, "#define PR_BITS_PER_INT64_LOG2  %d\n", 6);
+    fprintf(stream, "#define PR_BITS_PER_LONG_LOG2   %d\n", 
+            Log2(bpb * sizeof(long)));
+    fprintf(stream, "#define PR_BITS_PER_FLOAT_LOG2  %d\n", 
+            Log2(bpb * sizeof(float)));
+    fprintf(stream, "#define PR_BITS_PER_DOUBLE_LOG2 %d\n\n", 
+            Log2(bpb * sizeof(double)));
+
+    fprintf(stream, "#define PR_ALIGN_OF_SHORT   %d\n", ALIGN_OF(short));
+    fprintf(stream, "#define PR_ALIGN_OF_INT     %d\n", ALIGN_OF(int));
+    fprintf(stream, "#define PR_ALIGN_OF_LONG    %d\n", ALIGN_OF(long));
+    if (sizeof(INT64) < 8) {
+	/* this machine doesn't actually support PRInt64's */
+	fprintf(stream, "#define PR_ALIGN_OF_INT64   %d\n", 
+                ALIGN_OF(fakelonglong));
+    } else {
+	fprintf(stream, "#define PR_ALIGN_OF_INT64   %d\n", ALIGN_OF(PRInt64));
+    }
+    fprintf(stream, "#define PR_ALIGN_OF_FLOAT   %d\n", ALIGN_OF(float));
+    fprintf(stream, "#define PR_ALIGN_OF_DOUBLE  %d\n", ALIGN_OF(double));
+    fprintf(stream, "#define PR_ALIGN_OF_POINTER %d\n\n", ALIGN_OF(pointer));
+
+    fprintf(stream, "#endif /* nspr_cpucfg___ */\n");
+    fclose(stream);
+
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/Makefile.in
new file mode 100644
index 0000000..af369be
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/Makefile.in
@@ -0,0 +1,74 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+# The .cfg files need to be exported and installed to support
+# cross-compilation.
+CONFIGS = $(wildcard $(srcdir)/*.cfg)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(MDCPUCFG_H)
+	$(INSTALL) -m 444 $(CONFIGS) $(dist_includedir)/md
+	$(INSTALL) -m 444 $(srcdir)/$(MDCPUCFG_H) $(dist_includedir)
+	mv -f $(dist_includedir)/$(MDCPUCFG_H) $(dist_includedir)/prcpucfg.h
+
+install::
+	$(NSINSTALL) -D $(DESTDIR)$(includedir)/md
+	$(NSINSTALL) -t -m 644 $(CONFIGS) $(DESTDIR)$(includedir)/md
+	$(NSINSTALL) -t -m 644 $(srcdir)/$(MDCPUCFG_H) $(DESTDIR)$(includedir)
+	mv -f $(DESTDIR)$(includedir)/$(MDCPUCFG_H) $(DESTDIR)$(includedir)/prcpucfg.h
+
+release:: export
+	@echo "Copying machine-dependent prcpucfg.h"
+	@if test -z "$(BUILD_NUMBER)"; then \
+		echo "BUILD_NUMBER must be defined"; \
+		false; \
+	fi
+	@if test ! -d $(RELEASE_INCLUDE_DIR); then \
+		rm -rf $(RELEASE_INCLUDE_DIR); \
+		$(NSINSTALL) -D $(RELEASE_INCLUDE_DIR);\
+	fi
+	cp $(srcdir)/$(MDCPUCFG_H) $(RELEASE_INCLUDE_DIR)/prcpucfg.h
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix.h
new file mode 100644
index 0000000..4d313a7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix.h
@@ -0,0 +1,256 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_aix_defs_h___
+#define nspr_aix_defs_h___
+
+#include <sys/types.h>
+#if defined(_PR_PTHREADS) || defined(PTHREADS_USER)
+#include <pthread.h>
+#endif
+
+/*
+ * To pick up fd_set and the poll events.
+ */
+#include <sys/select.h>
+#include <sys/poll.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH          "aix"
+#define _PR_SI_SYSNAME		    "AIX"
+#define _PR_SI_ARCHITECTURE	    "rs6000"
+#define PR_DLL_SUFFIX		    ".so"
+
+#define _PR_VMBASE	 	        0x30000000
+#define _PR_STACK_VMBASE	    0x50000000
+#define _MD_DEFAULT_STACK_SIZE	(2*65536L)
+#define _MD_MINIMUM_STACK_SIZE	(2*65536L)
+#define _MD_MMAP_FLAGS		    MAP_PRIVATE
+
+#define NEED_TIME_R
+#undef  HAVE_STACK_GROWING_UP
+#undef	HAVE_WEAK_IO_SYMBOLS
+#undef	HAVE_WEAK_MALLOC_SYMBOLS
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#ifdef _AIX51 /* AIX 4.3.3 does not have AI_NUMERICHOST. */
+#define _PR_HAVE_GETADDRINFO
+#endif
+#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
+
+#else  /* defined(AIX_TIMERS) */
+#define _MD_GET_INTERVAL        _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC    _PR_UNIX_TicksPerSecond
+#endif  /* defined(AIX_TIMERS) */
+
+#ifdef AIX_HAVE_ATOMIC_OP_H
+/* The atomic operations */
+#include <sys/atomic_op.h>
+#define _PR_HAVE_ATOMIC_OPS
+#ifndef IS_64
+#define _PR_HAVE_ATOMIC_CAS
+#endif
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(val)   ((PRInt32)fetch_and_add((atomic_p)val, 1) + 1)
+#define _MD_ATOMIC_ADD(ptr, val)   ((PRInt32)fetch_and_add((atomic_p)ptr, val) + val)
+#define _MD_ATOMIC_DECREMENT(val)   ((PRInt32)fetch_and_add((atomic_p)val, -1) - 1)
+#define _MD_ATOMIC_SET(val, newval) _AIX_AtomicSet(val, newval)
+#endif /* AIX_HAVE_ATOMIC_OP_H */
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _MD_GET_SP(_t)				(_t)->md.jb[3]
+#define _MD_SET_THR_SP(_t, _sp)		((_t)->md.jb[3] = (int) (_sp - 2 * 64))
+#define PR_NUM_GCREGS				_JBLEN
+
+#define CONTEXT(_th) 				((_th)->md.jb)
+#define SAVE_CONTEXT(_th)			_setjmp(CONTEXT(_th))
+#define GOTO_CONTEXT(_th)			_longjmp(CONTEXT(_th), 1)
+
+#ifdef PTHREADS_USER
+#include "_nspr_pthread.h"
+#else
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+    PR_BEGIN_MACRO				      \
+        *status = PR_TRUE;              \
+	if (setjmp(CONTEXT(_thread))) {	\
+	    (*_main)();			\
+	}				\
+	_MD_GET_SP(_thread) = (int) (_sp - 2 * 64);		\
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode; \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    longjmp(CONTEXT(_thread), 1); \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    jmp_buf jb;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#if !defined(_PR_PTHREADS)
+#define _MD_INIT_LOCKS()
+#endif
+
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_EARLY_INIT          	_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+#endif /* PTHREADS_USER */
+
+#ifdef AIX_RENAME_SELECT
+#define _MD_SELECT	select
+#define _MD_POLL	poll
+#endif
+
+extern void _MD_aix_map_sendfile_error(int err);
+
+#endif /* nspr_aix_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix32.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix32.cfg
new file mode 100644
index 0000000..6b75e4f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix32.cfg
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef AIX
+#define AIX
+#endif
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2	5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#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
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+/* used by protypes.h only */
+#define _PR_AIX_HAVE_BSD_INT_TYPES
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix64.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix64.cfg
new file mode 100644
index 0000000..8b500ab
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_aix64.cfg
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef AIX
+#define AIX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2	6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 8
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#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
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+/* used by protypes.h only */
+#define _PR_AIX_HAVE_BSD_INT_TYPES
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_beos.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_beos.cfg
new file mode 100644
index 0000000..557252f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_beos.cfg
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_BEOS
+#define XP_BEOS
+#undef XP_UNIX
+#endif
+
+#ifndef BEOS
+#define BEOS
+#endif
+
+#define PR_AF_INET6 5  /* same as AF_INET6 */
+
+#ifdef __powerpc__
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#else
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#endif
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+/*
+ * XXX These two macros need to be investigated for different architectures.
+ */
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_beos.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_beos.h
new file mode 100644
index 0000000..5eb220d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_beos.h
@@ -0,0 +1,615 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_beos_defs_h___
+#define nspr_beos_defs_h___
+
+#include "prtypes.h"
+#include "prio.h"
+#include "prthread.h"
+#include "prproces.h"
+#include "prmem.h"
+#include "obsolete/prsem.h"
+#include <errno.h>
+
+#include <support/SupportDefs.h>
+#include <kernel/OS.h>
+#include <dirent.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#ifdef BONE_VERSION
+#define _PR_HAVE_SOCKADDR_LEN
+#define HAVE_NETINET_TCP_H
+#endif
+
+#define PR_LINKER_ARCH	"beos"
+#define _PR_SI_SYSNAME  "BEOS"
+#ifdef __powerpc__
+#define _PR_SI_ARCHITECTURE "ppc"
+#else
+#define _PR_SI_ARCHITECTURE "x86"
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef	HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define _PR_NO_CLOCK_TIMER
+
+/*
+ * The Atomic operations
+ */
+
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC _MD_AtomicInit
+#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement
+#define _MD_ATOMIC_ADD _MD_AtomicAdd
+#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement
+#define _MD_ATOMIC_SET _MD_AtomicSet
+
+#define HAVE_CVAR_BUILT_ON_SEM
+#define _PR_GLOBAL_THREADS_ONLY
+#define _PR_BTHREADS
+#define _PR_NEED_FAKE_POLL
+#define _PR_HAVE_PEEK_BUFFER
+#define _PR_PEEK_BUFFER_MAX (16 * 1024)
+#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) 1
+#define _PR_CONNECT_DOES_NOT_BIND
+#define _PR_HAVE_O_APPEND
+
+/* Define threading functions and objects as native BeOS */
+struct _MDThread {
+    thread_id	tid;	/* BeOS thread handle */
+	sem_id		joinSem;	/* sems used to synchronzie joining */
+	PRBool	is_joining;	/* TRUE if someone is currently waiting to
+						   join this thread */
+};
+
+struct _MDThreadStack {
+    PRInt8	notused;
+};
+
+/*
+ * Lock and Semaphore related definitions
+ */
+
+struct _MDLock {
+    sem_id semaphoreID;
+    int32  benaphoreCount;
+};
+
+struct _MDCVar {
+    sem_id sem1;
+    sem_id sem2;
+    int16  count;
+};
+
+struct _MDSemaphore {
+    sem_id sid;
+};
+
+/*
+** CPU-related definitions
+*/
+struct _MDCPU {
+    int8		unused;
+};
+
+/*
+** Process-related definitions
+*/
+struct _MDProcess {
+    pid_t pid;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** File- and directory-related definitions
+*/
+
+#ifndef BONE_VERSION
+#define BE_SOCK_SHUTDOWN_READ	0x01
+#define BE_SOCK_SHUTDOWN_WRITE	0x02
+#endif
+
+struct _MDFileDesc {
+    PRInt32	osfd;
+    PRInt32	sock_state;
+    PRBool	accepted_socket;
+    PRNetAddr	peer_addr;
+#ifndef BONE_VERSION
+    PRBool	connectValueValid;
+    int		connectReturnValue;
+    int		connectReturnError;
+#endif
+};
+
+struct _MDDir {
+    DIR		*d;
+};
+
+#define PR_DIRECTORY_SEPARATOR		'/'
+#define PR_DIRECTORY_SEPARATOR_STR	"/"
+#define PR_PATH_SEPARATOR		':'
+#define PR_PATH_SEPARATOR_STR		":"
+
+#define GETTIMEOFDAY(tp)	gettimeofday((tp), NULL)
+
+/* --- Memory-mapped files stuff --- not implemented on BeOS */
+
+struct _MDFileMap {
+    PRInt8 unused;
+};
+
+/*
+ * Network related definitions.
+ */
+
+#ifndef BONE_VERSION
+#define IPPROTO_IP 0
+#define AF_UNIX 2
+#define TCP_NODELAY SO_NONBLOCK
+#define SO_LINGER -1
+#define SO_ERROR 4
+#endif
+
+#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
+
+#ifndef BONE_VERSION
+/* these aren't actually used. if they are, we're screwed */
+struct  protoent {
+    char    *p_name;        /* official protocol name */
+    char    **p_aliases;    /* alias list */
+    int     p_proto;        /* protocol # */
+};
+
+struct protoent* getprotobyname(const char* name);
+struct protoent* getprotobynumber(int number);
+#endif
+
+/*
+ * malloc() related definitions.
+ */
+
+#undef _PR_OVERRIDE_MALLOC
+
+/* Miscellaneous */
+
+#define _MD_ERRNO()             (errno)
+
+#define _MD_CLEANUP_BEFORE_EXIT _MD_cleanup_before_exit
+#define _MD_EXIT _MD_exit
+
+#define _MD_GET_ENV getenv
+#define _MD_PUT_ENV putenv
+
+#define _MD_EARLY_INIT _MD_early_init
+#define _MD_FINAL_INIT _MD_final_init
+#define _MD_EARLY_CLEANUP()
+
+/* CPU Stuff */
+
+#define _MD_INIT_CPUS _MD_init_cpus
+#define _MD_WAKEUP_CPUS _MD_wakeup_cpus
+#define _MD_START_INTERRUPTS _MD_start_interrupts
+#define _MD_STOP_INTERRUPTS _MD_stop_interrupts
+#define _MD_DISABLE_CLOCK_INTERRUPTS _MD_disable_clock_interrupts
+#define _MD_BLOCK_CLOCK_INTERRUPTS _MD_block_clock_interrupts
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS _MD_unblock_clock_interrupts
+#define _MD_CLOCK_INTERRUPT _MD_clock_interrupt
+#define _MD_INIT_STACK _MD_init_stack
+#define _MD_CLEAR_STACK _MD_clear_stack
+// #define _MD_GET_INTSOFF _MD_get_intsoff
+// #define _MD_SET_INTSOFF _MD_set_intsoff
+#define _MD_CURRENT_CPU _MD_current_cpu
+#define _MD_SET_CURRENT_CPU _MD_set_current_cpu
+#define _MD_INIT_RUNNING_CPU _MD_init_running_cpu
+#define _MD_PAUSE_CPU _MD_pause_cpu
+
+/* Thread stuff */
+
+#define _MD_CURRENT_THREAD() PR_GetCurrentThread()
+// #define _MD_GET_ATTACHED_THREAD _MD_get_attached_thread
+#define _MD_LAST_THREAD _MD_last_thread
+#define _MD_SET_CURRENT_THREAD _MD_set_current_THREAD
+#define _MD_SET_LAST_THREAD _MD_set_last_thread
+#define _MD_INIT_THREAD _MD_init_thread
+#define _MD_EXIT_THREAD _MD_exit_thread
+#define _MD_INIT_ATTACHED_THREAD _MD_init_attached_thread
+
+#define _MD_SUSPEND_THREAD _MD_suspend_thread
+#define _MD_RESUME_THREAD _MD_resume_thread
+#define _MD_SUSPEND_CPU _MD_suspend_cpu
+#define _MD_RESUME_CPU _MD_resume_cpu
+#define _MD_BEGIN_SUSPEND_ALL _MD_begin_suspend_all
+#define _MD_END_SUSPEND_ALL _MD_end_suspend_all
+#define _MD_BEGIN_RESUME_ALL _MD_begin_resume_all
+#define _MD_END_RESUME_ALL _MD_end_resume_all
+
+#define _MD_GET_SP _MD_get_sp
+
+#define _MD_CLEAN_THREAD _MD_clean_thread
+#define _MD_CREATE_PRIMORDIAL_USER_THREAD _MD_create_primordial_user_thread
+#define _MD_CREATE_USER_THREAD _MD_create_user_thread
+#define _MD_INIT_PRIMORDIAL_THREAD _MD_init_primordial_thread
+#define _MD_CREATE_THREAD _MD_create_thread
+#define _MD_YIELD _MD_yield
+#define _MD_SET_PRIORITY _MD_set_priority
+
+#define _MD_SUSPENDALL _MD_suspendall
+#define _MD_RESUMEALL _MD_resumeall
+
+#define _MD_SWITCH_CONTEXT _MD_switch_context
+#define _MD_RESTORE_CONTEXT _MD_restore_context
+
+#define _MD_WAIT _MD_wait
+#define _MD_WAKEUP_WAITER _MD_wakeup_waiter
+
+#define _MD_SETTHREADAFFINITYMASK _MD_setthreadaffinitymask
+#define _MD_GETTHREADAFFINITYMASK _MD_getthreadaffinitymask
+
+/* Thread Synchronization */
+
+#define _MD_INIT_LOCKS _MD_init_locks
+#define _MD_NEW_LOCK _MD_new_lock
+#define _MD_FREE_LOCK _MD_free_lock
+#define _MD_LOCK _MD_lock
+#define _MD_TEST_AND_LOCK _MD_test_and_lock
+#define _MD_UNLOCK _MD_unlock
+#define _MD_IOQ_LOCK _MD_ioq_lock
+#define _MD_IOQ_UNLOCK _MD_ioq_unlock
+#define _MD_NEW_SEM _MD_new_sem
+#define _MD_DESTROY_SEM _MD_destroy_sem
+#define _MD_TIMED_WAIT_SEM _MD_timed_wait_sem
+#define _MD_WAIT_SEM _MD_wait_sem
+#define _MD_POST_SEM _MD_post_sem
+// #define _MD_NEW_CV _MD_new_cv
+// #define _MD_FREE_CV _MD_free_cv
+// #define _MD_WAIT_CV _MD_wait_cv
+// #define _MD_NOTIFY_CV _MD_notify_cv
+// #define _MD_NOTIFYALL_CV _MD_notifyall_cv
+
+/* File I/O */
+
+/* don't need any I/O initializations */
+#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_SET_FD_INHERITABLE _MD_set_fd_inheritable
+#define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable
+#define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable
+#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
+#define _MD_BIND _MD_bind
+#define _MD_LISTEN _MD_listen
+#define _MD_SHUTDOWN _MD_shutdown
+#define _MD_RECV _MD_recv
+#define _MD_SEND _MD_send
+#define _MD_ACCEPT_READ _MD_accept_read
+#define _MD_GETSOCKNAME _MD_getsockname
+#define _MD_GETPEERNAME _MD_getpeername
+#define _MD_GETSOCKOPT _MD_getsockopt
+#define _MD_SETSOCKOPT _MD_setsockopt
+#define _MD_RECVFROM _MD_recvfrom
+#define _MD_SENDTO _MD_sendto
+#define _MD_SOCKETPAIR _MD_socketpair
+#define _MD_SOCKET _MD_socket
+#define _MD_SOCKETAVAILABLE _MD_socketavailable
+#define _MD_PIPEAVAILABLE _MD_socketavailable
+
+#define _MD_GET_SOCKET_ERROR()	(errno)
+#define _MD_GETHOSTNAME _MD_gethostname
+
+#define _MD_SELECT select
+
+/* Process management */
+
+#define _MD_CREATE_PROCESS _MD_create_process
+#define _MD_DETACH_PROCESS _MD_detach_process
+#define _MD_WAIT_PROCESS _MD_wait_process
+#define _MD_KILL_PROCESS _MD_kill_process
+
+/* Atomic data operations */
+
+// #define _MD_INIT_ATOMIC _MD_init_atomic
+// #define _MD_ATOMIC_INCREMENT _MD_atomic_increment
+// #define _MD_ATOMIC_DECREMENT _MD_atomic_decrement
+// #define _MD_ATOMIC_SET _MD_atomic_set
+
+/* memory management */
+
+#define _MD_INIT_SEGS _MD_init_segs
+#define _MD_ALLOC_SEGMENT _MD_alloc_segment
+#define _MD_FREE_SEGMENT _MD_free_segment
+
+/* Memory mapped file I/O */
+
+#define _MD_CREATE_FILE_MAP _MD_create_file_map
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_get_mem_map_alignment
+#define _MD_MEM_MAP _MD_mem_map
+#define _MD_MEM_UNMAP _MD_mem_unmap
+#define _MD_CLOSE_FILE_MAP _MD_close_file_map
+
+/* Time related */
+
+#define _MD_NOW _MD_now
+#define _MD_INTERVAL_INIT _MD_interval_init
+#define _MD_GET_INTERVAL _MD_get_interval
+#define _MD_INTERVAL_PER_SEC _MD_interval_per_sec
+
+/* File locking */
+
+#define _MD_LOCKFILE _MD_lockfile
+#define _MD_TLOCKFILE _MD_tlockfile
+#define _MD_UNLOCKFILE _MD_unlockfile
+
+/**
+ * Prototypes for machine dependent function implementations. (Too bad
+ * NSPR's MD system blows so much that we have to reiterate every stinking
+ * thing we implement here in our MD header file.)
+ */
+
+/* Miscellaneous */
+
+NSPR_API(void) _MD_cleanup_before_exit(void);
+NSPR_API(void) _MD_exit(PRIntn status);
+
+NSPR_API(char*) _MD_get_env(const char *name);
+NSPR_API(PRIntn) _MD_put_env(const char *name);
+
+NSPR_API(void) _MD_early_init(void);
+NSPR_API(void) _MD_final_init(void);
+
+/* CPU Stuff */
+
+NSPR_API(void) _MD_init_cpus();
+NSPR_API(void) _MD_wakeup_cpus();
+NSPR_API(void) _MD_start_interrupts(void);
+NSPR_API(void) _MD_stop_interrupts(void);
+NSPR_API(void) _MD_disable_clock_interrupts(void);
+NSPR_API(void) _MD_block_clock_interrupts(void);
+NSPR_API(void) _MD_unblock_clock_interrupts(void);
+NSPR_API(void) _MD_clock_interrupt(void);
+// NSPR_API(void) _MD_init_stack(PRThreadStack *ts, PRIntn redzone);
+// NSPR_API(void) _MD_clear_stack(PRThreadStack* ts);
+// NSPR_API(PRInt32) _MD_get_intsoff(void);
+// NSPR_API(void) _MD_set_intsoff(PRInt32 _val);
+// NSPR_API(_PRCPU*) _MD_current_cpu(void);
+// NSPR_API(void) _MD_set_current_cpu(_PRCPU *cpu);
+// NSPR_API(void) _MD_init_running_cpu(_PRCPU *cpu);
+NSPR_API(PRInt32) _MD_pause_cpu(PRIntervalTime timeout);
+
+/* Thread stuff */
+
+// NSPR_API(PRThread*) _MD_current_thread(void);
+NSPR_API(PRThread*) _MD_get_attached_thread(void);
+NSPR_API(PRThread*) _MD_last_thread(void);
+NSPR_API(void) _MD_set_current_thread(PRThread *thread);
+NSPR_API(void) _MD_set_last_thread(PRThread *thread);
+NSPR_API(PRStatus) _MD_init_thread(PRThread *thread);
+NSPR_API(void) _MD_exit_thread(PRThread *thread);
+NSPR_API(PRStatus) _MD_init_attached_thread(PRThread *thread);
+
+NSPR_API(void) _MD_suspend_thread(PRThread *thread);
+NSPR_API(void) _MD_resume_thread(PRThread *thread);
+// NSPR_API(void) _MD_suspend_cpu(_PRCPU  *cpu);
+// NSPR_API(void) _MD_resume_cpu(_PRCPU  *cpu);
+NSPR_API(void) _MD_begin_suspend_all(void);
+NSPR_API(void) _MD_end_suspend_all(void);
+NSPR_API(void) _MD_begin_resume_all(void);
+NSPR_API(void) _MD_end_resume_all(void);
+
+NSPR_API(void *) _MD_get_sp(PRThread *thread);
+
+NSPR_API(void) _MD_clean_thread(PRThread *thread);
+NSPR_API(void) _MD_create_primordial_user_thread(PRThread *);
+NSPR_API(PRThread*) _MD_create_user_thread(PRUint32 stacksize, void (*start)(void *), void *arg);
+NSPR_API(void) _MD_init_primordial_thread(PRThread *thread);
+NSPR_API(PRStatus) _MD_create_thread(PRThread *thread, void (*start)(void *), PRThreadPriority priority, PRThreadScope scope, PRThreadState state, PRUint32 stackSize);
+NSPR_API(void) _MD_yield(void);
+NSPR_API(void) _MD_set_priority(struct _MDThread *md, PRThreadPriority newPri);
+
+NSPR_API(void) _MD_suspendall(void);
+NSPR_API(void) _MD_resumeall(void);
+
+NSPR_API(void) _MD_init_context(PRThread *thread, char *top, void (*start) (void), PRBool *status);
+NSPR_API(void) _MD_switch_context(PRThread *thread);
+NSPR_API(void) _MD_restore_context(PRThread *thread);
+
+NSPR_API(PRStatus) _MD_wait(PRThread *, PRIntervalTime timeout);
+NSPR_API(PRStatus) _MD_wakeup_waiter(PRThread *);
+
+NSPR_API(PRInt32) _MD_setthreadaffinitymask(PRThread *thread, PRUint32 mask );
+NSPR_API(PRInt32) _MD_getthreadaffinitymask(PRThread *thread, PRUint32 *mask);
+
+/* Thread Synchronization */
+
+NSPR_API(void) _MD_init_locks(void);
+NSPR_API(PRStatus) _MD_new_lock(struct _MDLock *md);
+NSPR_API(void) _MD_free_lock(struct _MDLock *md);
+NSPR_API(void) _MD_lock(struct _MDLock *md);
+NSPR_API(PRIntn) _MD_test_and_lock(struct _MDLock *md);
+NSPR_API(void) _MD_unlock(struct _MDLock *md);
+NSPR_API(void) _MD_ioq_lock(void);
+NSPR_API(void) _MD_ioq_unlock(void);
+NSPR_API(void) _MD_new_sem(struct _MDSemaphore *md, PRUintn value);
+NSPR_API(void) _MD_destroy_sem(struct _MDSemaphore *md);
+NSPR_API(PRStatus) _MD_timed_wait_sem(struct _MDSemaphore *md, PRIntervalTime timeout);
+NSPR_API(PRStatus) _MD_wait_sem(struct _MDSemaphore *md);
+NSPR_API(void) _MD_post_sem(struct _MDSemaphore *md);
+// NSPR_API(PRInt32) _MD_new_cv(struct _MDCVar *md);
+// NSPR_API(void) _MD_free_cv(struct _MDCVar *md);
+// NSPR_API(void) _MD_wait_cv(struct _MDCVar *mdCVar, struct _MDLock *mdLock, PRIntervalTime timeout);
+// NSPR_API(void) _MD_notify_cv(struct _MDCVar *md, struct _MDLock *lock);
+// NSPR_API(void) _MD_notifyall_cv(struct _MDCVar *md, struct _MDLock *lock);
+
+/* File I/O */
+
+// NSPR_API(void) _MD_init_io(void);
+NSPR_API(PRStatus) _MD_open_dir(struct _MDDir *md,const char *name);
+NSPR_API(char *) _MD_read_dir(struct _MDDir *md, PRIntn flags);
+NSPR_API(PRInt32) _MD_close_dir(struct _MDDir *md);
+NSPR_API(void) _MD_make_nonblock(PRFileDesc *fd);
+NSPR_API(void) _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported);
+NSPR_API(void) _MD_query_fd_inheritable(PRFileDesc *fd);
+NSPR_API(PRInt32) _MD_open(const char *name, PRIntn osflags, PRIntn mode);
+NSPR_API(PRInt32) _MD_close_file(PRInt32 osfd);
+NSPR_API(PRInt32) _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount);
+NSPR_API(PRInt32) _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
+NSPR_API(PRInt32) _MD_writev(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_lseek(PRFileDesc *fd, PRInt32 offset, int whence);
+NSPR_API(PRInt64) _MD_lseek64(PRFileDesc *fd, PRInt64 offset, int whence);
+NSPR_API(PRInt32) _MD_fsync(PRFileDesc *fd);
+NSPR_API(PRInt32) _MD_delete(const char *name);
+NSPR_API(PRInt32) _MD_getfileinfo(const char *fn, PRFileInfo *info);
+NSPR_API(PRInt32) _MD_getfileinfo64(const char *fn, PRFileInfo64 *info);
+NSPR_API(PRInt32) _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info);
+NSPR_API(PRInt32) _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info);
+NSPR_API(PRInt32) _MD_rename(const char *from, const char *to);
+NSPR_API(PRInt32) _MD_access(const char *name, PRIntn how);
+NSPR_API(PRInt32) _MD_stat(const char *name, struct stat *buf);
+NSPR_API(PRInt32) _MD_mkdir(const char *name, PRIntn mode);
+NSPR_API(PRInt32) _MD_rmdir(const char *name);
+NSPR_API(PRInt32) _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout);
+
+/* Network I/O */
+NSPR_API(PRInt32) _MD_close_socket(PRInt32 osfd);
+NSPR_API(PRInt32) _MD_connect(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
+NSPR_API(PRInt32) _MD_listen(PRFileDesc *fd, PRIntn backlog);
+NSPR_API(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how);
+NSPR_API(PRInt32) _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_accept_read(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout);
+// NSPR_API(PRInt32) _MD_fast_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout, PRBool fast, _PR_AcceptTimeoutCallback callback, void *callbackArg);
+// NSPR_API(PRInt32) _MD_fast_accept_read(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout, PRBool fast, _PR_AcceptTimeoutCallback callback, void *callbackArg);
+// NSPR_API(void) _MD_update_accept_context(PRInt32 s, PRInt32 ls);
+NSPR_API(PRStatus) _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
+NSPR_API(PRStatus) _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
+NSPR_API(PRStatus) _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
+NSPR_API(PRStatus) _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen);
+NSPR_API(PRInt32) _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_socketpair(int af, int type, int flags, PRInt32 *osfd);
+NSPR_API(PRInt32) _MD_socket(int af, int type, int flags);
+NSPR_API(PRInt32) _MD_socketavailable(PRFileDesc *fd);
+
+// NSPR_API(PRInt32) _MD_get_socket_error(void);
+NSPR_API(PRStatus) _MD_gethostname(char *name, PRUint32 namelen);
+
+/* Process management */
+
+NSPR_API(PRProcess *) _MD_create_process(const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr);
+NSPR_API(PRStatus) _MD_detach_process(PRProcess *process);
+NSPR_API(PRStatus) _MD_wait_process(PRProcess *process, PRInt32 *exitCode);
+NSPR_API(PRStatus) _MD_kill_process(PRProcess *process);
+
+/* Atomic data operations */
+
+// NSPR_API(void) _MD_init_atomic(void);
+// NSPR_API(PRInt32) _MD_atomic_increment(PRInt32 *);
+// NSPR_API(PRInt32) _MD_atomic_decrement(PRInt32 *);
+// NSPR_API(PRInt32) _MD_atomic_set(PRInt32 *, PRInt32);
+
+/* Memory management */
+
+NSPR_API(void) _MD_init_segs(void);
+NSPR_API(PRStatus) _MD_alloc_segment(PRSegment *seg, PRUint32 size, void *vaddr);
+NSPR_API(void) _MD_free_segment(PRSegment *seg);
+
+/* Memory mapped file I/O */
+
+NSPR_API(PRStatus) _MD_create_file_map(PRFileMap *fmap, PRInt64 size);
+NSPR_API(PRInt32) _MD_get_mem_map_alignment(void);
+NSPR_API(void *) _MD_mem_map(PRFileMap *fmap, PRInt64 offset, PRUint32 len);
+NSPR_API(PRStatus) _MD_mem_unmap(void *addr, PRUint32 size);
+NSPR_API(PRStatus) _MD_close_file_map(PRFileMap *fmap);
+
+/* Time related */
+
+NSPR_API(PRTime) _MD_now(void);
+NSPR_API(void) _MD_interval_init(void);
+NSPR_API(PRIntervalTime) _MD_get_interval(void);
+NSPR_API(PRIntervalTime) _MD_interval_per_sec(void);
+
+/* File locking */
+
+NSPR_API(PRStatus) _MD_lockfile(PRInt32 osfd);
+NSPR_API(PRStatus) _MD_tlockfile(PRInt32 osfd);
+NSPR_API(PRStatus) _MD_unlockfile(PRInt32 osfd);
+
+#endif /* _nspr_beos_defs_h___*/
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_bsdi.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_bsdi.cfg
new file mode 100644
index 0000000..eb933c1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_bsdi.cfg
@@ -0,0 +1,202 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef BSDI
+#define BSDI
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#if defined(__i386__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__sparc__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_bsdi.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_bsdi.h
new file mode 100644
index 0000000..b59c9b0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_bsdi.h
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_bsdi_defs_h___
+#define nspr_bsdi_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#include <sys/param.h>	/* for _BSDI_VERSION */
+
+#define PR_LINKER_ARCH	"bsdi"
+#define _PR_SI_SYSNAME "BSDI"
+#if defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#else
+#error "Unknown CPU architecture"
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define HAVE_BSD_FLOCK
+#define NEED_TIME_R
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_NO_LARGE_FILES
+
+#define USE_SETJMP
+
+/* BSD/OS 4.3 and newer all have IPv6 support */
+#if _BSDI_VERSION >= 200105
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#endif
+
+#ifndef _PR_PTHREADS
+
+#include <setjmp.h>
+
+#if defined(_PR_BSDI_JMPBUF_IS_ARRAY)
+#define _MD_GET_SP(_t)    (_t)->md.context[2] 
+#elif defined(_PR_BSDI_JMPBUF_IS_STRUCT)
+#define _MD_GET_SP(_t)    (_t)->md.context[0].jb_esp
+#else
+#error "Unknown BSDI jmp_buf type"
+#endif
+
+#define PR_NUM_GCREGS	_JBLEN
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	  \
+{								  \
+    *status = PR_TRUE; \
+    if (setjmp(CONTEXT(_thread))) {				  \
+	_main();					  \
+    }								  \
+    _MD_GET_SP(_thread) = (int) (_sp - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    longjmp(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+#endif /* ! _PR_PTHREADS */
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+
+#include <sys/syscall.h>
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#endif /* nspr_bsdi_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_darwin.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_darwin.cfg
new file mode 100644
index 0000000..60bea8e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_darwin.cfg
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#define PR_AF_INET6 30  /* same as AF_INET6 */
+
+#ifdef __LITTLE_ENDIAN__
+#undef IS_BIG_ENDIAN
+#define  IS_LITTLE_ENDIAN 1
+#else
+#undef IS_LITTLE_ENDIAN
+#define  IS_BIG_ENDIAN 1
+#endif
+
+#ifdef __x86_64__
+#define IS_64
+#endif
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#ifdef IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+#define PR_BITS_PER_DWORD   64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+#define PR_BITS_PER_DWORD_LOG2  6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+#define PR_ALIGN_OF_DWORD   8
+
+#else /* IS_64 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+#define PR_BITS_PER_DWORD   64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#endif /* IS_64 */
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_darwin.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_darwin.h
new file mode 100644
index 0000000..fc37798
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_darwin.h
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_darwin_defs_h___
+#define nspr_darwin_defs_h___
+
+#include "prthread.h"
+
+#include <sys/syscall.h>
+
+#ifdef XP_MACOSX
+#include <AvailabilityMacros.h>
+#endif
+
+#define PR_LINKER_ARCH	"darwin"
+#define _PR_SI_SYSNAME  "DARWIN"
+#ifdef __i386__
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__x86_64__)
+#define _PR_SI_ARCHITECTURE "x86-64"
+#elif defined(__ppc__)
+#define _PR_SI_ARCHITECTURE "ppc"
+#endif
+#define PR_DLL_SUFFIX		".dylib"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#ifdef __x86_64__
+#define USE_DLFCN
+#else
+#define USE_MACH_DYLD
+#endif
+#define _PR_HAVE_SOCKADDR_LEN  
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_HAVE_LARGE_OFF_T
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#define _PR_INET6
+/*
+ * I'd prefer to use getipnodebyname and getipnodebyaddr but the
+ * getipnodebyname(3) man page on Mac OS X 10.2 says they are not
+ * thread-safe.  AI_V4MAPPED|AI_ADDRCONFIG doesn't work either.
+ */
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+/*
+ * On Mac OS X 10.2, gethostbyaddr fails with h_errno=NO_RECOVERY
+ * if you pass an IPv4-mapped IPv6 address to it.
+ */
+#define _PR_GHBA_DISALLOW_V4MAPPED
+#ifdef XP_MACOSX
+#if !defined(MAC_OS_X_VERSION_10_3) || \
+    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
+/*
+ * socket(AF_INET6) fails with EPROTONOSUPPORT on Mac OS X 10.1.
+ * IPv6 under OS X 10.2 and below is not complete (see bug 222031).
+ */
+#define _PR_INET6_PROBE
+#endif /* DT < 10.3 */
+#if defined(MAC_OS_X_VERSION_10_2) && \
+    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_2
+/* Mac OS X 10.2 has inet_ntop and inet_pton. */
+#define _PR_HAVE_INET_NTOP
+#endif /* DT >= 10.2 */
+#endif /* XP_MACOSX */
+#define _PR_IPV6_V6ONLY_PROBE
+/* The IPV6_V6ONLY socket option is not defined on Mac OS X 10.1. */
+#ifndef IPV6_V6ONLY
+#define IPV6_V6ONLY 27
+#endif
+
+#ifdef __ppc__
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_DarwinPPC_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT(val)   _PR_DarwinPPC_AtomicIncrement(val)
+extern PRInt32 _PR_DarwinPPC_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT(val)   _PR_DarwinPPC_AtomicDecrement(val)
+extern PRInt32 _PR_DarwinPPC_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET(val, newval) _PR_DarwinPPC_AtomicSet(val, newval)
+extern PRInt32 _PR_DarwinPPC_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD(ptr, val)    _PR_DarwinPPC_AtomicAdd(ptr, val)
+#endif /* __ppc__ */
+
+#ifdef __i386__
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_Darwin_x86_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT(val)   _PR_Darwin_x86_AtomicIncrement(val)
+extern PRInt32 _PR_Darwin_x86_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT(val)   _PR_Darwin_x86_AtomicDecrement(val)
+extern PRInt32 _PR_Darwin_x86_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET(val, newval) _PR_Darwin_x86_AtomicSet(val, newval)
+extern PRInt32 _PR_Darwin_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD(ptr, val)    _PR_Darwin_x86_AtomicAdd(ptr, val)
+#endif /* __i386__ */
+
+#ifdef __x86_64__
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_Darwin_x86_64_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT(val)   _PR_Darwin_x86_64_AtomicIncrement(val)
+extern PRInt32 _PR_Darwin_x86_64_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT(val)   _PR_Darwin_x86_64_AtomicDecrement(val)
+extern PRInt32 _PR_Darwin_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET(val, newval) _PR_Darwin_x86_64_AtomicSet(val, newval)
+extern PRInt32 _PR_Darwin_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD(ptr, val)    _PR_Darwin_x86_64_AtomicAdd(ptr, val)
+#endif /* __x86_64__ */
+
+#define USE_SETJMP
+
+#if !defined(_PR_PTHREADS)
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th)       ((_th)->md.context)
+#define _MD_GET_SP(_th)    (((struct sigcontext *) (_th)->md.context)->sc_onstack)
+#define PR_NUM_GCREGS	    _JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (setjmp(CONTEXT(_thread))) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    longjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL        _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC    _PR_UNIX_TicksPerSecond
+
+extern void             _MD_EarlyInit(void);
+extern PRIntervalTime   _PR_UNIX_GetInterval(void);
+extern PRIntervalTime   _PR_UNIX_TicksPerSecond(void);
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+/* For writev() */
+#include <sys/uio.h>
+
+#endif /* nspr_darwin_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_dgux.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_dgux.cfg
new file mode 100644
index 0000000..4db8ec4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_dgux.cfg
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef DGUX
+#define DGUX
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_dgux.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_dgux.h
new file mode 100644
index 0000000..f3f02e8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_dgux.h
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_dgux_defs_h___
+#define nspr_dgux_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"dgux"
+#define _PR_SI_SYSNAME		"DGUX"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE	 	0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_NETCONFIG
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP setjmp
+#define _LONGJMP longjmp
+#define _PR_CONTEXT_TYPE         jmp_buf
+#define _MD_GET_SP(_t)           (_t)->md.context[4]
+#define _PR_NUM_GCREGS	_JBLEN
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+{								  \
+    *status = PR_TRUE; \
+    if(_SETJMP(CONTEXT(_thread))) (*_main)(); \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!_SETJMP(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    _LONGJMP(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures.
+ * Don't use SVR4 native threads (yet). 
+ */
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+                fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif  /* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)               ((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)       ((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)       ((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)      ((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)      ((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)  ((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)  ((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)       ((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)      ((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)      ((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)       ((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)  ((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)  32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *execptfds, struct timeval *timeout);
+#define _MD_SELECT _select
+
+#define _MD_POLL _poll
+#include <poll.h>
+#include <stropts.h>
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+#endif /* nspr_dgux_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_freebsd.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_freebsd.cfg
new file mode 100644
index 0000000..76d3542
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_freebsd.cfg
@@ -0,0 +1,337 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef FREEBSD
+#define FREEBSD
+#endif
+
+#define PR_AF_INET6 28  /* same as AF_INET6 */
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+
+#if defined(__i386__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__alpha__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#elif defined(__sparc__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#elif defined(__ia64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#elif defined(__amd64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_freebsd.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_freebsd.h
new file mode 100644
index 0000000..9cda93c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_freebsd.h
@@ -0,0 +1,278 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_freebsd_defs_h___
+#define nspr_freebsd_defs_h___
+
+#include "prthread.h"
+
+#if __FreeBSD__ >= 2
+#include <osreldate.h>  /* for __FreeBSD_version */
+#endif
+#include <sys/syscall.h>
+
+#define PR_LINKER_ARCH	"freebsd"
+#define _PR_SI_SYSNAME  "FREEBSD"
+#if defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__alpha__)
+#define _PR_SI_ARCHITECTURE "alpha"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__ia64__)
+#define _PR_SI_ARCHITECTURE "ia64"
+#elif defined(__amd64__)
+#define _PR_SI_ARCHITECTURE "amd64"
+#else
+#error "Unknown CPU architecture"
+#endif
+#if defined(__ELF__)
+#define PR_DLL_SUFFIX          ".so"
+#else
+#define PR_DLL_SUFFIX          ".so.1.0"
+#endif
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_HAVE_LARGE_OFF_T
+
+#if defined(_PR_PTHREADS)
+#if __FreeBSD_version >= 400008
+/*
+ * libc_r before this version of FreeBSD doesn't have poll().
+ * Although libc has poll(), it is not thread-safe so we can't
+ * use it in the pthreads version.
+ */
+#define _PR_POLL_AVAILABLE
+#endif
+#else
+#if __FreeBSD_version >= 300000
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#endif
+#endif
+
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#if __FreeBSD_version >= 400014
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#define _PR_IPV6_V6ONLY_PROBE
+#endif
+
+#define USE_SETJMP
+
+#ifndef _PR_PTHREADS
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#define _MD_GET_SP(_th)    (_th)->md.context[0]._sjb[2]
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!sigsetjmp(CONTEXT(_thread), 1)) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    siglongjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+extern void _MD_EarlyInit(void);
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+#if defined(_PR_POLL_AVAILABLE)
+#include <poll.h>
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+#endif
+
+/* freebsd has INADDR_LOOPBACK defined, but in /usr/include/rpc/types.h, and I didn't
+   want to be including that.. */
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK         (u_long)0x7F000001
+#endif
+
+/* For writev() */
+#include <sys/uio.h>
+
+#endif /* nspr_freebsd_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux.h
new file mode 100644
index 0000000..2a6f177
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux.h
@@ -0,0 +1,297 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_xhppa_defs_h___
+#define nspr_xhppa_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH    "hpux"
+#define _PR_SI_SYSNAME   "HPUX"
+#ifdef __ia64
+#define _PR_SI_ARCHITECTURE "ia64"
+#define PR_DLL_SUFFIX        ".so"
+#else
+/*
+ * _PR_SI_ARCHITECTURE must be "hppa1.1" for backward compatibility.
+ * It was changed to "hppa" in NSPR 4.6.2, but was changed back in
+ * NSPR 4.6.4.
+ */
+#define _PR_SI_ARCHITECTURE "hppa1.1"
+#define PR_DLL_SUFFIX        ".sl"
+#endif
+
+#define _PR_VMBASE        0x30000000 
+#define _PR_STACK_VMBASE    0x50000000
+/*
+ * _USE_BIG_FDS increases the size of fd_set from 256 bytes to
+ * about 7500 bytes.  PR_Poll allocates three fd_sets on the
+ * stack, so it is safer to also increase the default thread
+ * stack size.
+ */
+#define _MD_DEFAULT_STACK_SIZE    (2*65536L)
+#define _MD_MINIMUM_STACK_SIZE    (2*65536L)
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define NEED_TIME_R
+
+#define HAVE_STACK_GROWING_UP
+#undef	HAVE_WEAK_IO_SYMBOLS
+#undef	HAVE_WEAK_MALLOC_SYMBOLS
+#define	HAVE_DLL
+#ifdef IS_64
+#define USE_DLFCN
+#else
+#define USE_HPSHL
+#endif
+#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
+
+#if defined(__ia64)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_ia64_AtomicIncrement
+extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_ia64_AtomicDecrement
+extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_ia64_AtomicAdd
+extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_ia64_AtomicSet
+#endif
+
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#else
+#define _PR_INET6_PROBE
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* isomorphic to struct in6_addr on HP-UX B.11.23 */
+struct _md_in6_addr {
+    union {
+        PRUint8   _S6_u8[16];
+        PRUint16  _S6_u16[8];
+        PRUint32  _S6_u32[4];
+        PRUint32  __S6_align;
+    } _s6_un;
+};
+/* isomorphic to struct sockaddr_in6 on HP-UX B.11.23 */
+struct _md_sockaddr_in6 {
+    PRUint16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+};
+#endif
+
+#if !defined(_PR_PTHREADS)
+
+#include <syscall.h>
+#include <setjmp.h>
+
+#define USE_SETJMP
+
+#define _MD_GET_SP(_t) (*((int *)((_t)->md.jb) + 1))
+#define PR_NUM_GCREGS _JBLEN
+/* Caveat: This makes jmp_buf full of doubles. */
+#define CONTEXT(_th) ((_th)->md.jb)
+
+    /* Stack needs two frames (64 bytes) at the bottom */ \
+#define _MD_SET_THR_SP(_t, _sp)     ((_MD_GET_SP(_t)) = (int) (_sp + 64 *2))
+#define SAVE_CONTEXT(_th)           _setjmp(CONTEXT(_th))
+#define GOTO_CONTEXT(_th)           _longjmp(CONTEXT(_th), 1)
+
+#if !defined(PTHREADS_USER)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+{ \
+    *(status) = PR_TRUE; \
+    if (_setjmp(CONTEXT(_thread))) (*_main)(); \
+    /* Stack needs two frames (64 bytes) at the bottom */ \
+    (_MD_GET_SP(_thread)) = (int) ((_sp) + 64*2); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread) \
+    if (!_setjmp(CONTEXT(_thread))) { \
+    (_thread)->md.errcode = errno; \
+    _PR_Schedule(); \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{ \
+    errno = (_thread)->md.errcode; \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    _longjmp(CONTEXT(_thread), 1); \
+}
+
+/* Machine-dependent (MD) data structures.  HP-UX has no native threads. */
+
+struct _MDThread {
+    jmp_buf jb;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+#else /* PTHREADS_USER	*/
+
+#include "_nspr_pthread.h"
+
+#endif /* PTHREADS_USER	*/
+
+#endif  /* !defined(_PR_PTHREADS) */
+
+#if !defined(PTHREADS_USER)
+#define _MD_EARLY_INIT                 	_MD_EarlyInit
+#define _MD_FINAL_INIT					_PR_UnixInit
+#endif 
+
+#if defined(HPUX_LW_TIMER)
+extern void _PR_HPUX_LW_IntervalInit(void);
+extern PRIntervalTime _PR_HPUX_LW_GetInterval(void);
+#define _MD_INTERVAL_INIT                 _PR_HPUX_LW_IntervalInit
+#define _MD_GET_INTERVAL                  _PR_HPUX_LW_GetInterval
+#define _MD_INTERVAL_PER_SEC()            1000
+#else
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+#endif
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+#include <poll.h>
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+
+#ifdef HPUX11
+extern void _MD_hpux_map_sendfile_error(int err);
+#endif /* HPUX11 */
+
+#endif /* nspr_xhppa_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux32.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux32.cfg
new file mode 100644
index 0000000..d79b1a9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux32.cfg
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BYTES_PER_WORD_LOG2 2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux64.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux64.cfg
new file mode 100644
index 0000000..f1f829d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_hpux64.cfg
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BYTES_PER_WORD_LOG2 3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix.h
new file mode 100644
index 0000000..c38bb4b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix.h
@@ -0,0 +1,470 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_irix_defs_h___
+#define nspr_irix_defs_h___
+
+#define _PR_HAVE_ATOMIC_CAS
+
+/*
+ * MipsPro assembler defines _LANGUAGE_ASSEMBLY
+ */
+#ifndef _LANGUAGE_ASSEMBLY
+
+#include "prclist.h"
+#include "prthread.h"
+#include <sys/ucontext.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH          "irix"
+#define _PR_SI_SYSNAME          "IRIX"
+#define _PR_SI_ARCHITECTURE     "mips"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE        0x50000000
+#define _PR_NUM_GCREGS          9
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define _MD_DEFAULT_STACK_SIZE  65536L
+#define _MD_MIN_STACK_SIZE      16384L
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_WEAK_IO_SYMBOLS
+#define HAVE_WEAK_MALLOC_SYMBOLS
+#define HAVE_DLL
+#define USE_DLFCN
+#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
+
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#endif
+
+/* 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
+
+#define _MD_INIT_IO()
+
+/* Timer operations */
+NSPR_API(PRIntervalTime) _MD_IrixGetInterval(void);
+#define _MD_GET_INTERVAL _MD_IrixGetInterval
+
+NSPR_API(PRIntervalTime) _MD_IrixIntervalPerSec(void);
+#define _MD_INTERVAL_PER_SEC _MD_IrixIntervalPerSec
+
+/* GC operations */
+NSPR_API(void *) _MD_GetSP(PRThread *thread);
+#define    _MD_GET_SP _MD_GetSP
+
+/* The atomic operations */
+#include <mutex.h>
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(val) add_then_test((unsigned long*)val, 1)
+#define _MD_ATOMIC_ADD(ptr, val) add_then_test((unsigned long*)ptr, (unsigned long)val)
+#define _MD_ATOMIC_DECREMENT(val) add_then_test((unsigned long*)val, 0xffffffff)
+#define _MD_ATOMIC_SET(val, newval) test_and_set((unsigned long*)val, newval)
+
+#if defined(_PR_PTHREADS)
+#else /* defined(_PR_PTHREADS) */
+
+/************************************************************************/
+
+#include <setjmp.h>
+#include <errno.h>
+#include <unistd.h>
+#include <bstring.h>
+#include <sys/time.h>
+#include <ulocks.h>
+#include <sys/prctl.h>
+
+
+/*
+ * Data region private to each sproc. This region is setup by calling
+ * mmap(...,MAP_LOCAL,...). The private data is mapped at the same
+ * address in every sproc, but every sproc gets a private mapping.
+ *
+ * Just make sure that this structure fits in a page, as only one page
+ * is allocated for the private region.
+ */
+struct sproc_private_data {
+    struct PRThread *me;
+    struct _PRCPU *cpu;
+    struct PRThread *last;
+    PRUintn intsOff;
+	int		sproc_pid;
+};
+
+extern char *_nspr_sproc_private;
+
+#define _PR_PRDA() ((struct sproc_private_data *) _nspr_sproc_private)
+#define _MD_SET_CURRENT_THREAD(_thread) _PR_PRDA()->me = (_thread)
+#define _MD_THIS_THREAD() (_PR_PRDA()->me)
+#define _MD_LAST_THREAD() (_PR_PRDA()->last)
+#define _MD_SET_LAST_THREAD(_thread) _PR_PRDA()->last = (_thread)
+#define _MD_CURRENT_CPU() (_PR_PRDA()->cpu)
+#define _MD_SET_CURRENT_CPU(_cpu) _PR_PRDA()->cpu = (_cpu)
+#define _MD_SET_INTSOFF(_val) (_PR_PRDA()->intsOff = _val)
+#define _MD_GET_INTSOFF() (_PR_PRDA()->intsOff)
+
+#define _MD_SET_SPROC_PID(_val) (_PR_PRDA()->sproc_pid = _val)
+#define _MD_GET_SPROC_PID() (_PR_PRDA()->sproc_pid)
+
+NSPR_API(struct PRThread*) _MD_get_attached_thread(void);
+NSPR_API(struct PRThread*) _MD_get_current_thread(void);
+#define _MD_GET_ATTACHED_THREAD()	_MD_get_attached_thread()
+#define _MD_CURRENT_THREAD()	_MD_get_current_thread()
+
+#define _MD_CHECK_FOR_EXIT() {					\
+		if (_pr_irix_exit_now) {				\
+			_PR_POST_SEM(_pr_irix_exit_sem);	\
+			_MD_Wakeup_CPUs();					\
+			_exit(0);							\
+		}										\
+	}
+		
+#define _MD_ATTACH_THREAD(threadp)
+
+#define _MD_SAVE_ERRNO(_thread)			(_thread)->md.errcode = errno;
+#define _MD_RESTORE_ERRNO(_thread)		errno = (_thread)->md.errcode;
+
+extern struct _PRCPU  *_pr_primordialCPU;
+extern usema_t *_pr_irix_exit_sem;
+extern PRInt32 _pr_irix_exit_now;
+extern int _pr_irix_primoridal_cpu_fd[];
+extern PRInt32 _pr_irix_process_exit;
+extern PRInt32 _pr_irix_process_exit_code;
+
+/* Thread operations */
+#define _PR_LOCK_HEAP()	{						\
+			PRIntn _is;					\
+				if (_pr_primordialCPU) {		\
+				if (_MD_GET_ATTACHED_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_MD_GET_ATTACHED_THREAD()))	\
+						_PR_INTSOFF(_is); 	\
+					_PR_LOCK(_pr_heapLock);		\
+				}
+
+#define _PR_UNLOCK_HEAP() 	if (_pr_primordialCPU)	{		\
+					_PR_UNLOCK(_pr_heapLock);	\
+				if (_MD_GET_ATTACHED_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_MD_GET_ATTACHED_THREAD()))	\
+						_PR_INTSON(_is);	\
+				}					\
+			  }
+
+#define _PR_OPEN_POLL_SEM(_sem)  usopenpollsema(_sem, 0666)
+#define _PR_WAIT_SEM(_sem) uspsema(_sem)
+#define _PR_POST_SEM(_sem) usvsema(_sem)
+
+#define _MD_CVAR_POST_SEM(threadp)	usvsema((threadp)->md.cvar_pollsem)
+
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+struct _MDLock {
+    ulock_t lock;
+	usptr_t *arena;
+};
+
+/*
+ * disable pre-emption for the LOCAL threads when calling the arena lock
+ * routines
+ */
+
+#define _PR_LOCK(lock) {						\
+		PRIntn _is;						\
+		PRThread *me = _MD_GET_ATTACHED_THREAD();			\
+		if (me && !_PR_IS_NATIVE_THREAD(me))			\
+			_PR_INTSOFF(_is); 				\
+		ussetlock(lock);					\
+		if (me && !_PR_IS_NATIVE_THREAD(me))			\
+			_PR_FAST_INTSON(_is); 				\
+	}
+
+#define _PR_UNLOCK(lock) {						\
+		PRIntn _is;						\
+		PRThread *me = _MD_GET_ATTACHED_THREAD();			\
+		if (me && !_PR_IS_NATIVE_THREAD(me))			\
+			_PR_INTSOFF(_is); 				\
+		usunsetlock(lock);					\
+		if (me && !_PR_IS_NATIVE_THREAD(me))			\
+			_PR_FAST_INTSON(_is); 				\
+	}
+
+NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md);
+NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp);
+
+#define _MD_LOCK(_lockp) _PR_LOCK((_lockp)->lock)
+#define _MD_UNLOCK(_lockp) _PR_UNLOCK((_lockp)->lock)
+#define _MD_TEST_AND_LOCK(_lockp) (uscsetlock((_lockp)->lock, 1) == 0)
+
+extern ulock_t _pr_heapLock;
+
+struct _MDThread {
+    jmp_buf jb;
+    usptr_t     *pollsem_arena;
+    usema_t     *cvar_pollsem;
+    PRInt32     cvar_pollsemfd;
+    PRInt32     cvar_pollsem_select;    /* acquire sem by calling select */
+    PRInt32     cvar_wait;              /* if 1, thread is waiting on cvar Q */
+    PRInt32	id;
+    PRInt32	suspending_id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    usema_t *sem;
+};
+
+struct _MDCVar {
+    ulock_t mdcvar_lock;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+
+struct _MDCPU {
+    PRInt32 id;
+    PRInt32 suspending_id;
+    struct _MDCPU_Unix md_unix;
+};
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+    PR_BEGIN_MACRO				      \
+	int *jb = (_thread)->md.jb;		      \
+    *status = PR_TRUE;              \
+	(void) setjmp(jb);			      \
+	(_thread)->md.jb[JB_SP] = (int) ((_sp) - 64); \
+	(_thread)->md.jb[JB_PC] = (int) _main;	      \
+	_thread->no_sched = 0; \
+    PR_END_MACRO
+
+/*
+** Switch away from the current thread context by saving its state and
+** calling the thread scheduler. Reload cpu when we come back from the
+** context switch because it might have changed.
+*
+*  XXX RUNQ lock needed before clearing _PR_NO_SCHED flag, because the
+*      thread may be unr RUNQ?
+*/
+#define _MD_SWITCH_CONTEXT(_thread) \
+    PR_BEGIN_MACRO    \
+    PR_ASSERT(_thread->no_sched); \
+    if (!setjmp(_thread->md.jb)) { \
+        _MD_SAVE_ERRNO(_thread) \
+        _MD_SET_LAST_THREAD(_thread); \
+        _PR_Schedule(); \
+    } else {      \
+        PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \
+            _MD_LAST_THREAD()->no_sched = 0;			\
+    }             \
+    PR_END_MACRO
+
+/*
+** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
+** initialized by _MD_INIT_CONTEXT.
+*/
+#define _MD_RESTORE_CONTEXT(_newThread) \
+    PR_BEGIN_MACRO \
+    int *jb = (_newThread)->md.jb; \
+    _MD_RESTORE_ERRNO(_newThread) \
+    _MD_SET_CURRENT_THREAD(_newThread); \
+    _newThread->no_sched = 1;		\
+    longjmp(jb, 1); \
+    PR_END_MACRO
+
+NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread,
+								PRBool wakeup_parent);
+NSPR_API(PRStatus) _MD_InitAttachedThread(struct PRThread *thread,
+									PRBool wakeup_parent);
+#define _MD_INIT_THREAD(thread) 			_MD_InitThread(thread, PR_TRUE)
+#define _MD_INIT_ATTACHED_THREAD(thread)		\
+						_MD_InitAttachedThread(thread, PR_FALSE)
+
+NSPR_API(void) _MD_ExitThread(struct PRThread *thread);
+#define _MD_EXIT_THREAD _MD_ExitThread
+
+NSPR_API(void) _MD_SuspendThread(struct PRThread *thread);
+#define _MD_SUSPEND_THREAD _MD_SuspendThread
+
+NSPR_API(void) _MD_ResumeThread(struct PRThread *thread);
+#define _MD_RESUME_THREAD _MD_ResumeThread
+
+NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread);
+#define _MD_SUSPEND_CPU _MD_SuspendCPU
+
+NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread);
+#define _MD_RESUME_CPU _MD_ResumeCPU
+
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_RESUME_ALL()
+
+NSPR_API(void) _MD_InitLocks(void);
+#define _MD_INIT_LOCKS _MD_InitLocks
+
+NSPR_API(void) _MD_CleanThread(struct PRThread *thread);
+#define _MD_CLEAN_THREAD _MD_CleanThread
+
+#define _MD_YIELD()    sginap(0)
+
+/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
+ * awaken a thread which is waiting on a lock or cvar.
+ */
+NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout);
+#define _MD_WAIT _MD_wait
+
+NSPR_API(void) _PR_MD_primordial_cpu();
+NSPR_API(void) _PR_MD_WAKEUP_PRIMORDIAL_CPU();
+
+NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *);
+#define _MD_WAKEUP_WAITER _MD_WakeupWaiter
+
+NSPR_API(void ) _MD_exit(PRIntn status);
+#define _MD_EXIT	_MD_exit
+
+#include "prthread.h"
+
+NSPR_API(void) _MD_SetPriority(struct _MDThread *thread,
+	PRThreadPriority newPri);
+#define _MD_SET_PRIORITY _MD_SetPriority
+
+NSPR_API(PRStatus) _MD_CreateThread(
+                        struct PRThread *thread,
+                        void (*start) (void *),
+                        PRThreadPriority priority,
+                        PRThreadScope scope,
+                        PRThreadState state,
+                        PRUint32 stackSize);
+#define _MD_CREATE_THREAD _MD_CreateThread
+
+extern void _MD_CleanupBeforeExit(void);
+#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
+
+NSPR_API(void) _PR_MD_PRE_CLEANUP(PRThread *me);
+
+
+/* The following defines the unwrapped versions of select() and poll(). */
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *exceptfds, struct timeval *timeout);
+#define _MD_SELECT	_select
+
+#include <stropts.h>
+#include <poll.h>
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+
+#define HAVE_THREAD_AFFINITY 1
+
+NSPR_API(PRInt32) _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask);
+#define _MD_GETTHREADAFFINITYMASK _MD_GetThreadAffinityMask
+
+NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu);
+#define    _MD_INIT_RUNNING_CPU _MD_InitRunningCPU
+
+#endif  /* defined(_PR_PTHREADS) */
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#endif /* nspr_irix_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix32.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix32.cfg
new file mode 100644
index 0000000..88e0cee
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix32.cfg
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef _SGI_MP_SOURCE
+#define _SGI_MP_SOURCE
+#endif
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix64.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix64.cfg
new file mode 100644
index 0000000..ba51eca
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_irix64.cfg
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef _SGI_MP_SOURCE
+#define _SGI_MP_SOURCE
+#endif
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_linux.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_linux.cfg
new file mode 100644
index 0000000..dea4cf3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_linux.cfg
@@ -0,0 +1,861 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This file is used by not only Linux but also other glibc systems
+ * such as GNU/Hurd and GNU/k*BSD.
+ */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#if !defined(LINUX) && defined(__linux__)
+#define LINUX
+#endif
+
+#ifdef __FreeBSD_kernel__
+#define PR_AF_INET6 28  /* same as AF_INET6 */
+#else
+#define PR_AF_INET6 10  /* same as AF_INET6 */
+#endif
+
+#ifdef __powerpc64__
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN    1
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__alpha)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__ia64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__x86_64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__mc68000__)
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     2
+#define PR_ALIGN_OF_LONG    2
+#define PR_ALIGN_OF_INT64   2
+#define PR_ALIGN_OF_FLOAT   2
+#define PR_ALIGN_OF_DOUBLE  2
+#define PR_ALIGN_OF_POINTER 2
+#define PR_ALIGN_OF_WORD    2
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__sparc__) && defined (__arch64__)
+
+#undef	IS_LITTLE_ENDIAN
+#define	IS_BIG_ENDIAN 1
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__sparc__)
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__i386__)
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__mips__)
+
+#ifdef __MIPSEB__
+#define IS_BIG_ENDIAN 1
+#undef  IS_LITTLE_ENDIAN
+#elif defined(__MIPSEL__)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#else
+#error "Unknown MIPS endianness."
+#endif
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__arm__)
+
+#ifdef __ARMEB__
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#elif defined(__ARMEL__)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#else
+#error "Unknown ARM endianness."
+#endif
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__hppa__)
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__s390x__)
+
+#define IS_BIG_ENDIAN 1
+#undef  IS_LITTLE_ENDIAN
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__s390__)
+
+#define IS_BIG_ENDIAN 1
+#undef  IS_LITTLE_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__sh__)
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__avr32__)
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#if PR_ALIGN_OF_DOUBLE == 8
+#define HAVE_ALIGNED_DOUBLES
+#endif
+#if PR_ALIGN_OF_INT64 == 8
+#define HAVE_ALIGNED_LONGLONGS
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_linux.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_linux.h
new file mode 100644
index 0000000..a125192
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_linux.h
@@ -0,0 +1,658 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This file is used by not only Linux but also other glibc systems
+ * such as GNU/Hurd and GNU/k*BSD.
+ */
+
+#ifndef nspr_linux_defs_h___
+#define nspr_linux_defs_h___
+
+#include "prthread.h"
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"linux"
+#define _PR_SI_SYSNAME  "LINUX"
+#ifdef __powerpc64__
+#define _PR_SI_ARCHITECTURE "ppc64"
+#elif defined(__powerpc__)
+#define _PR_SI_ARCHITECTURE "ppc"
+#elif defined(__alpha)
+#define _PR_SI_ARCHITECTURE "alpha"
+#elif defined(__ia64__)
+#define _PR_SI_ARCHITECTURE "ia64"
+#elif defined(__x86_64__)
+#define _PR_SI_ARCHITECTURE "x86-64"
+#elif defined(__mc68000__)
+#define _PR_SI_ARCHITECTURE "m68k"
+#elif defined(__sparc__) && defined(__arch64__)
+#define _PR_SI_ARCHITECTURE "sparc64"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__mips__)
+#define _PR_SI_ARCHITECTURE "mips"
+#elif defined(__arm__)
+#define _PR_SI_ARCHITECTURE "arm"
+#elif defined(__hppa__)
+#define _PR_SI_ARCHITECTURE "hppa"
+#elif defined(__s390x__)
+#define _PR_SI_ARCHITECTURE "s390x"
+#elif defined(__s390__)
+#define _PR_SI_ARCHITECTURE "s390"
+#elif defined(__sh__)
+#define _PR_SI_ARCHITECTURE "sh"
+#elif defined(__avr32__)
+#define _PR_SI_ARCHITECTURE "avr32"
+#else
+#error "Unknown CPU architecture"
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef	HAVE_STACK_GROWING_UP
+
+/*
+ * Elf linux supports dl* functions
+ */
+#define HAVE_DLL
+#define USE_DLFCN
+#if defined(ANDROID)
+#define NO_DLOPEN_NULL
+#endif
+
+#ifdef __FreeBSD_kernel__
+#define _PR_HAVE_SOCKADDR_LEN
+#endif
+
+#if defined(__i386__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_x86_AtomicIncrement
+extern PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_x86_AtomicDecrement
+extern PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_x86_AtomicAdd
+extern PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_x86_AtomicSet
+#endif
+
+#if defined(__ia64__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_ia64_AtomicIncrement
+extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_ia64_AtomicDecrement
+extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_ia64_AtomicAdd
+extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_ia64_AtomicSet
+#endif
+
+#if defined(__x86_64__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_x86_64_AtomicIncrement
+extern PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_x86_64_AtomicDecrement
+extern PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_x86_64_AtomicAdd
+extern PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_x86_64_AtomicSet
+#endif
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_ppc_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_ppc_AtomicIncrement
+extern PRInt32 _PR_ppc_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_ppc_AtomicDecrement
+extern PRInt32 _PR_ppc_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_ppc_AtomicAdd
+extern PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_ppc_AtomicSet
+#endif
+
+#if defined(__alpha)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_ADD(ptr, i) ({               \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    __asm__ __volatile__(                       \
+    "1: ldl_l   %[ret], %[val]          \n"     \
+    "   addl    %[ret], %[inc], %[tmp]  \n"     \
+    "   addl    %[ret], %[inc], %[ret]  \n"     \
+    "   stl_c   %[tmp], %[val]          \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r" (__atomic_tmp),               \
+      [val] "=m" (*ptr)                         \
+    : [inc] "Ir" (i), "m" (*ptr));              \
+    __atomic_ret;                               \
+})
+#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1)
+#define _MD_ATOMIC_DECREMENT(ptr) ({            \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    __asm__ __volatile__(                       \
+    "1: ldl_l   %[ret], %[val]          \n"     \
+    "   subl    %[ret], 1, %[tmp]       \n"     \
+    "   subl    %[ret], 1, %[ret]       \n"     \
+    "   stl_c   %[tmp], %[val]          \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r" (__atomic_tmp),               \
+      [val] "=m" (*ptr)                         \
+    : "m" (*ptr));                              \
+    __atomic_ret;                               \
+})
+#define _MD_ATOMIC_SET(ptr, n) ({               \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    __asm__ __volatile__(                       \
+    "1: ldl_l   %[ret], %[val]          \n"     \
+    "   mov     %[newval], %[tmp]       \n"     \
+    "   stl_c   %[tmp], %[val]          \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r"(__atomic_tmp),                \
+      [val] "=m" (*ptr)                         \
+    : [newval] "Ir" (n), "m" (*ptr));           \
+    __atomic_ret;                               \
+})
+#endif
+
+#if defined(__arm__) && defined(_PR_ARM_KUSER)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+
+/*
+ * The kernel provides this helper function at a fixed address with a fixed
+ * ABI signature, directly callable from user space.
+ *
+ * Definition:
+ * Atomically store newval in *ptr if *ptr is equal to oldval.
+ * Return zero if *ptr was changed or non-zero if no exchange happened.
+ */
+typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
+
+#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1)
+#define _MD_ATOMIC_DECREMENT(ptr) _MD_ATOMIC_ADD(ptr, -1)
+
+static inline PRInt32 _MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 n)
+{
+    PRInt32 ov, nv;
+    volatile PRInt32 *vp = ptr;
+
+    do {
+        ov = *vp;
+        nv = ov + n;
+    } while (__kernel_cmpxchg(ov, nv, vp));
+
+    return nv;
+}
+
+static inline PRInt32 _MD_ATOMIC_SET(PRInt32 *ptr, PRInt32 nv)
+{
+    PRInt32 ov;
+    volatile PRInt32 *vp = ptr;
+
+    do {
+        ov = *vp;
+    } while (__kernel_cmpxchg(ov, nv, vp));
+
+    return ov;
+}
+#endif
+
+#define USE_SETJMP
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _PR_POLL_AVAILABLE
+#endif
+#undef _PR_USE_POLL
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#if defined(__alpha) || defined(__ia64__)
+#define _PR_HAVE_LARGE_OFF_T
+#elif (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#define _PR_HAVE_OFF64_T
+#else
+#define _PR_NO_LARGE_FILES
+#endif
+#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#endif
+#ifndef ANDROID
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#endif
+#if (__GLIBC__ >= 2) && defined(_PR_PTHREADS)
+#define _PR_HAVE_GETHOST_R
+#define _PR_HAVE_GETHOST_R_INT
+#endif
+
+#ifdef _PR_PTHREADS
+
+extern void _MD_CleanupBeforeExit(void);
+#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
+
+#else  /* ! _PR_PTHREADS */
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#ifdef __powerpc__
+/*
+ * PowerPC based MkLinux
+ *
+ * On the PowerPC, the new style jmp_buf isn't used until glibc
+ * 2.1.
+ */
+#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_GPR1]
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__misc[0]
+#endif /* glibc 2.1 or later */
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+/* aix = 64, macos = 70 */
+#define PR_NUM_GCREGS  64
+
+#elif defined(__alpha)
+/* Alpha based Linux */
+
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE long int
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE __ptr_t
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+/* XXX not sure if this is correct, or maybe it should be 17? */
+#define PR_NUM_GCREGS 9
+
+#elif defined(__ia64__)
+
+#define _MD_GET_SP(_t)      ((long *)((_t)->md.context[0].__jmpbuf)[0])
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t)  &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t)  ((void *) 0)
+#define _MD_SP_TYPE         long int
+
+#define PR_NUM_GCREGS       _JBLEN
+
+#elif defined(__mc68000__)
+/* m68k based Linux */
+
+/*
+ * On the m68k, glibc still uses the old style sigjmp_buf, even
+ * in glibc 2.0.7.
+ */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE int
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE __ptr_t
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+/* XXX not sure if this is correct, or maybe it should be 17? */
+#define PR_NUM_GCREGS 9
+
+#elif defined(__sparc__)
+/* Sparc */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+/*
+ * You need glibc2-2.0.7-25 or later. The libraries that came with
+ * Red Hat 5.1 are not new enough, but they are in 5.2.
+ */
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_FP] = val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_FP])
+#define _MD_SP_TYPE int
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__fp
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE __ptr_t
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+#elif defined(__i386__)
+/* Intel based Linux */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_BP] = val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_BP])
+#define _MD_SP_TYPE int
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__bp = val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) &((_t)->md.context[0].__jmpbuf[0].__bp)
+#define _MD_SP_TYPE __ptr_t
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+#define PR_NUM_GCREGS   6
+
+#elif defined(__mips__)
+/* Linux/MIPS */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__fp = (val))
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__fp)
+#define _MD_SP_TYPE __ptr_t
+#else
+#error "Linux/MIPS pre-glibc2 not supported yet"
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+#elif defined(__arm__)
+/* ARM/Linux */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#ifdef __ARM_EABI__
+/* EABI */
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[8]
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[7] = (val))
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[7])
+#define _MD_SP_TYPE __ptr_t
+#else /* __ARM_EABI__ */
+/* old ABI */
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[20]
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[19] = (val))
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[19])
+#define _MD_SP_TYPE __ptr_t
+#endif /* __ARM_EABI__ */
+#else
+#error "ARM/Linux pre-glibc2 not supported yet"
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+#elif defined(__sh__)
+/* SH/Linux */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[7]
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[6] = (val))
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[6])
+#define _MD_SP_TYPE __ptr_t
+#else
+#error "SH/Linux pre-glibc2 not supported yet"
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif /*__powerpc__*/
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#ifdef __powerpc__
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 128); \
+    _thread->md.sp = _MD_GET_SP_PTR(_thread); \
+    _thread->md.fp = _MD_GET_FP_PTR(_thread); \
+    _MD_SET_FP(_thread, 0); \
+}
+
+#elif defined(__mips__)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    (void) sigsetjmp(CONTEXT(_thread), 1);  \
+    _thread->md.context[0].__jmpbuf[0].__pc = (__ptr_t) _main;  \
+    _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \
+    _thread->md.sp = _MD_GET_SP_PTR(_thread); \
+    _thread->md.fp = _MD_GET_FP_PTR(_thread); \
+    _MD_SET_FP(_thread, 0); \
+}
+
+#else
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \
+    _thread->md.sp = _MD_GET_SP_PTR(_thread); \
+    _thread->md.fp = _MD_GET_FP_PTR(_thread); \
+    _MD_SET_FP(_thread, 0); \
+}
+
+#endif /*__powerpc__*/
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!sigsetjmp(CONTEXT(_thread), 1)) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    siglongjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    void *sp;
+    void *fp;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#include <sys/time.h>  /* for FD_SETSIZE */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+            fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+extern void _MD_EarlyInit(void);
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT                  _PR_UnixInit
+#define _MD_GET_INTERVAL                _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC            _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT __select
+
+#ifdef _PR_POLL_AVAILABLE
+#include <sys/poll.h>
+extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds,
+	int timeout);
+#define _MD_POLL __syscall_poll
+#endif
+
+/* For writev() */
+#include <sys/uio.h>
+
+extern void _MD_linux_map_sendfile_error(int err);
+
+#endif /* nspr_linux_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_ncr.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_ncr.cfg
new file mode 100644
index 0000000..c8a32bf
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_ncr.cfg
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NCR
+#define NCR
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_ncr.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_ncr.h
new file mode 100644
index 0000000..d094c2e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_ncr.h
@@ -0,0 +1,230 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_unixware_defs_h___
+#define nspr_unixware_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"ncr"
+#define _PR_SI_SYSNAME		"NCR"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE	 	0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define _PR_RECV_BROKEN /* recv doesn't work on Unix Domain Sockets */
+
+#if !defined (HAVE_STRERROR)
+#define HAVE_STRERROR
+#endif
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_NO_LARGE_FILES
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_NETCONFIG
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define NEED_LOCALTIME_R
+#define NEED_GMTIME_R  
+#define NEED_ASCTIME_R
+#define NEED_STRTOK_R
+#define NEED_CTIME_R
+#define _PR_NEED_STRCASECMP
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP setjmp
+#define _LONGJMP longjmp
+#define _PR_CONTEXT_TYPE         jmp_buf
+#define _MD_GET_SP(_t)           (_t)->md.context[4]
+#define _PR_NUM_GCREGS	_JBLEN
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+{								  \
+    *status = PR_TRUE; \
+    if(_SETJMP(CONTEXT(_thread))) (*_main)(); \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!_SETJMP(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    _LONGJMP(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures.
+ * Don't use SVR4 native threads (yet). 
+ */
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *execptfds, struct timeval *timeout);
+#define _MD_SELECT _select
+
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+#endif /* nspr_ncr_defs_h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nec.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nec.cfg
new file mode 100644
index 0000000..558a525
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nec.cfg
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NEC
+#define NEC
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#undef  HAVE_LONG_LONG
+#undef  HAVE_ALIGNED_DOUBLES
+#undef  HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nec.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nec.h
new file mode 100644
index 0000000..ed7e8a3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nec.h
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_nec_defs_h___
+#define nspr_nec_defs_h___
+ 
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH  "nec"
+#define _PR_SI_SYSNAME "NEC"
+#define _PR_SI_ARCHITECTURE "mips"
+#define PR_DLL_SUFFIX		".so"
+ 
+#define _PR_STACK_VMBASE        0x50000000
+#define _MD_DEFAULT_STACK_SIZE  65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define NEED_TIME_R
+#define NEED_STRFTIME_LOCK
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ST_ATIM_UNION
+ 
+#include <ucontext.h>
+#include <sys/regset.h>
+ 
+#define PR_NUM_GCREGS   NGREG
+#define PR_CONTEXT_TYPE ucontext_t
+ 
+#define CONTEXT(_thread) (&(_thread)->md.context)
+ 
+#define _MD_GET_SP(_t)    (_t)->md.context.uc_mcontext.gregs[CXT_SP]
+ 
+/*
+** Initialize the thread context preparing it to execute "e(o,a)"
+*/
+#define _MD_INIT_CONTEXT(thread, _sp, _main, status)               \
+{                                                                   \
+    *status = PR_TRUE; \
+    getcontext(CONTEXT(thread));                                    \
+    CONTEXT(thread)->uc_stack.ss_sp = (char*) (thread)->stack->stackBottom; \
+    CONTEXT(thread)->uc_stack.ss_size = (thread)->stack->stackSize; \
+    _MD_GET_SP(thread) = (greg_t) _sp - 64;             \
+    makecontext(CONTEXT(thread), _main, 0);              \
+}
+ 
+#define _MD_SWITCH_CONTEXT(_thread)      \
+    if (!getcontext(CONTEXT(_thread))) { \
+        (_thread)->md.errcode = errno;      \
+        _PR_Schedule();                  \
+    }
+ 
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)   \
+{                                      \
+    ucontext_t *uc = CONTEXT(_thread); \
+    uc->uc_mcontext.gregs[CXT_V0] = 1; \
+    uc->uc_mcontext.gregs[CXT_A3] = 0; \
+    errno = (_thread)->md.errcode;     \
+    _MD_SET_CURRENT_THREAD(_thread);   \
+    setcontext(uc);                    \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+#define _MD_SELECT _select
+#define _MD_POLL _poll
+
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+ 
+#endif /* nspr_nec_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_netbsd.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_netbsd.cfg
new file mode 100644
index 0000000..4a63838
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_netbsd.cfg
@@ -0,0 +1,383 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NETBSD
+#define NETBSD
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+
+#if defined(__i386__) || defined(__arm32__) || defined(__ARMEL__) || \
+	defined(__MIPSEL__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__sparc_v9__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8 
+#define PR_ALIGN_OF_FLOAT   4 
+#define PR_ALIGN_OF_DOUBLE  8 
+#define PR_ALIGN_OF_POINTER 8 
+
+#elif defined(__sparc__) || defined(__MIPSEB__) || defined(__ARMEB__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__alpha__)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__amd64__)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__powerpc__) || defined(__m68k__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN    1
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error Must define constants for type sizes here.
+
+#endif
+
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_netbsd.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_netbsd.h
new file mode 100644
index 0000000..bf57a4f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_netbsd.h
@@ -0,0 +1,265 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_netbsd_defs_h___
+#define nspr_netbsd_defs_h___
+
+#include <sys/syscall.h>
+#include <sys/param.h>  /* for __NetBSD_Version__ */
+
+#define PR_LINKER_ARCH	"netbsd"
+#define _PR_SI_SYSNAME  "NetBSD"
+#if defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__alpha__)
+#define _PR_SI_ARCHITECTURE "alpha"
+#elif defined(__amd64__)
+#define _PR_SI_ARCHITECTURE "amd64"
+#elif defined(__m68k__)
+#define _PR_SI_ARCHITECTURE "m68k"
+#elif defined(__powerpc__)
+#define _PR_SI_ARCHITECTURE "powerpc"
+#elif defined(__sparc_v9__)
+#define _PR_SI_ARCHITECTURE "sparc64"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__mips__)
+#define _PR_SI_ARCHITECTURE "mips"
+#elif defined(__arm32__) || defined(__arm__) || defined(__armel__) \
+    || defined(__armeb__)
+#define _PR_SI_ARCHITECTURE "arm"
+#endif
+
+#if defined(__ELF__)
+#define PR_DLL_SUFFIX		".so"
+#else
+#define PR_DLL_SUFFIX		".so.1.0"
+#endif
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#if __NetBSD_Version__ >= 105000000
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#endif
+
+#define USE_SETJMP
+
+#ifndef _PR_PTHREADS
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#if defined(__i386__) || defined(__sparc__) || defined(__m68k__) || defined(__powerpc__)
+#define JB_SP_INDEX 2
+#elif defined(__mips__)
+#define JB_SP_INDEX 4
+#elif defined(__alpha__)
+#define JB_SP_INDEX 34
+#elif defined(__arm32__)
+/*
+ * On the arm32, the jmpbuf regs underwent a name change after NetBSD 1.3.
+ */
+#ifdef JMPBUF_REG_R13
+#define JB_SP_INDEX JMPBUF_REG_R13
+#else
+#define JB_SP_INDEX _JB_REG_R13
+#endif
+#else
+#error "Need to define SP index in jmp_buf here"
+#endif
+#define _MD_GET_SP(_th)    (_th)->md.context[JB_SP_INDEX]
+
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!sigsetjmp(CONTEXT(_thread), 1)) {  \
+        (_thread)->md.errcode = errno;  \
+        _PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    siglongjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+#endif /* ! _PR_PTHREADS */
+
+extern void _MD_EarlyInit(void);
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+#if defined(_PR_POLL_AVAILABLE)
+#include <poll.h>
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+#endif
+
+#if NetBSD1_3 == 1L
+typedef unsigned int nfds_t;
+#endif
+
+#endif /* nspr_netbsd_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nextstep.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nextstep.cfg
new file mode 100644
index 0000000..ce623cb
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nextstep.cfg
@@ -0,0 +1,255 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NEXTSTEP
+#define NEXTSTEP
+#endif
+
+/*	Platform specific
+*/
+#if defined(__sparc__)
+
+/* Check these
+*/
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+/* Taken from _solaris.cfg
+*/
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+/* Taken from _solaris.cfg
+*/
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+/* Taken from _solaris.cfg
+*/
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_WORDS_PER_DWORD_LOG2  1
+
+#elif defined(__m68k__)
+
+/* Check these
+*/
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     2
+#define PR_ALIGN_OF_LONG    2
+#define PR_ALIGN_OF_INT64   2
+#define PR_ALIGN_OF_FLOAT   2
+#define PR_ALIGN_OF_DOUBLE  2
+#define PR_ALIGN_OF_POINTER 2
+
+#define PR_WORDS_PER_DWORD_LOG2  1
+
+#elif defined(__i386__)
+
+/* Check these
+*/
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+#define PR_WORDS_PER_DWORD_LOG2  1
+#endif /* defined(__somearch__) */
+
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nextstep.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nextstep.h
new file mode 100644
index 0000000..e7e4c05
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nextstep.h
@@ -0,0 +1,299 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_nextstep_defs_h___
+#define nspr_nextstep_defs_h___
+
+#include "prthread.h"
+
+#include <bsd/libc.h>
+#include <bsd/syscall.h>
+
+/*	syscall() is not declared in NEXTSTEP's syscall.h ...
+*/
+extern int syscall(int number, ...);
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"nextstep"
+#define _PR_SI_SYSNAME  "NEXTSTEP"
+#if defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__m68k__)
+#define _PR_SI_ARCHITECTURE "m68k"
+#elif defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#else
+error Unknown NEXTSTEP architecture
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+
+#define HAVE_WEAK_MALLOC_SYMBOLS
+
+#define HAVE_DLL
+#define USE_MACH_DYLD
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define _PR_NO_LARGE_FILES
+
+#define USE_SETJMP
+
+#ifndef _PR_PTHREADS
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/* balazs.pataki@sztaki.hu:
+** __sparc__ is checked
+** __m68k__ is checked
+** __i386__ is a guess (one of the two defines should work)
+*/
+#if defined(__sparc__)
+#define _MD_GET_SP(_th)		(_th)->md.context[2]
+#elif defined(__m68k__)
+#define _MD_GET_SP(_th)		(_th)->md.context[2]
+#elif defined(__i386__)
+/* One of this two must be OK ... try using sc_onstack
+*/
+#define _MD_GET_SP(_th)    (((struct sigcontext *) (_th)->md.context)->sc_onstack)
+//#define _MD_GET_SP(_th)		(_th)->md.context[0].sc_esp
+#else
+error Unknown NEXTSTEP architecture
+#endif
+
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (setjmp(CONTEXT(_thread))) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    longjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+extern void _MD_EarlyInit(void);
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+/* For writev() */
+#include <sys/uio.h>
+
+/* signal.h */
+/* 	balazs.pataki@sztaki.hu: this is stolen from sunos4.h. The things is that
+** 	NEXTSTEP doesn't support these flags for `struct sigaction's sa_flags, so
+**	I have to fake them ...
+*/
+#define SA_RESTART 0
+
+/* mmap */
+/* 	balazs.pataki@sztaki.hu: NEXTSTEP doesn't have mmap, at least not 
+**	publically. We have sys/mman.h, but it doesn't declare mmap(), and
+**	PROT_NONE is also missing. syscall.h has entries for mmap, munmap, and 
+**	mprotect so I wrap these in nextstep.c as  mmap(), munmap() and mprotect()
+**	and pray for it to work.
+**	
+*/
+caddr_t mmap(caddr_t addr, size_t len, int prot, int flags,
+          int fildes, off_t off);
+int munmap(caddr_t addr, size_t len);
+int mprotect(caddr_t addr, size_t len, int prot);
+
+/*	my_mmap() is implemented in nextstep.c and is based on map_fd() of mach.
+*/
+caddr_t my_mmap(caddr_t addr, size_t len, int prot, int flags,
+          int fildes, off_t off);
+int my_munmap(caddr_t addr, size_t len);
+
+
+/*	string.h
+*/
+/* balazs.pataki@sztaki.hu: this is missing so implemenetd in nextstep.c ...
+*/
+char *strdup(const char *s1);
+
+/* unistd.h
+*/
+/* 	balazs.pataki@sztaki.hu: these functions are hidden, though correctly 
+**	implemented in NEXTSTEP. Here I give the declaration for them to be used
+**	by prmalloc.c, and I have a wrapped syscall() version of them in nextstep.c
+*/
+int brk(void *endds);
+void *sbrk(int incr);
+
+#endif /* nspr_nextstep_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nspr_pthread.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nspr_pthread.h
new file mode 100644
index 0000000..b7a0481
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nspr_pthread.h
@@ -0,0 +1,283 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_pthread_defs_h___
+#define nspr_pthread_defs_h___
+
+#include <pthread.h>
+#include "prthread.h"
+
+#if defined(PTHREADS_USER)
+/*
+** Thread Local Storage 
+*/
+extern pthread_key_t current_thread_key;
+extern pthread_key_t current_cpu_key;
+extern pthread_key_t last_thread_key;
+extern pthread_key_t intsoff_key;
+
+#define _MD_CURRENT_THREAD() 			\
+			((struct PRThread *) pthread_getspecific(current_thread_key))
+#define _MD_CURRENT_CPU() 				\
+			((struct _PRCPU *) pthread_getspecific(current_cpu_key))
+#define _MD_LAST_THREAD()				\
+			((struct PRThread *) pthread_getspecific(last_thread_key))
+	
+#define _MD_SET_CURRENT_THREAD(newval) 			\
+	pthread_setspecific(current_thread_key, (void *)newval)
+
+#define _MD_SET_CURRENT_CPU(newval) 			\
+	pthread_setspecific(current_cpu_key, (void *)newval)
+
+#define _MD_SET_LAST_THREAD(newval)	 			\
+	pthread_setspecific(last_thread_key, (void *)newval)
+
+#define _MD_SET_INTSOFF(_val)
+#define _MD_GET_INTSOFF()	1
+	
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+    PR_BEGIN_MACRO				      							\
+        *status = PR_TRUE;              						\
+		if (SAVE_CONTEXT(_thread)) {							\
+	    	(*_main)();											\
+		}														\
+		_MD_SET_THR_SP(_thread, _sp);							\
+		_thread->no_sched = 0; 									\
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread)  								\
+    PR_BEGIN_MACRO 													\
+	PR_ASSERT(_thread->no_sched);									\
+	if (!SAVE_CONTEXT(_thread)) {									\
+		(_thread)->md.errcode = errno;  							\
+		_MD_SET_LAST_THREAD(_thread);								\
+		_PR_Schedule();		     									\
+    } else {														\
+		 (_MD_LAST_THREAD())->no_sched = 0;							\
+	}																\
+    PR_END_MACRO
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)								\
+    PR_BEGIN_MACRO 													\
+    errno = (_thread)->md.errcode; 									\
+    _MD_SET_CURRENT_THREAD(_thread); 								\
+	_thread->no_sched = 1;											\
+    GOTO_CONTEXT(_thread); 											\
+    PR_END_MACRO
+
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    jmp_buf 		jb;
+    int				id;
+    int				errcode;
+	pthread_t		pthread;
+	pthread_mutex_t	pthread_mutex;
+	pthread_cond_t	pthread_cond;
+	int				wait;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+	pthread_mutex_t mutex;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+	pthread_mutex_t mutex;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    jmp_buf 			jb;
+	pthread_t 			pthread;
+	struct _MDCPU_Unix 	md_unix;
+};
+
+/*
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+*/
+
+extern pthread_mutex_t _pr_heapLock;
+
+#define _PR_LOCK(lock) pthread_mutex_lock(lock)
+
+#define _PR_UNLOCK(lock) pthread_mutex_unlock(lock)
+
+
+#define _PR_LOCK_HEAP()	{									\
+				if (_pr_primordialCPU) {					\
+					_PR_LOCK(_pr_heapLock);					\
+				}
+
+#define _PR_UNLOCK_HEAP() 	if (_pr_primordialCPU)	{		\
+					_PR_UNLOCK(_pr_heapLock);				\
+				}											\
+			  }
+
+NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md);
+NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp);
+
+#define _MD_LOCK(_lockp) _PR_LOCK(&(_lockp)->mutex)
+#define _MD_UNLOCK(_lockp) _PR_UNLOCK(&(_lockp)->mutex)
+
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+#define _MD_CHECK_FOR_EXIT()
+
+NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread);
+#define _MD_INIT_THREAD _MD_InitThread
+#define _MD_INIT_ATTACHED_THREAD _MD_InitThread
+
+NSPR_API(void) _MD_ExitThread(struct PRThread *thread);
+#define _MD_EXIT_THREAD _MD_ExitThread
+
+NSPR_API(void) _MD_SuspendThread(struct PRThread *thread);
+#define _MD_SUSPEND_THREAD _MD_SuspendThread
+
+NSPR_API(void) _MD_ResumeThread(struct PRThread *thread);
+#define _MD_RESUME_THREAD _MD_ResumeThread
+
+NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread);
+#define _MD_SUSPEND_CPU _MD_SuspendCPU
+
+NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread);
+#define _MD_RESUME_CPU _MD_ResumeCPU
+
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_RESUME_ALL()
+
+NSPR_API(void) _MD_EarlyInit(void);
+#define _MD_EARLY_INIT _MD_EarlyInit
+
+#define _MD_FINAL_INIT _PR_UnixInit
+
+NSPR_API(void) _MD_InitLocks(void);
+#define _MD_INIT_LOCKS _MD_InitLocks
+
+NSPR_API(void) _MD_CleanThread(struct PRThread *thread);
+#define _MD_CLEAN_THREAD _MD_CleanThread
+
+NSPR_API(PRStatus) _MD_CreateThread(
+                        struct PRThread *thread,
+                        void (*start) (void *),
+                        PRThreadPriority priority,
+                        PRThreadScope scope,
+                        PRThreadState state,
+                        PRUint32 stackSize);
+#define _MD_CREATE_THREAD _MD_CreateThread
+
+extern void _MD_CleanupBeforeExit(void);
+#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
+
+NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu);
+#define    _MD_INIT_RUNNING_CPU _MD_InitRunningCPU
+
+/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
+ * awaken a thread which is waiting on a lock or cvar.
+ */
+NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout);
+#define _MD_WAIT _MD_wait
+
+NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *);
+#define _MD_WAKEUP_WAITER _MD_WakeupWaiter
+
+NSPR_API(void) _MD_SetPriority(struct _MDThread *thread,
+	PRThreadPriority newPri);
+#define _MD_SET_PRIORITY _MD_SetPriority
+
+#endif /* PTHREADS_USER */
+
+#endif /* nspr_pthread_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nto.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nto.cfg
new file mode 100644
index 0000000..b664b7f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nto.cfg
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NTO
+#define NTO
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#ifdef __i386__
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#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
+#define PR_BYTES_PER_DWORD  8L
+
+#define PR_BITS_PER_BYTE    8L
+#define PR_BITS_PER_SHORT   16L
+#define PR_BITS_PER_INT     32L
+#define PR_BITS_PER_INT64   64L
+#define PR_BITS_PER_LONG    32L
+#define PR_BITS_PER_FLOAT   32L
+#define PR_BITS_PER_DOUBLE  64L
+#define PR_BITS_PER_WORD    32L
+
+#define PR_BITS_PER_BYTE_LOG2   3L
+#define PR_BITS_PER_SHORT_LOG2  4L
+#define PR_BITS_PER_INT_LOG2    5L
+#define PR_BITS_PER_INT64_LOG2  6L
+#define PR_BITS_PER_LONG_LOG2   5L
+#define PR_BITS_PER_FLOAT_LOG2  5L
+#define PR_BITS_PER_DOUBLE_LOG2 6L
+#define PR_BITS_PER_WORD_LOG2   5L
+
+#define PR_ALIGN_OF_SHORT   2L
+#define PR_ALIGN_OF_INT     4L
+#define PR_ALIGN_OF_LONG    4L
+#define PR_ALIGN_OF_INT64   4L
+#define PR_ALIGN_OF_FLOAT   4L
+#define PR_ALIGN_OF_DOUBLE  4L
+#define PR_ALIGN_OF_POINTER 4L
+#define PR_ALIGN_OF_WORD    4L
+
+#define PR_BYTES_PER_WORD_LOG2   2L
+#define PR_BYTES_PER_DWORD_LOG2  3L
+#define PR_WORDS_PER_DWORD_LOG2  1L
+
+#else
+
+#error Undefined CPU Architecture
+
+#endif
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nto.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nto.h
new file mode 100644
index 0000000..97f4d38
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_nto.h
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_nto_defs_h___
+#define nspr_nto_defs_h___
+
+/*
+** Internal configuration macros
+*/
+#define PR_LINKER_ARCH		"nto"
+#define _PR_SI_SYSNAME		"NTO"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MINIMUM_STACK_SIZE	131072L
+#define _MD_MMAP_FLAGS		MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef  _PR_POLL_AVAILABLE
+#undef  _PR_USE_POLL
+#define _PR_HAVE_SOCKADDR_LEN
+#undef  HAVE_BSD_FLOCK
+#define HAVE_FCNTL_FILE_LOCKING
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_HAVE_POSIX_SEMAPHORES
+
+#undef FD_SETSIZE
+#define FD_SETSIZE	4096
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+
+#undef  HAVE_STACK_GROWING_UP
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR
+#endif
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP			setjmp
+#define _LONGJMP		longjmp
+#define _PR_CONTEXT_TYPE	jmp_buf
+#define _PR_NUM_GCREGS		_JBLEN
+#define _MD_GET_SP(_t)		(_t)->md.context[7]
+
+#define CONTEXT(_th)		((_th)->md.context)
+
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	\
+{							\
+    *status = PR_TRUE;					\
+    if(_SETJMP(CONTEXT(_thread))) (*_main)();		\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128);		\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)	\
+    if (!_SETJMP(CONTEXT(_thread))) {	\
+	(_thread)->md.errcode = errno;	\
+	_PR_Schedule();			\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)	\
+{					\
+    errno = (_thread)->md.errcode;	\
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    _LONGJMP(CONTEXT(_thread), 1);	\
+}
+
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** md-specific cpu structure field
+*/
+#define _PR_MD_MAX_OSFD		FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu)	PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock)		PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_GET_INTERVAL		_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC		_PR_UNIX_TicksPerSecond
+#define _MD_EARLY_INIT			_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+** We wrapped the select() call.  _MD_SELECT refers to the built-in,
+** unwrapped version.
+*/
+#define _MD_SELECT		select
+
+#define SA_RESTART 0
+
+#endif /* nspr_nto_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_openbsd.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_openbsd.cfg
new file mode 100644
index 0000000..dbd7b54
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_openbsd.cfg
@@ -0,0 +1,385 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef OPENBSD
+#define OPENBSD
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+
+#if defined(__i386__) || defined(__arm__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__amd64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+
+#elif defined(__sparc_v9__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__sparc__)
+
+#undef IS_LITTLE_ENDIAN
+#define  IS_BIG_ENDIAN 1
+#define  HAVE_ALIGNED_DOUBLES
+#define  HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__alpha__)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__powerpc__) || defined(__m68k__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN    1
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error Must define constants for type sizes here.
+
+#endif
+
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_openbsd.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_openbsd.h
new file mode 100644
index 0000000..8dd4409
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_openbsd.h
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_openbsd_defs_h___
+#define nspr_openbsd_defs_h___
+
+#include <sys/syscall.h>
+
+#define PR_LINKER_ARCH	"openbsd"
+#define _PR_SI_SYSNAME  "OPENBSD"
+#if defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__alpha__)
+#define _PR_SI_ARCHITECTURE "alpha"
+#elif defined(__amd64__)
+#define _PR_SI_ARCHITECTURE "amd64"
+#elif defined(__m68k__)
+#define _PR_SI_ARCHITECTURE "m68k"
+#elif defined(__powerpc__)
+#define _PR_SI_ARCHITECTURE "powerpc"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__arm__)
+#define _PR_SI_ARCHITECTURE "arm"
+#endif
+
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_HAVE_LARGE_OFF_T
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+
+#define USE_SETJMP
+
+#ifndef _PR_PTHREADS
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#if defined(__i386__) || defined(__sparc__) || defined(__m68k__)
+#define JB_SP_INDEX 2
+#elif defined(__powerpc__)
+#define JB_SP_INDEX 1
+#elif defined(__alpha__)
+#define JB_SP_INDEX 34
+#elif defined(__amd64__)
+#define JB_SP_INDEX 6
+#elif defined(__arm__)
+#define JB_SP_INDEX 23
+#else
+#error "Need to define SP index in jmp_buf here"
+#endif
+#define _MD_GET_SP(_th)    (_th)->md.context[JB_SP_INDEX]
+
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!sigsetjmp(CONTEXT(_thread), 1)) {  \
+        (_thread)->md.errcode = errno;  \
+        _PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    siglongjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+#endif /* ! _PR_PTHREADS */
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+#include <poll.h>
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+
+#if OpenBSD1_3 == 1L
+typedef unsigned int nfds_t;
+#endif
+
+#endif /* nspr_openbsd_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2.cfg
new file mode 100644
index 0000000..950f8ed
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2.cfg
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_PC
+#define XP_PC
+#endif
+
+#ifndef XP_OS2
+#define XP_OS2
+#endif
+
+#ifndef OS2
+#define OS2
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#ifdef NO_LONG_LONG
+#undef HAVE_LONG_LONG
+#else
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG 1
+#endif
+#endif
+
+#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
+#define PR_BYTES_PER_DWORD	8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	32
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	5
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_WORD	4
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2	2
+#define PR_BYTES_PER_DWORD_LOG2	2
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE      PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT     PR_BYTES_PER_SHORT
+#define BYTES_PER_INT       PR_BYTES_PER_INT
+#define BYTES_PER_INT64     PR_BYTES_PER_INT64
+#define BYTES_PER_LONG      PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT     PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE    PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD      PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD     PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE       PR_BITS_PER_BYTE
+#define BITS_PER_SHORT      PR_BITS_PER_SHORT
+#define BITS_PER_INT        PR_BITS_PER_INT
+#define BITS_PER_INT64      PR_BITS_PER_INT64
+#define BITS_PER_LONG       PR_BITS_PER_LONG
+#define BITS_PER_FLOAT      PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE     PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD       PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2  PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2   PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2  PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2    PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2  PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT      PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT        PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG       PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64      PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT      PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE     PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER    PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD       PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2		PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2    PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2    PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2.h
new file mode 100644
index 0000000..befb51d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2.h
@@ -0,0 +1,536 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_os2_defs_h___
+#define nspr_os2_defs_h___
+
+#ifndef NO_LONG_LONG
+#define INCL_LONGLONG
+#endif
+#define INCL_DOS
+#define INCL_DOSPROCESS
+#define INCL_DOSERRORS
+#define INCL_WIN
+#define INCL_WPS
+#include <os2.h>
+#include <sys/select.h>
+
+#include "prio.h"
+
+#include <errno.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH      "os2"
+#define _PR_SI_SYSNAME        "OS2"
+#define _PR_SI_ARCHITECTURE   "x86"    /* XXXMB hardcode for now */
+
+#define HAVE_DLL
+#define _PR_GLOBAL_THREADS_ONLY
+#undef  HAVE_THREAD_AFFINITY
+#define _PR_HAVE_THREADSAFE_GETHOST
+#define _PR_HAVE_ATOMIC_OPS
+#define HAVE_NETINET_TCP_H
+
+#define HANDLE unsigned long
+#define HINSTANCE HMODULE
+
+/* --- Common User-Thread/Native-Thread Definitions --------------------- */
+
+/* --- Globals --- */
+extern struct PRLock                      *_pr_schedLock;
+
+/* --- Typedefs --- */
+typedef void (*FiberFunc)(void *);
+
+#define PR_NUM_GCREGS           8
+typedef PRInt32	                PR_CONTEXT_TYPE[PR_NUM_GCREGS];
+#define GC_VMBASE               0x40000000
+#define GC_VMLIMIT              0x00FFFFFF
+typedef int (*FARPROC)();
+
+#define _MD_MAGIC_THREAD	0x22222222
+#define _MD_MAGIC_THREADSTACK	0x33333333
+#define _MD_MAGIC_SEGMENT	0x44444444
+#define _MD_MAGIC_DIR		0x55555555
+#define _MD_MAGIC_CV        0x66666666
+
+struct _MDSemaphore {
+   HEV sem;
+};
+
+struct _MDCPU {
+    int              unused;
+}; 
+
+struct _MDThread {
+    HEV              blocked_sema;      /* Threads block on this when waiting
+                                         * for IO or CondVar.
+                                         */
+    PRBool           inCVWaitQueue;     /* PR_TRUE if the thread is in the
+                                         * wait queue of some cond var.
+                                         * PR_FALSE otherwise.  */
+    TID              handle;            /* OS/2 thread handle */
+    void            *sp;                /* only valid when suspended */
+    PRUint32         magic;             /* for debugging */
+    PR_CONTEXT_TYPE  gcContext;         /* Thread context for GC */
+    struct PRThread *prev, *next;       /* used by the cvar wait queue to
+                                         * chain the PRThread structures
+                                         * together */
+};
+
+struct _MDThreadStack {
+    PRUint32           magic;          /* for debugging */
+};
+
+struct _MDSegment {
+    PRUint32           magic;          /* for debugging */
+};
+
+#undef PROFILE_LOCKS
+
+struct _MDDir {
+    HDIR           d_hdl;
+    union {
+        FILEFINDBUF3  small;
+        FILEFINDBUF3L large;
+    } d_entry;
+    PRBool           firstEntry;     /* Is this the entry returned
+                                      * by FindFirstFile()? */
+    PRUint32         magic;          /* for debugging */
+};
+
+struct _MDCVar {
+    PRUint32 magic;
+    struct PRThread *waitHead, *waitTail;  /* the wait queue: a doubly-
+                                            * linked list of threads
+                                            * waiting on this condition
+                                            * variable */
+    PRIntn nwait;                          /* number of threads in the
+                                            * wait queue */
+};
+
+#define _MD_CV_NOTIFIED_LENGTH 6
+typedef struct _MDNotified _MDNotified;
+struct _MDNotified {
+    PRIntn length;                     /* # of used entries in this
+                                        * structure */
+    struct {
+        struct _MDCVar *cv;            /* the condition variable notified */
+        PRIntn times;                  /* and the number of times notified */
+        struct PRThread *notifyHead;   /* list of threads to wake up */
+    } cv[_MD_CV_NOTIFIED_LENGTH];
+    _MDNotified *link;                 /* link to another of these, or NULL */
+};
+
+struct _MDLock {
+    HMTX mutex;                        /* this is recursive on OS/2 */
+
+    /*
+     * When notifying cvars, there is no point in actually
+     * waking up the threads waiting on the cvars until we've
+     * released the lock.  So, we temporarily record the cvars.
+     * When doing an unlock, we'll then wake up the waiting threads.
+     */
+    struct _MDNotified notified;     /* array of conditions notified */
+#ifdef PROFILE_LOCKS
+    PRInt32 hitcount;
+    PRInt32 misscount;
+#endif
+};
+
+struct _MDFileDesc {
+    PRInt32 osfd;    /* The osfd can come from one of three spaces:
+                      * - For stdin, stdout, and stderr, we are using
+                      *   the libc file handle (0, 1, 2), which is an int.
+                      * - For files and pipes, we are using OS/2 handles,
+                      *   which is a void*.
+                      * - For sockets, we are using int
+                      */
+};
+
+struct _MDProcess {
+   PID pid;
+};
+
+/* --- Misc stuff --- */
+#define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
+
+/* --- IO stuff --- */
+
+#define _MD_OPEN                      (_PR_MD_OPEN)
+#define _MD_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... */
+#define _MD_EACCES                EACCES
+#define _MD_EADDRINUSE            EADDRINUSE
+#define _MD_EADDRNOTAVAIL         EADDRNOTAVAIL
+#define _MD_EAFNOSUPPORT          EAFNOSUPPORT
+#define _MD_EAGAIN                EWOULDBLOCK
+#define _MD_EALREADY              EALREADY
+#define _MD_EBADF                 EBADF
+#define _MD_ECONNREFUSED          ECONNREFUSED
+#define _MD_ECONNRESET            ECONNRESET
+#define _MD_EFAULT                SOCEFAULT
+#define _MD_EINPROGRESS           EINPROGRESS
+#define _MD_EINTR                 EINTR
+#define _MD_EINVAL                EINVAL
+#define _MD_EISCONN               EISCONN
+#define _MD_ENETUNREACH           ENETUNREACH
+#define _MD_ENOENT                ENOENT
+#define _MD_ENOTCONN              ENOTCONN
+#define _MD_ENOTSOCK              ENOTSOCK
+#define _MD_EOPNOTSUPP            EOPNOTSUPP
+#define _MD_EWOULDBLOCK           EWOULDBLOCK
+#define _MD_GET_SOCKET_ERROR()    sock_errno()
+#ifndef INADDR_LOOPBACK /* For some reason this is not defined in OS2 tcpip */
+/*  #define INADDR_LOOPBACK         INADDR_ANY */
+#endif  
+
+#define _MD_INIT_FILEDESC(fd)
+extern void _MD_MakeNonblock(PRFileDesc *f);
+#define _MD_MAKE_NONBLOCK             _MD_MakeNonblock
+#define _MD_INIT_FD_INHERITABLE       (_PR_MD_INIT_FD_INHERITABLE)
+#define _MD_QUERY_FD_INHERITABLE      (_PR_MD_QUERY_FD_INHERITABLE)
+#define _MD_SHUTDOWN                  (_PR_MD_SHUTDOWN)
+#define _MD_LISTEN                    _PR_MD_LISTEN
+extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
+#define _MD_CLOSE_SOCKET              _MD_CloseSocket
+#define _MD_SENDTO                    (_PR_MD_SENDTO)
+#define _MD_RECVFROM                  (_PR_MD_RECVFROM)
+#define _MD_SOCKETPAIR                (_PR_MD_SOCKETPAIR)
+#define _MD_GETSOCKNAME               (_PR_MD_GETSOCKNAME)
+#define _MD_GETPEERNAME               (_PR_MD_GETPEERNAME)
+#define _MD_GETSOCKOPT                (_PR_MD_GETSOCKOPT)
+#define _MD_SETSOCKOPT                (_PR_MD_SETSOCKOPT)
+
+#define _MD_FSYNC                     _PR_MD_FSYNC
+#define _MD_SET_FD_INHERITABLE        (_PR_MD_SET_FD_INHERITABLE)
+
+#ifdef _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT          _PR_MD_ATOMIC_INCREMENT
+#define _MD_ATOMIC_ADD                _PR_MD_ATOMIC_ADD
+#define _MD_ATOMIC_DECREMENT          _PR_MD_ATOMIC_DECREMENT
+#define _MD_ATOMIC_SET                _PR_MD_ATOMIC_SET
+#endif
+
+#define _MD_INIT_IO                   (_PR_MD_INIT_IO)
+#define _MD_PR_POLL                   (_PR_MD_PR_POLL)
+
+#define _MD_SOCKET                    (_PR_MD_SOCKET)
+extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd);
+#define _MD_SOCKETAVAILABLE           _MD_SocketAvailable
+#define _MD_PIPEAVAILABLE             _MD_SocketAvailable
+#define _MD_CONNECT                   (_PR_MD_CONNECT)
+extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
+        PRIntervalTime timeout);
+#define _MD_ACCEPT                    _MD_Accept
+#define _MD_BIND                      (_PR_MD_BIND)
+#define _MD_RECV                      (_PR_MD_RECV)
+#define _MD_SEND                      (_PR_MD_SEND)
+
+/* --- Scheduler stuff --- */
+/* #define _MD_PAUSE_CPU                 _PR_MD_PAUSE_CPU */
+#define _MD_PAUSE_CPU
+
+/* --- DIR stuff --- */
+#define PR_DIRECTORY_SEPARATOR        '\\'
+#define PR_DIRECTORY_SEPARATOR_STR    "\\"
+#define PR_PATH_SEPARATOR		';'
+#define PR_PATH_SEPARATOR_STR		";"
+#define _MD_ERRNO()                   errno
+#define _MD_OPEN_DIR                  (_PR_MD_OPEN_DIR)
+#define _MD_CLOSE_DIR                 (_PR_MD_CLOSE_DIR)
+#define _MD_READ_DIR                  (_PR_MD_READ_DIR)
+
+/* --- Segment stuff --- */
+#define _MD_INIT_SEGS()
+#define _MD_ALLOC_SEGMENT(seg, size, vaddr)   0
+#define _MD_FREE_SEGMENT(seg)
+
+/* --- Environment Stuff --- */
+#define _MD_GET_ENV                 (_PR_MD_GET_ENV)
+#define _MD_PUT_ENV                 (_PR_MD_PUT_ENV)
+
+/* --- Threading Stuff --- */
+#define _MD_DEFAULT_STACK_SIZE      65536L
+#define _MD_INIT_THREAD             (_PR_MD_INIT_THREAD)
+#define _MD_INIT_ATTACHED_THREAD    (_PR_MD_INIT_THREAD)
+#define _MD_CREATE_THREAD           (_PR_MD_CREATE_THREAD)
+#define _MD_YIELD                   (_PR_MD_YIELD)
+#define _MD_SET_PRIORITY            (_PR_MD_SET_PRIORITY)
+#define _MD_CLEAN_THREAD            (_PR_MD_CLEAN_THREAD)
+#define _MD_SETTHREADAFFINITYMASK   (_PR_MD_SETTHREADAFFINITYMASK)
+#define _MD_GETTHREADAFFINITYMASK   (_PR_MD_GETTHREADAFFINITYMASK)
+#define _MD_EXIT_THREAD             (_PR_MD_EXIT_THREAD)
+#define _MD_SUSPEND_THREAD          (_PR_MD_SUSPEND_THREAD)
+#define _MD_RESUME_THREAD           (_PR_MD_RESUME_THREAD)
+#define _MD_SUSPEND_CPU             (_PR_MD_SUSPEND_CPU)
+#define _MD_RESUME_CPU              (_PR_MD_RESUME_CPU)
+#define _MD_WAKEUP_CPUS             (_PR_MD_WAKEUP_CPUS)
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_END_RESUME_ALL()
+
+/* --- Lock stuff --- */
+#define _PR_LOCK                      _MD_LOCK
+#define _PR_UNLOCK					  _MD_UNLOCK
+
+#define _MD_NEW_LOCK                  (_PR_MD_NEW_LOCK)
+#define _MD_FREE_LOCK(lock)           (DosCloseMutexSem((lock)->mutex))
+#define _MD_LOCK(lock)                (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT))
+#define _MD_TEST_AND_LOCK(lock)       (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0)
+#define _MD_UNLOCK                    (_PR_MD_UNLOCK)
+
+/* --- lock and cv waiting --- */
+#define _MD_WAIT                      (_PR_MD_WAIT)
+#define _MD_WAKEUP_WAITER             (_PR_MD_WAKEUP_WAITER)
+
+/* --- CVar ------------------- */
+#define _MD_WAIT_CV					  (_PR_MD_WAIT_CV)
+#define _MD_NEW_CV					  (_PR_MD_NEW_CV)
+#define _MD_FREE_CV					  (_PR_MD_FREE_CV)
+#define _MD_NOTIFY_CV				  (_PR_MD_NOTIFY_CV	)
+#define _MD_NOTIFYALL_CV			  (_PR_MD_NOTIFYALL_CV)
+
+   /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
+/* extern  struct _MDLock              _pr_ioq_lock; */
+#define _MD_IOQ_LOCK()                
+#define _MD_IOQ_UNLOCK()              
+
+
+/* --- Initialization stuff --- */
+#define _MD_START_INTERRUPTS()
+#define _MD_STOP_INTERRUPTS()
+#define _MD_DISABLE_CLOCK_INTERRUPTS()
+#define _MD_ENABLE_CLOCK_INTERRUPTS()
+#define _MD_BLOCK_CLOCK_INTERRUPTS()
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _MD_EARLY_INIT                (_PR_MD_EARLY_INIT)
+#define _MD_FINAL_INIT()
+#define _MD_EARLY_CLEANUP()
+#define _MD_INIT_CPUS()
+#define _MD_INIT_RUNNING_CPU(cpu)
+
+struct PRProcess;
+struct PRProcessAttr;
+
+#define _MD_CREATE_PROCESS _PR_CreateOS2Process
+extern struct PRProcess * _PR_CreateOS2Process(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _PR_DetachOS2Process
+extern PRStatus _PR_DetachOS2Process(struct PRProcess *process);
+
+/* --- Wait for a child process to terminate --- */
+#define _MD_WAIT_PROCESS _PR_WaitOS2Process
+extern PRStatus _PR_WaitOS2Process(struct PRProcess *process, 
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _PR_KillOS2Process
+extern PRStatus _PR_KillOS2Process(struct PRProcess *process);
+
+#define _MD_CLEANUP_BEFORE_EXIT()
+#define _MD_EXIT                          (_PR_MD_EXIT)
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+    PR_BEGIN_MACRO \
+    *status = PR_TRUE; \
+    PR_END_MACRO
+#define _MD_SWITCH_CONTEXT
+#define _MD_RESTORE_CONTEXT
+
+/* --- Intervals --- */
+#define _MD_INTERVAL_INIT                 (_PR_MD_INTERVAL_INIT)
+#define _MD_GET_INTERVAL                  (_PR_MD_GET_INTERVAL)
+#define _MD_INTERVAL_PER_SEC              (_PR_MD_INTERVAL_PER_SEC)
+#define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/* --- Native-Thread Specific Definitions ------------------------------- */
+
+typedef struct __NSPR_TLS
+{
+    struct PRThread  *_pr_thread_last_run;
+    struct PRThread  *_pr_currentThread;
+    struct _PRCPU    *_pr_currentCPU;
+} _NSPR_TLS;
+
+extern _NSPR_TLS*  pThreadLocalStorage;
+NSPR_API(void) _PR_MD_ENSURE_TLS(void);
+
+#define _MD_GET_ATTACHED_THREAD() pThreadLocalStorage->_pr_currentThread
+extern struct PRThread * _MD_CURRENT_THREAD(void);
+#define _MD_SET_CURRENT_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentThread = (_thread)
+
+#define _MD_LAST_THREAD() pThreadLocalStorage->_pr_thread_last_run
+#define _MD_SET_LAST_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_thread_last_run = (_thread)
+
+#define _MD_CURRENT_CPU() pThreadLocalStorage->_pr_currentCPU
+#define _MD_SET_CURRENT_CPU(_cpu) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentCPU = (_cpu)
+
+/* lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) */
+/* lth. #define _MD_GET_INTSOFF() _pr_ints_off */
+/* lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++) */
+/* lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--) */
+
+/* --- Scheduler stuff --- */
+#define LOCK_SCHEDULER()                 0
+#define UNLOCK_SCHEDULER()               0
+#define _PR_LockSched()                	 0
+#define _PR_UnlockSched()                0
+
+/* --- Initialization stuff --- */
+#define _MD_INIT_LOCKS()
+
+/* --- Stack stuff --- */
+#define _MD_INIT_STACK(stack, redzone)
+#define _MD_CLEAR_STACK(stack)
+
+/* --- Memory-mapped files stuff --- */
+/* ReadOnly and WriteCopy modes are simulated on OS/2;
+ * ReadWrite mode is not supported.
+ */
+struct _MDFileMap {
+    PROffset64  maxExtent;
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+extern PRInt32 _MD_GetMemMapAlignment(void);
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+/* Some stuff for setting up thread contexts */
+typedef ULONG DWORD, *PDWORD;
+
+/* The following definitions and two structures are new in OS/2 Warp 4.0.
+ */
+#ifndef CONTEXT_CONTROL
+#define CONTEXT_CONTROL        0x00000001
+#define CONTEXT_INTEGER        0x00000002
+#define CONTEXT_SEGMENTS       0x00000004
+#define CONTEXT_FLOATING_POINT 0x00000008
+#define CONTEXT_FULL           0x0000000F
+
+#pragma pack(2)
+typedef struct _FPREG {
+    ULONG      losig;    /*  Low 32-bits of the significand. */
+    ULONG      hisig;    /*  High 32-bits of the significand. */
+    USHORT     signexp;  /*  Sign and exponent. */
+} FPREG;
+typedef struct _CONTEXTRECORD {
+    ULONG     ContextFlags;
+    ULONG     ctx_env[7];
+    FPREG     ctx_stack[8];
+    ULONG     ctx_SegGs;     /*  GS register. */
+    ULONG     ctx_SegFs;     /*  FS register. */
+    ULONG     ctx_SegEs;     /*  ES register. */
+    ULONG     ctx_SegDs;     /*  DS register. */
+    ULONG     ctx_RegEdi;    /*  EDI register. */
+    ULONG     ctx_RegEsi;    /*  ESI register. */
+    ULONG     ctx_RegEax;    /*  EAX register. */
+    ULONG     ctx_RegEbx;    /*  EBX register. */
+    ULONG     ctx_RegEcx;    /*  ECX register. */
+    ULONG     ctx_RegEdx;    /*  EDX register. */
+    ULONG     ctx_RegEbp;    /*  EBP register. */
+    ULONG     ctx_RegEip;    /*  EIP register. */
+    ULONG     ctx_SegCs;     /*  CS register. */
+    ULONG     ctx_EFlags;    /*  EFLAGS register. */
+    ULONG     ctx_RegEsp;    /*  ESP register. */
+    ULONG     ctx_SegSs;     /*  SS register. */
+} CONTEXTRECORD, *PCONTEXTRECORD;
+#pragma pack()
+#endif
+
+extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
+
+/*
+#define _pr_tid            (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid)
+#define _pr_current_Thread (_system_tls[_pr_tid-1].__pr_current_thread)
+*/
+
+/* Some simple mappings of Windows API's to OS/2 API's to make our lives a
+ * little bit easier.  Only add one here if it is a DIRECT mapping.  We are
+ * not emulating anything.  Just mapping.
+ */
+#define FreeLibrary(x) DosFreeModule((HMODULE)x)
+#define OutputDebugStringA(x)
+                               
+extern int _MD_os2_get_nonblocking_connect_error(int osfd);
+
+#endif /* nspr_os2_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2_errors.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2_errors.h
new file mode 100644
index 0000000..e3a2500
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_os2_errors.h
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_os2_errors_h___
+#define nspr_os2_errors_h___
+
+#include "md/_os2.h"
+#ifndef assert
+  #include <assert.h>
+#endif  
+
+NSPR_API(void) _MD_os2_map_default_error(PRInt32 err);
+#define	_PR_MD_MAP_DEFAULT_ERROR	_MD_os2_map_default_error
+
+NSPR_API(void) _MD_os2_map_opendir_error(PRInt32 err);
+#define	_PR_MD_MAP_OPENDIR_ERROR	_MD_os2_map_opendir_error
+
+NSPR_API(void) _MD_os2_map_closedir_error(PRInt32 err);
+#define	_PR_MD_MAP_CLOSEDIR_ERROR	_MD_os2_map_closedir_error
+
+NSPR_API(void) _MD_os2_readdir_error(PRInt32 err);
+#define	_PR_MD_MAP_READDIR_ERROR	_MD_os2_readdir_error
+
+NSPR_API(void) _MD_os2_map_delete_error(PRInt32 err);
+#define	_PR_MD_MAP_DELETE_ERROR	_MD_os2_map_delete_error
+
+NSPR_API(void) _MD_os2_map_stat_error(PRInt32 err);
+#define	_PR_MD_MAP_STAT_ERROR	_MD_os2_map_stat_error
+
+NSPR_API(void) _MD_os2_map_fstat_error(PRInt32 err);
+#define	_PR_MD_MAP_FSTAT_ERROR	_MD_os2_map_fstat_error
+
+NSPR_API(void) _MD_os2_map_rename_error(PRInt32 err);
+#define	_PR_MD_MAP_RENAME_ERROR	_MD_os2_map_rename_error
+
+NSPR_API(void) _MD_os2_map_access_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCESS_ERROR	_MD_os2_map_access_error
+
+NSPR_API(void) _MD_os2_map_mkdir_error(PRInt32 err);
+#define	_PR_MD_MAP_MKDIR_ERROR	_MD_os2_map_mkdir_error
+
+NSPR_API(void) _MD_os2_map_rmdir_error(PRInt32 err);
+#define	_PR_MD_MAP_RMDIR_ERROR	_MD_os2_map_rmdir_error
+
+NSPR_API(void) _MD_os2_map_read_error(PRInt32 err);
+#define	_PR_MD_MAP_READ_ERROR	_MD_os2_map_read_error
+
+NSPR_API(void) _MD_os2_map_transmitfile_error(PRInt32 err);
+#define	_PR_MD_MAP_TRANSMITFILE_ERROR	_MD_os2_map_transmitfile_error
+
+NSPR_API(void) _MD_os2_map_write_error(PRInt32 err);
+#define	_PR_MD_MAP_WRITE_ERROR	_MD_os2_map_write_error
+
+NSPR_API(void) _MD_os2_map_lseek_error(PRInt32 err);
+#define	_PR_MD_MAP_LSEEK_ERROR	_MD_os2_map_lseek_error
+
+NSPR_API(void) _MD_os2_map_fsync_error(PRInt32 err);
+#define	_PR_MD_MAP_FSYNC_ERROR	_MD_os2_map_fsync_error
+
+NSPR_API(void) _MD_os2_map_close_error(PRInt32 err);
+#define	_PR_MD_MAP_CLOSE_ERROR	_MD_os2_map_close_error
+
+NSPR_API(void) _MD_os2_map_socket_error(PRInt32 err);
+#define	_PR_MD_MAP_SOCKET_ERROR	_MD_os2_map_socket_error
+
+NSPR_API(void) _MD_os2_map_recv_error(PRInt32 err);
+#define	_PR_MD_MAP_RECV_ERROR	_MD_os2_map_recv_error
+
+NSPR_API(void) _MD_os2_map_recvfrom_error(PRInt32 err);
+#define	_PR_MD_MAP_RECVFROM_ERROR	_MD_os2_map_recvfrom_error
+
+NSPR_API(void) _MD_os2_map_send_error(PRInt32 err);
+#define	_PR_MD_MAP_SEND_ERROR	_MD_os2_map_send_error
+
+NSPR_API(void) _MD_os2_map_sendto_error(PRInt32 err);
+#define	_PR_MD_MAP_SENDTO_ERROR	_MD_os2_map_sendto_error
+
+NSPR_API(void) _MD_os2_map_writev_error(int err);
+#define	_PR_MD_MAP_WRITEV_ERROR	_MD_os2_map_writev_error
+
+NSPR_API(void) _MD_os2_map_accept_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCEPT_ERROR	_MD_os2_map_accept_error
+
+NSPR_API(void) _MD_os2_map_acceptex_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCEPTEX_ERROR	_MD_os2_map_acceptex_error
+
+NSPR_API(void) _MD_os2_map_connect_error(PRInt32 err);
+#define	_PR_MD_MAP_CONNECT_ERROR	_MD_os2_map_connect_error
+
+NSPR_API(void) _MD_os2_map_bind_error(PRInt32 err);
+#define	_PR_MD_MAP_BIND_ERROR	_MD_os2_map_bind_error
+
+NSPR_API(void) _MD_os2_map_listen_error(PRInt32 err);
+#define	_PR_MD_MAP_LISTEN_ERROR	_MD_os2_map_listen_error
+
+NSPR_API(void) _MD_os2_map_shutdown_error(PRInt32 err);
+#define	_PR_MD_MAP_SHUTDOWN_ERROR	_MD_os2_map_shutdown_error
+
+NSPR_API(void) _MD_os2_map_socketpair_error(int err);
+#define	_PR_MD_MAP_SOCKETPAIR_ERROR	_MD_os2_map_socketpair_error
+
+NSPR_API(void) _MD_os2_map_getsockname_error(PRInt32 err);
+#define	_PR_MD_MAP_GETSOCKNAME_ERROR	_MD_os2_map_getsockname_error
+
+NSPR_API(void) _MD_os2_map_getpeername_error(PRInt32 err);
+#define	_PR_MD_MAP_GETPEERNAME_ERROR	_MD_os2_map_getpeername_error
+
+NSPR_API(void) _MD_os2_map_getsockopt_error(PRInt32 err);
+#define	_PR_MD_MAP_GETSOCKOPT_ERROR	_MD_os2_map_getsockopt_error
+
+NSPR_API(void) _MD_os2_map_setsockopt_error(PRInt32 err);
+#define	_PR_MD_MAP_SETSOCKOPT_ERROR	_MD_os2_map_setsockopt_error
+
+NSPR_API(void) _MD_os2_map_open_error(PRInt32 err);
+#define	_PR_MD_MAP_OPEN_ERROR	_MD_os2_map_open_error
+
+NSPR_API(void) _MD_os2_map_gethostname_error(PRInt32 err);
+#define	_PR_MD_MAP_GETHOSTNAME_ERROR	_MD_os2_map_gethostname_error
+
+NSPR_API(void) _MD_os2_map_select_error(PRInt32 err);
+#define	_PR_MD_MAP_SELECT_ERROR	_MD_os2_map_select_error
+
+NSPR_API(void) _MD_os2_map_lockf_error(int err);
+#define _PR_MD_MAP_LOCKF_ERROR  _MD_os2_map_lockf_error
+
+#endif /* nspr_os2_errors_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_osf1.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_osf1.cfg
new file mode 100644
index 0000000..dcd8d30
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_osf1.cfg
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef OSF1
+#define OSF1
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#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
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_osf1.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_osf1.h
new file mode 100644
index 0000000..9767b87
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_osf1.h
@@ -0,0 +1,255 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_osf1_defs_h___
+#define nspr_osf1_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"osf"
+#define _PR_SI_SYSNAME	"OSF"
+#define _PR_SI_ARCHITECTURE "alpha"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE        0x50000000
+#define _MD_DEFAULT_STACK_SIZE  131072L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#undef 	HAVE_WEAK_IO_SYMBOLS
+#undef 	HAVE_WEAK_MALLOC_SYMBOLS
+#define HAVE_DLL
+#define HAVE_BSD_FLOCK
+
+#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
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#else
+#define AF_INET6 26
+#ifndef AI_CANONNAME
+#define AI_CANONNAME 0x00000002
+struct addrinfo {
+    int              ai_flags;
+    int              ai_family;
+    int              ai_socktype;
+    int              ai_protocol;
+    size_t           ai_addrlen;
+    char            *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#endif
+#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 jmp_buf is actually a struct sigcontext.  The sc_sp field of
+ * struct sigcontext is the stack pointer.
+ */
+#define _MD_GET_SP(_t) (((struct sigcontext *) (_t)->md.context)->sc_sp)
+#define PR_NUM_GCREGS _JBLEN
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+{									  \
+        *status = PR_TRUE;              \
+    if (setjmp(CONTEXT(_thread))) {				\
+	(*_main)();						\
+    }								\
+    _MD_GET_SP(_thread) = (long) ((_sp) - 64);			\
+    _MD_GET_SP(_thread) &= ~15;					\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;     \
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    longjmp(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    jmp_buf context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#ifndef _PR_PTHREADS
+#define _MD_INIT_LOCKS()
+#endif
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/* The following defines unwrapped versions of select() and poll(). */
+#include <sys/time.h>
+extern int __select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
+#define _MD_SELECT              __select
+
+#include <sys/poll.h>
+#define _MD_POLL __poll
+extern int __poll(struct pollfd filedes[], unsigned int nfds, int timeout);
+
+/*
+ * Atomic operations
+ */
+#ifdef OSF1_HAVE_MACHINE_BUILTINS_H
+#include <machine/builtins.h>
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(val) (__ATOMIC_INCREMENT_LONG(val) + 1)
+#define _MD_ATOMIC_ADD(ptr, val)  (__ATOMIC_ADD_LONG(ptr, val) + val)
+#define _MD_ATOMIC_DECREMENT(val) (__ATOMIC_DECREMENT_LONG(val) - 1)
+#define _MD_ATOMIC_SET(val, newval) __ATOMIC_EXCH_LONG(val, newval)
+#endif /* OSF1_HAVE_MACHINE_BUILTINS_H */
+
+#endif /* nspr_osf1_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_pcos.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_pcos.h
new file mode 100644
index 0000000..59e8e2c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_pcos.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prpcos_h___
+#define prpcos_h___
+
+#define PR_DLL_SUFFIX		".dll"
+
+#include <stdlib.h>
+
+#define DIRECTORY_SEPARATOR         '\\'
+#define DIRECTORY_SEPARATOR_STR     "\\"
+#define PATH_SEPARATOR              ';'
+
+/*
+** Routines for processing command line arguments
+*/
+PR_BEGIN_EXTERN_C
+#ifndef XP_OS2
+extern char *optarg;
+extern int optind;
+extern int getopt(int argc, char **argv, char *spec);
+#endif
+PR_END_EXTERN_C
+
+
+/*
+** Definitions of directory structures amd functions
+** These definitions are from:
+**      <dirent.h>
+*/
+#ifdef XP_OS2
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#include <io.h>
+#include <fcntl.h>          /* O_BINARY */
+
+#ifdef OS2
+extern PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen);
+#define _MD_GETHOSTNAME _MD_OS2GetHostName
+#else
+extern PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen);
+#define _MD_GETHOSTNAME _MD_WindowsGetHostName
+extern PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen);
+#define _MD_GETSYSINFO _MD_WindowsGetSysInfo
+#endif
+
+#endif /* prpcos_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_pth.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_pth.h
new file mode 100644
index 0000000..66a4c07
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_pth.h
@@ -0,0 +1,306 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_pth_defs_h_
+#define nspr_pth_defs_h_
+
+/*
+** Appropriate definitions of entry points not used in a pthreads world
+*/
+#define _PR_MD_BLOCK_CLOCK_INTERRUPTS()
+#define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _PR_MD_DISABLE_CLOCK_INTERRUPTS()
+#define _PR_MD_ENABLE_CLOCK_INTERRUPTS()
+
+/* In good standards fashion, the DCE threads (based on posix-4) are not
+ * quite the same as newer posix implementations.  These are mostly name
+ * changes and small differences, so macros usually do the trick
+ */
+#ifdef _PR_DCETHREADS
+#define _PT_PTHREAD_MUTEXATTR_INIT        pthread_mutexattr_create
+#define _PT_PTHREAD_MUTEXATTR_DESTROY     pthread_mutexattr_delete
+#define _PT_PTHREAD_MUTEX_INIT(m, a)      pthread_mutex_init(&(m), a)
+#define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (0 == pthread_mutex_trylock(&(m)))
+#define _PT_PTHREAD_CONDATTR_INIT         pthread_condattr_create
+#define _PT_PTHREAD_COND_INIT(m, a)       pthread_cond_init(&(m), a)
+#define _PT_PTHREAD_CONDATTR_DESTROY      pthread_condattr_delete
+
+/* Notes about differences between DCE threads and pthreads 10:
+ *   1. pthread_mutex_trylock returns 1 when it locks the mutex
+ *      0 when it does not.  The latest pthreads has a set of errno-like
+ *      return values.
+ *   2. return values from pthread_cond_timedwait are different.
+ *
+ *
+ *
+ */
+#elif defined(BSDI)
+/*
+ * Mutex and condition attributes are not supported.  The attr
+ * argument to pthread_mutex_init() and pthread_cond_init() must
+ * be passed as NULL.
+ *
+ * The memset calls in _PT_PTHREAD_MUTEX_INIT and _PT_PTHREAD_COND_INIT
+ * are to work around BSDI's using a single bit to indicate a mutex
+ * or condition variable is initialized.  This entire BSDI section
+ * will go away when BSDI releases updated threads libraries for
+ * BSD/OS 3.1 and 4.0.
+ */
+#define _PT_PTHREAD_MUTEXATTR_INIT(x)     0
+#define _PT_PTHREAD_MUTEXATTR_DESTROY(x)  /* */
+#define _PT_PTHREAD_MUTEX_INIT(m, a)      (memset(&(m), 0, sizeof(m)), \
+                                      pthread_mutex_init(&(m), NULL))
+#define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (EBUSY == pthread_mutex_trylock(&(m)))
+#define _PT_PTHREAD_CONDATTR_INIT(x)      0
+#define _PT_PTHREAD_CONDATTR_DESTROY(x)   /* */
+#define _PT_PTHREAD_COND_INIT(m, a)       (memset(&(m), 0, sizeof(m)), \
+                                      pthread_cond_init(&(m), NULL))
+#else
+#define _PT_PTHREAD_MUTEXATTR_INIT        pthread_mutexattr_init
+#define _PT_PTHREAD_MUTEXATTR_DESTROY     pthread_mutexattr_destroy
+#define _PT_PTHREAD_MUTEX_INIT(m, a)      pthread_mutex_init(&(m), &(a))
+#if defined(FREEBSD)
+#define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    pt_pthread_mutex_is_locked(&(m))
+#else
+#define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (EBUSY == pthread_mutex_trylock(&(m)))
+#endif
+#if defined(ANDROID)
+/* Conditional attribute init and destroy aren't implemented in bionic. */
+#define _PT_PTHREAD_CONDATTR_INIT(x)      0
+#define _PT_PTHREAD_CONDATTR_DESTROY(x)   /* */
+#else
+#define _PT_PTHREAD_CONDATTR_INIT         pthread_condattr_init
+#define _PT_PTHREAD_CONDATTR_DESTROY      pthread_condattr_destroy
+#endif
+#define _PT_PTHREAD_COND_INIT(m, a)       pthread_cond_init(&(m), &(a))
+#endif
+
+/* The pthreads standard does not specify an invalid value for the
+ * pthread_t handle.  (0 is usually an invalid pthread identifier
+ * but there are exceptions, for example, DG/UX.)  These macros
+ * define a way to set the handle to or compare the handle with an
+ * invalid identifier.  These macros are not portable and may be
+ * more of a problem as we adapt to more pthreads implementations.
+ * They are only used in the PRMonitor functions.  Do not use them
+ * in new code.
+ *
+ * Unfortunately some of our clients depend on certain properties
+ * of our PRMonitor implementation, preventing us from replacing
+ * it by a portable implementation.
+ * - High-performance servers like the fact that PR_EnterMonitor
+ *   only calls PR_Lock and PR_ExitMonitor only calls PR_Unlock.
+ *   (A portable implementation would use a PRLock and a PRCondVar
+ *   to implement the recursive lock in a monitor and call both
+ *   PR_Lock and PR_Unlock in PR_EnterMonitor and PR_ExitMonitor.)
+ *   Unfortunately this forces us to read the monitor owner field
+ *   without holding a lock.
+ * - One way to make it safe to read the monitor owner field
+ *   without holding a lock is to make that field a PRThread*
+ *   (one should be able to read a pointer with a single machine
+ *   instruction).  However, PR_GetCurrentThread calls calloc if
+ *   it is called by a thread that was not created by NSPR.  The
+ *   malloc tracing tools in the Mozilla client use PRMonitor for
+ *   locking in their malloc, calloc, and free functions.  If
+ *   PR_EnterMonitor calls any of these functions, infinite
+ *   recursion ensues.
+ */
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) \
+	memset(&(t), 0, sizeof(pthread_t))
+#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) \
+	(!memcmp(&(t), &pt_zero_tid, sizeof(pthread_t)))
+#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
+#elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(SOLARIS) \
+	|| defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+	|| defined(HPUX) || defined(FREEBSD) \
+	|| defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \
+	|| defined(NTO) || defined(DARWIN) \
+	|| defined(UNIXWARE) || defined(RISCOS)	|| defined(SYMBIAN)
+#ifdef __GNU__
+/* Hurd pthreads don't have an invalid value for pthread_t. -- rmh */
+#error Using Hurd pthreads
+#endif
+#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t)  (t) = 0
+#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t)  (t) == 0
+#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
+#else 
+#error "pthreads is not supported for this architecture"
+#endif
+
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_ATTR_INIT            pthread_attr_create
+#define _PT_PTHREAD_ATTR_DESTROY         pthread_attr_delete
+#define _PT_PTHREAD_CREATE(t, a, f, r)   pthread_create(t, a, f, r) 
+#define _PT_PTHREAD_KEY_CREATE           pthread_keycreate
+#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY  pthread_attr_setsched
+#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) \
+                                     (*(s) = pthread_attr_getstacksize(*(a)), 0)
+#define _PT_PTHREAD_GETSPECIFIC(k, r) \
+		pthread_getspecific((k), (pthread_addr_t *) &(r))
+#elif defined(_PR_PTHREADS)
+#define _PT_PTHREAD_ATTR_INIT            pthread_attr_init
+#define _PT_PTHREAD_ATTR_DESTROY         pthread_attr_destroy
+#define _PT_PTHREAD_CREATE(t, a, f, r)   pthread_create(t, &a, f, r) 
+#define _PT_PTHREAD_KEY_CREATE           pthread_key_create
+#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY  pthread_attr_setschedpolicy
+#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) pthread_attr_getstacksize(a, s)
+#define _PT_PTHREAD_GETSPECIFIC(k, r)    (r) = pthread_getspecific(k)
+#else
+#error "Cannot determine pthread strategy"
+#endif
+
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_EXPLICIT_SCHED      _PT_PTHREAD_DEFAULT_SCHED
+#endif
+
+/*
+ * pthread_mutex_trylock returns different values in DCE threads and
+ * pthreads.
+ */
+#if defined(_PR_DCETHREADS)
+#define PT_TRYLOCK_SUCCESS 1
+#define PT_TRYLOCK_BUSY    0
+#else
+#define PT_TRYLOCK_SUCCESS 0
+#define PT_TRYLOCK_BUSY    EBUSY
+#endif
+
+/*
+ * These platforms don't have sigtimedwait()
+ */
+#if (defined(AIX) && !defined(AIX4_3_PLUS)) \
+	|| defined(LINUX) || defined(__GNU__)|| defined(__GLIBC__) \
+	|| defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
+	|| defined(BSDI) || defined(UNIXWARE) \
+	|| defined(DARWIN) || defined(SYMBIAN)
+#define PT_NO_SIGTIMEDWAIT
+#endif
+
+#if defined(OSF1)
+#define PT_PRIO_MIN            PRI_OTHER_MIN
+#define PT_PRIO_MAX            PRI_OTHER_MAX
+#elif defined(IRIX)
+#include <sys/sched.h>
+#define PT_PRIO_MIN            PX_PRIO_MIN
+#define PT_PRIO_MAX            PX_PRIO_MAX
+#elif defined(AIX)
+#include <sys/priv.h>
+#include <sys/sched.h>
+#ifndef PTHREAD_CREATE_JOINABLE
+#define PTHREAD_CREATE_JOINABLE     PTHREAD_CREATE_UNDETACHED
+#endif
+#define PT_PRIO_MIN            DEFAULT_PRIO
+#define PT_PRIO_MAX            DEFAULT_PRIO
+#elif defined(HPUX)
+
+#if defined(_PR_DCETHREADS)
+#define PT_PRIO_MIN            PRI_OTHER_MIN
+#define PT_PRIO_MAX            PRI_OTHER_MAX
+#else /* defined(_PR_DCETHREADS) */
+#include <sys/sched.h>
+#define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
+#define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
+#endif /* defined(_PR_DCETHREADS) */
+
+#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+	|| defined(FREEBSD) || defined(SYMBIAN)
+#define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
+#define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
+#elif defined(NTO)
+/*
+ * Neutrino has functions that return the priority range but
+ * they return invalid numbers, so I just hard coded these here
+ * for now.  Jerry.Kirk@Nexarecorp.com
+ */
+#define PT_PRIO_MIN            0
+#define PT_PRIO_MAX            30
+#elif defined(SOLARIS)
+/*
+ * Solaris doesn't seem to have macros for the min/max priorities.
+ * The range of 0-127 is mentioned in the pthread_setschedparam(3T)
+ * man pages, and pthread_setschedparam indeed allows 0-127.  However,
+ * pthread_attr_setschedparam does not allow 0; it allows 1-127.
+ */
+#define PT_PRIO_MIN            1
+#define PT_PRIO_MAX            127
+#elif defined(OPENBSD)
+#define PT_PRIO_MIN            0
+#define PT_PRIO_MAX            31
+#elif defined(NETBSD) \
+	|| defined(BSDI) || defined(DARWIN) || defined(UNIXWARE) \
+	|| defined(RISCOS) /* XXX */
+#define PT_PRIO_MIN            0
+#define PT_PRIO_MAX            126
+#else
+#error "pthreads is not supported for this architecture"
+#endif
+
+/*
+ * The _PT_PTHREAD_YIELD function is called from a signal handler.
+ * Needed for garbage collection -- Look at PR_Suspend/PR_Resume
+ * implementation.
+ */
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_YIELD()            	pthread_yield()
+#elif defined(OSF1)
+/*
+ * sched_yield can't be called from a signal handler.  Must use
+ * the _np version.
+ */
+#define _PT_PTHREAD_YIELD()            	pthread_yield_np()
+#elif defined(AIX)
+extern int (*_PT_aix_yield_fcn)();
+#define _PT_PTHREAD_YIELD()			(*_PT_aix_yield_fcn)()
+#elif defined(IRIX)
+#include <time.h>
+#define _PT_PTHREAD_YIELD() \
+    PR_BEGIN_MACRO               				\
+		struct timespec onemillisec = {0};		\
+		onemillisec.tv_nsec = 1000000L;			\
+        nanosleep(&onemillisec,NULL);			\
+    PR_END_MACRO
+#elif defined(HPUX) || defined(SOLARIS) \
+	|| defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+	|| defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
+	|| defined(BSDI) || defined(NTO) || defined(DARWIN) \
+	|| defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN)
+#define _PT_PTHREAD_YIELD()            	sched_yield()
+#else
+#error "Need to define _PT_PTHREAD_YIELD for this platform"
+#endif
+
+#endif /* nspr_pth_defs_h_ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_qnx.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_qnx.cfg
new file mode 100644
index 0000000..7c5fc3e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_qnx.cfg
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef QNX
+#define QNX
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef  HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   1
+#define PR_ALIGN_OF_INT     1
+#define PR_ALIGN_OF_LONG    1
+#define PR_ALIGN_OF_INT64   1
+#define PR_ALIGN_OF_FLOAT   1
+#define PR_ALIGN_OF_DOUBLE  1
+#define PR_ALIGN_OF_POINTER 1
+#define PR_ALIGN_OF_WORD    1
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+#define PR_WORDS_PER_DWORD_LOG2  1
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_qnx.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_qnx.h
new file mode 100644
index 0000000..f7593c6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_qnx.h
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_qnx_defs_h___
+#define nspr_qnx_defs_h___
+
+/*
+** Internal configuration macros
+*/
+#define PR_LINKER_ARCH		"qnx"
+#define _PR_SI_SYSNAME		"QNX"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS		MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef _PR_POLL_AVAILABLE
+#undef _PR_USE_POLL
+#define _PR_HAVE_SOCKADDR_LEN
+#define HAVE_BSD_FLOCK
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#include <sys/select.h>
+
+#undef  HAVE_STACK_GROWING_UP
+#undef	HAVE_DLL
+#undef	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR
+#endif
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP			setjmp
+#define _LONGJMP		longjmp
+#define _PR_CONTEXT_TYPE	jmp_buf
+#define _PR_NUM_GCREGS		_JBLEN
+#define _MD_GET_SP(_t)		(_t)->md.context[7]
+
+#define CONTEXT(_th)		((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	\
+{							\
+    *status = PR_TRUE;					\
+    if(_SETJMP(CONTEXT(_thread))) (*_main)();		\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128);		\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)	\
+    if (!_SETJMP(CONTEXT(_thread))) {	\
+	(_thread)->md.errcode = errno;	\
+	_PR_Schedule();			\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)	\
+{					\
+    errno = (_thread)->md.errcode;	\
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    _LONGJMP(CONTEXT(_thread), 1);	\
+}
+
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** md-specific cpu structure field
+*/
+#define _PR_MD_MAX_OSFD		FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu)	PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock)		PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_GET_INTERVAL		_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC		_PR_UNIX_TicksPerSecond
+#define _MD_EARLY_INIT			_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+** We wrapped the select() call.  _MD_SELECT refers to the built-in,
+** unwrapped version.
+*/
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#define _MD_SELECT		select
+
+#define SA_RESTART 0
+
+#endif /* nspr_qnx_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_reliantunix.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_reliantunix.cfg
new file mode 100644
index 0000000..f2913d1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_reliantunix.cfg
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef RELIANTUNIX
+#define RELIANTUNIX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#undef HAVE_LONG_LONG
+#undef  HAVE_ALIGNED_DOUBLES
+#undef  HAVE_ALIGNED_LONGLONGS
+
+#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_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD    32
+#define PR_BITS_PER_DWORD   64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2   5
+#define PR_BITS_PER_DWORD_LOG2  6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+#define PR_WORDS_PER_DWORD_LOG2 1
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD    4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_reliantunix.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_reliantunix.h
new file mode 100644
index 0000000..a924e2f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_reliantunix.h
@@ -0,0 +1,270 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * reliantunix.h
+ * 5/18/96 Taken from nec.h -- chrisk@netscape.com
+ * 3/14/97 Modified for nspr20 -- chrisk@netscape.com
+ */
+#ifndef nspr_reliantunix_defs_h___
+#define nspr_reliantunix_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"sinix"
+#define _PR_SI_SYSNAME	"SINIX"
+#define _PR_SI_ARCHITECTURE "mips"
+#define PR_DLL_SUFFIX ".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	(2*65536L)
+#define _MD_MMAP_FLAGS		MAP_PRIVATE|MAP_FIXED
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define HAVE_NETCONFIG
+#define HAVE_WEAK_IO_SYMBOLS
+#define HAVE_WEAK_MALLOC_SYMBOLS
+#define _PR_RECV_BROKEN /* recv doesn't work on Unix Domain Sockets */
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ST_ATIM
+#define _PR_NO_LARGE_FILES
+
+/*
+ * Mike Patnode indicated that it is possibly safe now to use context-switching
+ * calls that do not change the signal mask, like setjmp vs. sigsetjmp.
+ * So we'll use our homegrown, getcontext/setcontext-compatible stuff which 
+ * will save us the getcontext/setcontext system calls at each context switch.
+ * It already works in FastTrack 2.01, so it should do it here :-)
+ *  - chrisk 040497
+ */
+#define USE_SETCXT /* temporarily disabled... */
+
+#include <ucontext.h>
+ 
+#ifdef USE_SETCXT
+/* use non-syscall machine language replacement */
+#define _GETCONTEXT		getcxt
+#define _SETCONTEXT		setcxt
+/* defined in os_ReliantUNIX.s */
+extern int getcxt(ucontext_t *);
+extern int setcxt(ucontext_t *);
+#else
+#define _GETCONTEXT		getcontext
+#define _SETCONTEXT		setcontext
+#endif
+
+#define _MD_GET_SP(_t)		(_t)->md.context.uc_mcontext.gpregs[CXT_SP]
+#define _PR_CONTEXT_TYPE	ucontext_t
+#define _PR_NUM_GCREGS		NGREG
+ 
+#define CONTEXT(_thread) (&(_thread)->md.context)
+
+#define _PR_IS_NATIVE_THREAD_SUPPORTED() 0
+ 
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+** Initialize the thread context preparing it to execute "_main()"
+** - get a nice, fresh context
+** - set its SP to the stack we allcoated for it
+** - set it to start things at "e"
+*/
+#define _MD_INIT_CONTEXT(thread, _sp, _main, status)                \
+    PR_BEGIN_MACRO                                                  \
+    *status = PR_TRUE;                                              \
+    _GETCONTEXT(CONTEXT(thread));                                   \
+    /* this is supposed to point to the stack BASE, not to SP */    \
+    CONTEXT(thread)->uc_stack.ss_sp = thread->stack->stackBottom;   \
+    CONTEXT(thread)->uc_stack.ss_size = thread->stack->stackSize;   \
+    CONTEXT(thread)->uc_mcontext.gpregs[CXT_SP] = ((unsigned long)_sp - 128) & 0xfffffff8; \
+    CONTEXT(thread)->uc_mcontext.gpregs[CXT_T9] = _main;            \
+    CONTEXT(thread)->uc_mcontext.gpregs[CXT_EPC] = _main;           \
+    CONTEXT(thread)->uc_mcontext.gpregs[CXT_RA] = 0;                \
+    thread->no_sched = 0;                                           \
+    PR_END_MACRO
+ 
+/*
+** Save current context as it is scheduled away
+*/
+#define _MD_SWITCH_CONTEXT(_thread)       \
+    PR_BEGIN_MACRO                        \
+    if (!_GETCONTEXT(CONTEXT(_thread))) { \
+	_MD_SAVE_ERRNO(_thread);          \
+	_MD_SET_LAST_THREAD(_thread);     \
+        _PR_Schedule();                   \
+    }                                     \
+    PR_END_MACRO
+ 
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT or set up
+**  by _MD_INIT_CONTEXT
+**  CXT_V0 is the register that holds the return value.
+**   We must set it to 1 so that we can see if the return from
+**   getcontext() is the result of calling getcontext() or
+**   setcontext()...
+**   setting a context got with getcontext() appears to
+**   return from getcontext(), too!
+**  CXT_A3 is the register that holds status when returning
+**   from a syscall. It is set to 0 to indicate success,
+**   because we want getcontext() on the other side of the magic
+**   door to be ok.
+*/
+#define _MD_RESTORE_CONTEXT(_thread)   \
+    PR_BEGIN_MACRO                     \
+    ucontext_t *uc = CONTEXT(_thread); \
+    uc->uc_mcontext.gpregs[CXT_V0] = 1;\
+    uc->uc_mcontext.gpregs[CXT_A3] = 0;\
+    _MD_RESTORE_ERRNO(_thread);        \
+    _MD_SET_CURRENT_THREAD(_thread);   \
+    _SETCONTEXT(uc);                   \
+    PR_END_MACRO
+
+#define _MD_SAVE_ERRNO(t)	 (t)->md.errcode = errno;
+#define _MD_RESTORE_ERRNO(t)	 errno = (t)->md.errcode;
+
+#define _MD_GET_INTERVAL	_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC	_PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD		_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)
+#define _MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+#if !defined(S_ISSOCK) && defined(S_IFSOCK)
+#define S_ISSOCK(mode)   ((mode&0xF000) == 0xC000)
+#endif
+#if !defined(S_ISLNK) && defined(S_IFLNK)
+#define S_ISLNK(mode)   ((mode&0xA000) == 0xC000)
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *execptfds, struct timeval *timeout);
+#define _MD_SELECT(nfds,r,w,e,tv) _select(nfds,r,w,e,tv)
+#define _MD_POLL _poll
+
+#endif /* nspr_reliantunix_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_riscos.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_riscos.cfg
new file mode 100644
index 0000000..53010bd
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_riscos.cfg
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef RISCOS
+#define RISCOS
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+#undef  HAVE_ALIGNED_DOUBLES
+#undef  HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+#define PR_WORDS_PER_DWORD_LOG2  1
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_riscos.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_riscos.h
new file mode 100644
index 0000000..c95067c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_riscos.h
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Peter Naulls <peter@chocky.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_riscos_defs_h___
+#define nspr_riscos_defs_h___
+
+/*
+** Internal configuration macros
+*/
+#define PR_LINKER_ARCH		"riscos"
+#define _PR_SI_SYSNAME		"RISCOS"
+#define _PR_SI_ARCHITECTURE	"arm"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_HAVE_SOCKADDR_LEN
+#undef HAVE_BSD_FLOCK
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define _PR_HAVE_POSIX_SEMAPHORES
+
+#include <sys/select.h>
+#include <sys/poll.h>
+#include <kernel.h>
+
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define PT_NO_SIGTIMEDWAIT
+
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR
+#endif
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP			setjmp
+#define _LONGJMP		longjmp
+#define _PR_CONTEXT_TYPE	jmp_buf
+#define _PR_NUM_GCREGS		_JBLEN
+#define _MD_GET_SP(_t)		(_t)->md.context[7]
+
+#define CONTEXT(_th)		((_th)->md.context)
+
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	\
+{							\
+    *status = PR_TRUE;					\
+    if(_SETJMP(CONTEXT(_thread))) (*_main)();		\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128);		\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)	\
+    if (!_SETJMP(CONTEXT(_thread))) {	\
+	(_thread)->md.errcode = errno;	\
+	_PR_Schedule();			\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)	\
+{					\
+    errno = (_thread)->md.errcode;	\
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    _LONGJMP(CONTEXT(_thread), 1);	\
+}
+
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** md-specific cpu structure field
+*/
+#define _PR_MD_MAX_OSFD		FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif
+};
+
+#define _PR_IOQ(_cpu)	/*	*/	((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu)	PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock)		PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_GET_INTERVAL		_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC		_PR_UNIX_TicksPerSecond
+#define _MD_EARLY_INIT			_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+** We wrapped the select() call.  _MD_SELECT refers to the built-in,
+** unwrapped version.
+*/
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#define _MD_SELECT		select
+
+#endif /* nspr_riscos_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_scoos.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_scoos.cfg
new file mode 100644
index 0000000..d7c461f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_scoos.cfg
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SCO
+#define SCO
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_scoos.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_scoos.h
new file mode 100644
index 0000000..6efaa7e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_scoos.h
@@ -0,0 +1,204 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_scoos5_defs_h___
+#define nspr_scoos5_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"scoos5"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_SI_SYSNAME      "SCO"
+#define _PR_SI_ARCHITECTURE "x86"
+#define _PR_STACK_VMBASE    0x50000000
+
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define	HAVE_DLL
+#define	USE_DLFCN
+
+#if !defined (HAVE_STRERROR)
+#define HAVE_STRERROR
+#endif
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_RECV_BROKEN /* recv doesn't work on Unix Domain Sockets */
+
+#define USE_SETJMP
+
+#ifdef _PR_LOCAL_THREADS_ONLY
+#include <setjmp.h>
+
+#define _MD_GET_SP(_t)  (_t)->md.jb[4]
+#define PR_NUM_GCREGS	_SIGJBLEN
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.jb)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)				\
+{								  									\
+	*status = PR_TRUE;												\
+    if (sigsetjmp(CONTEXT(_thread),1)) {				  			\
+		(*_main)(); 												\
+    }								  								\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 64);	\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  								\
+    if (!sigsetjmp(CONTEXT(_thread), 1)) { 							\
+		(_thread)->md.errcode = errno;  							\
+		_PR_Schedule();		     									\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)								\
+{				     												\
+    errno = (_thread)->osErrorCode;	     							\
+	_MD_SET_CURRENT_THREAD(_thread);								\
+    siglongjmp(CONTEXT(_thread), 1);    							\
+}
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+struct _MDThread {
+    jmp_buf jb;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_EARLY_INIT          	_MD_EarlyInit
+#define _MD_FINAL_INIT				_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) 	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         	_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_SELECT		_select
+#define _MD_POLL		_poll
+
+#endif /* nspr_scoos5_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_solaris.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_solaris.cfg
new file mode 100644
index 0000000..81313e5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_solaris.cfg
@@ -0,0 +1,203 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SOLARIS
+#define SOLARIS
+#endif
+
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
+#if defined(sparc) || defined(__sparc)
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_DOUBLE  8
+#if defined(__sparcv9)
+#define IS_64
+#endif
+#elif defined(__x86_64)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_DOUBLE  8
+#define IS_64
+#elif defined(i386) || defined(__i386)
+#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
+
+#ifdef IS_64
+
+#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
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_POINTER 8
+
+#else /* IS_64 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_POINTER 4
+
+#endif /* IS_64 */
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* ifndef nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_solaris.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_solaris.h
new file mode 100644
index 0000000..edc5520
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_solaris.h
@@ -0,0 +1,531 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_solaris_defs_h___
+#define nspr_solaris_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"solaris"
+#define _PR_SI_SYSNAME	"SOLARIS"
+#ifdef sparc
+#define _PR_SI_ARCHITECTURE	"sparc"
+#elif defined(__x86_64)
+#define _PR_SI_ARCHITECTURE	"x86-64"
+#elif defined(i386)
+#define _PR_SI_ARCHITECTURE	"x86"
+#else
+#error unknown processor
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	(2*65536L)
+#define _MD_MMAP_FLAGS          MAP_SHARED
+
+#undef  HAVE_STACK_GROWING_UP
+
+#ifndef HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef	HAVE_WEAK_MALLOC_SYMBOLS
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+
+/*
+ * Intel x86 has atomic instructions.
+ *
+ * Sparc v8 does not have instructions to efficiently implement
+ * atomic increment/decrement operations.  We use the default
+ * atomic routine implementation in pratom.c.
+ *
+ * 64-bit Solaris requires sparc v9, which has atomic instructions.
+ */
+#if defined(i386) || defined(IS_64)
+#define _PR_HAVE_ATOMIC_OPS
+#endif
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ST_ATIM
+#ifdef SOLARIS2_5
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#else
+#define _PR_HAVE_POSIX_SEMAPHORES
+#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#endif
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#define _PR_ACCEPT_INHERIT_NONBLOCK
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#else
+#define AF_INET6 26
+struct addrinfo {
+    int ai_flags;
+    int ai_family;
+    int ai_socktype;
+    int ai_protocol;
+    size_t ai_addrlen;
+    char *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#define AI_CANONNAME 0x0010
+#define AI_V4MAPPED 0x0001 
+#define AI_ALL      0x0002
+#define AI_ADDRCONFIG   0x0004
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* isomorphic to struct in6_addr on Solaris 8 */
+struct _md_in6_addr {
+    union {
+        PRUint8  _S6_u8[16];
+        PRUint32 _S6_u32[4];
+        PRUint32 __S6_align;
+    } _S6_un;
+};
+/* isomorphic to struct sockaddr_in6 on Solaris 8 */
+struct _md_sockaddr_in6 {
+    PRUint16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+    PRUint32 __sin6_src_id;
+};
+#endif
+#if defined(_PR_PTHREADS)
+#define _PR_HAVE_GETHOST_R
+#define _PR_HAVE_GETHOST_R_POINTER
+#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)
+/*
+** Atomic Operations
+*/
+#define _MD_INIT_ATOMIC()
+
+NSPR_API(PRInt32) _MD_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement
+
+NSPR_API(PRInt32) _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD _MD_AtomicAdd
+
+NSPR_API(PRInt32) _MD_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement
+
+NSPR_API(PRInt32) _MD_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET _MD_AtomicSet
+#endif /* _PR_HAVE_ATOMIC_OPS */
+
+#if defined(_PR_PTHREADS)
+
+NSPR_API(void)		_MD_EarlyInit(void);
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+
+#else /* _PR_PTHREADS */
+
+/*
+ * _PR_LOCAL_THREADS_ONLY implementation on Solaris
+ */
+
+#include "prthread.h"
+
+#include <errno.h>
+#include <ucontext.h>
+#include <sys/stack.h>
+#include <synch.h>
+
+/*
+** Initialization Related definitions
+*/
+
+NSPR_API(void)				_MD_EarlyInit(void);
+NSPR_API(void)				_MD_SolarisInit();
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_MD_SolarisInit
+#define	_MD_INIT_THREAD		_MD_InitializeThread
+
+#ifdef USE_SETJMP
+
+#include <setjmp.h>
+
+#define _PR_CONTEXT_TYPE	jmp_buf
+
+#ifdef sparc
+#define _MD_GET_SP(_t)		(_t)->md.context[2]
+#else
+#define _MD_GET_SP(_t)		(_t)->md.context[4]
+#endif
+
+#define PR_NUM_GCREGS		_JBLEN
+#define CONTEXT(_thread)	(_thread)->md.context
+
+#else  /* ! USE_SETJMP */
+
+#ifdef sparc
+#define	_PR_CONTEXT_TYPE	ucontext_t
+#define _MD_GET_SP(_t)		(_t)->md.context.uc_mcontext.gregs[REG_SP]
+/*
+** Sparc's use register windows. the _MD_GetRegisters for the sparc's
+** doesn't actually store anything into the argument buffer; instead the
+** register windows are homed to the stack. I assume that the stack
+** always has room for the registers to spill to...
+*/
+#define PR_NUM_GCREGS		0
+#else
+#define _PR_CONTEXT_TYPE	unsigned int edi; sigset_t oldMask, blockMask; ucontext_t
+#define _MD_GET_SP(_t)		(_t)->md.context.uc_mcontext.gregs[USP]
+#define PR_NUM_GCREGS		_JBLEN
+#endif
+
+#define CONTEXT(_thread)	(&(_thread)->md.context)
+
+#endif /* ! USE_SETJMP */
+
+#include <time.h>
+/* 
+ * Because clock_gettime() on Solaris/x86 always generates a
+ * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
+ * which is implemented using gettimeofday().
+ */
+#ifdef i386
+#define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
+#else
+#define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
+#endif  /* i386 */
+
+#define _MD_SAVE_ERRNO(_thread)			(_thread)->md.errcode = errno;
+#define _MD_RESTORE_ERRNO(_thread)		errno = (_thread)->md.errcode;
+
+#ifdef sparc
+
+#ifdef USE_SETJMP
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+    PR_BEGIN_MACRO				      \
+	int *context = (_thread)->md.context;	      \
+    *status = PR_TRUE;              \
+	(void) setjmp(context);			      \
+	(_thread)->md.context[1] = (int) ((_sp) - 64); \
+	(_thread)->md.context[2] = (int) _main;	      \
+	(_thread)->md.context[3] = (int) _main + 4; \
+    _thread->no_sched = 0; \
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread)    \
+    if (!setjmp(CONTEXT(_thread))) { \
+	_MD_SAVE_ERRNO(_thread)    \
+	_MD_SET_LAST_THREAD(_thread);	 \
+    _MD_SET_CURRENT_THREAD(_thread);	 \
+	_PR_Schedule();		     \
+    }
+
+#define _MD_RESTORE_CONTEXT(_newThread)	    \
+{				     \
+	_MD_RESTORE_ERRNO(_newThread)	    \
+	_MD_SET_CURRENT_THREAD(_newThread); \
+    longjmp(CONTEXT(_newThread), 1);    \
+}
+
+#else
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)					\
+    PR_BEGIN_MACRO				      									\
+    ucontext_t *uc = CONTEXT(_thread);									\
+    *status = PR_TRUE;													\
+    getcontext(uc);														\
+    uc->uc_stack.ss_sp = (char *) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);	\
+    uc->uc_stack.ss_size = _thread->stack->stackSize; 					\
+    uc->uc_stack.ss_flags = 0; 				/* ? */		        		\
+    uc->uc_mcontext.gregs[REG_SP] = (unsigned int) uc->uc_stack.ss_sp;	\
+    uc->uc_mcontext.gregs[REG_PC] = (unsigned int) _main;				\
+    uc->uc_mcontext.gregs[REG_nPC] = (unsigned int) ((char*)_main)+4;	\
+    uc->uc_flags = UC_ALL;												\
+    _thread->no_sched = 0;												\
+    PR_END_MACRO
+
+/*
+** Switch away from the current thread context by saving its state and
+** calling the thread scheduler. Reload cpu when we come back from the
+** context switch because it might have changed.
+*/
+#define _MD_SWITCH_CONTEXT(_thread)    				\
+    PR_BEGIN_MACRO                     				\
+		if (!getcontext(CONTEXT(_thread))) { 		\
+			_MD_SAVE_ERRNO(_thread);    			\
+			_MD_SET_LAST_THREAD(_thread);	 		\
+			_PR_Schedule();			 				\
+		}					 						\
+    PR_END_MACRO
+
+/*
+** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
+** initialized by _MD_INIT_CONTEXT.
+*/
+#define _MD_RESTORE_CONTEXT(_newThread)	    				\
+    PR_BEGIN_MACRO			    							\
+    	ucontext_t *uc = CONTEXT(_newThread); 				\
+    	uc->uc_mcontext.gregs[11] = 1;     					\
+		_MD_RESTORE_ERRNO(_newThread);	    				\
+		_MD_SET_CURRENT_THREAD(_newThread); 				\
+    	setcontext(uc);		       							\
+    PR_END_MACRO
+#endif
+
+#else  /* x86 solaris */
+
+#ifdef USE_SETJMP
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+    PR_BEGIN_MACRO \
+    *status = PR_TRUE; \
+    if (setjmp(CONTEXT(_thread))) _main(); \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 64); \
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread) \
+    if (!setjmp(CONTEXT(_thread))) { \
+        _MD_SAVE_ERRNO(_thread) \
+        _PR_Schedule();	\
+    }
+
+#define _MD_RESTORE_CONTEXT(_newThread) \
+{ \
+    _MD_RESTORE_ERRNO(_newThread) \
+    _MD_SET_CURRENT_THREAD(_newThread); \
+    longjmp(CONTEXT(_newThread), 1); \
+}
+
+#else /* USE_SETJMP */
+
+#define WINDOWSIZE		0
+ 
+int getedi(void);
+void setedi(int);
+ 
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+	PR_BEGIN_MACRO					\
+	ucontext_t *uc = CONTEXT(_thread);		\
+        *status = PR_TRUE;              \
+	getcontext(uc);					\
+	/* Force sp to be double aligned! */		\
+    	uc->uc_mcontext.gregs[USP] = (int) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);	\
+	uc->uc_mcontext.gregs[PC] = (int) _main;	\
+	(_thread)->no_sched = 0; \
+	PR_END_MACRO
+
+/* getcontext() may return 1, contrary to what the man page says */
+#define _MD_SWITCH_CONTEXT(_thread)			\
+	PR_BEGIN_MACRO					\
+	ucontext_t *uc = CONTEXT(_thread);		\
+	PR_ASSERT(_thread->no_sched);			\
+	sigfillset(&((_thread)->md.blockMask));		\
+	sigprocmask(SIG_BLOCK, &((_thread)->md.blockMask),	\
+		&((_thread)->md.oldMask));		\
+	(_thread)->md.edi = getedi();			\
+	if (! getcontext(uc)) {				\
+		sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
+		uc->uc_mcontext.gregs[EDI] = (_thread)->md.edi;	\
+		_MD_SAVE_ERRNO(_thread)    		\
+	        _MD_SET_LAST_THREAD(_thread);	        \
+		_PR_Schedule();				\
+	} else {					\
+		sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
+		setedi((_thread)->md.edi);		\
+		PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \
+		_MD_LAST_THREAD()->no_sched = 0;	\
+	}						\
+	PR_END_MACRO
+
+/*
+** Restore a thread context, saved by _PR_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_newthread)			\
+	PR_BEGIN_MACRO					\
+	ucontext_t *uc = CONTEXT(_newthread);		\
+	uc->uc_mcontext.gregs[EAX] = 1;			\
+	_MD_RESTORE_ERRNO(_newthread)  			\
+	_MD_SET_CURRENT_THREAD(_newthread);		\
+	(_newthread)->no_sched = 1;			\
+	setcontext(uc);					\
+	PR_END_MACRO
+#endif /* USE_SETJMP */
+
+#endif /* sparc */
+
+struct _MDLock {
+	PRInt8 notused;
+};
+
+struct _MDCVar {
+	PRInt8 notused;
+};
+
+struct _MDSemaphore {
+	PRInt8 notused;
+};
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int errcode;
+    int id;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#ifndef _PR_PTHREADS
+#define _MD_INIT_LOCKS()
+#endif
+#define _MD_NEW_LOCK(lock)				PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)		_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD					_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)
+#define _MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_WAIT(struct PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(struct PRThread *);
+extern void     _MD_YIELD(void);
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+extern void     _MD_SET_PRIORITY(struct _MDThread *thread,
+	PRThreadPriority newPri);
+extern PRStatus _MD_CREATE_THREAD(PRThread *thread, void (*start) (void *),
+	PRThreadPriority priority, PRThreadScope scope, PRThreadState state,
+        PRUint32 stackSize);
+
+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
+
+/* The following defines the unwrapped versions of select() and poll(). */
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *exceptfds, struct timeval *timeout);
+#define _MD_SELECT	_select
+
+#include <stropts.h>
+#include <poll.h>
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Missing function prototypes
+*/
+extern int gethostname (char *name, int namelen);
+
+PR_END_EXTERN_C
+
+#endif /* _PR_PTHREADS */
+
+extern void _MD_solaris_map_sendfile_error(int err);
+
+#endif /* nspr_solaris_defs_h___ */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sony.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sony.cfg
new file mode 100644
index 0000000..4b8fbff
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sony.cfg
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SONY
+#define SONY
+#endif
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#undef  HAVE_LONG_LONG
+#undef  HAVE_ALIGNED_DOUBLES
+#undef  HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sony.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sony.h
new file mode 100644
index 0000000..3d17e04
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sony.h
@@ -0,0 +1,204 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_sony_defs_h___
+#define nspr_sony_defs_h___
+ 
+#define PR_LINKER_ARCH		"sony"
+#define _PR_SI_SYSNAME		"SONY"
+#define _PR_SI_ARCHITECTURE	"mips"
+#define PR_DLL_SUFFIX		".so"
+ 
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define _MD_GET_INTERVAL	_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC	_PR_UNIX_TicksPerSecond
+
+#if defined(_PR_LOCAL_THREADS_ONLY)
+#include <ucontext.h>
+#include <sys/regset.h>
+ 
+#define PR_NUM_GCREGS	NGREG
+#define PR_CONTEXT_TYPE	ucontext_t
+ 
+#define CONTEXT(_thread)	(&(_thread)->md.context)
+ 
+#define _MD_GET_SP(_t)		(_t)->md.context.uc_mcontext.gregs[CXT_SP]
+ 
+/*
+** Initialize the thread context preparing it to execute _main()
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)               \
+{                                                                   \
+    *status = PR_TRUE;  \
+    getcontext(CONTEXT(_thread));                                    \
+    CONTEXT(_thread)->uc_stack.ss_sp = (char*) (_thread)->stack->stackBottom; \
+    CONTEXT(_thread)->uc_stack.ss_size = (_thread)->stack->stackSize; \
+    _MD_GET_SP(_thread) = (greg_t) (_sp) - 64;             \
+    makecontext(CONTEXT(_thread), _main, 0);              \
+}
+ 
+#define _MD_SWITCH_CONTEXT(_thread)      \
+    if (!getcontext(CONTEXT(_thread))) { \
+        (_thread)->md.errcode = errno;      \
+        _PR_Schedule();                  \
+    }
+ 
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)   \
+{                                      \
+    ucontext_t *uc = CONTEXT(_thread); \
+    uc->uc_mcontext.gregs[CXT_V0] = 1; \
+    uc->uc_mcontext.gregs[CXT_A3] = 0; \
+    _MD_SET_CURRENT_THREAD(_thread);      \
+    errno = (_thread)->md.errcode;        \
+    setcontext(uc);                    \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_EARLY_INIT          	_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/* The following defines unwrapped versions of select() and poll(). */
+extern int _select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
+#define _MD_SELECT              _select
+
+#include <sys/poll.h>
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+#define _MD_POLL _poll
+ 
+#endif /* _PR_LOCAL_THREADS_ONLY */
+ 
+#undef	HAVE_STACK_GROWING_UP
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define	NEED_TIME_R
+#define NEED_STRFTIME_LOCK
+ 
+/*
+** Missing function prototypes
+*/
+extern int gethostname(char *name, int namelen);
+ 
+#endif /* nspr_sony_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sunos4.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sunos4.cfg
new file mode 100644
index 0000000..581d483
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sunos4.cfg
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SUNOS4
+#define SUNOS4
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#undef  HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* ifndef nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sunos4.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sunos4.h
new file mode 100644
index 0000000..0d62892
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_sunos4.h
@@ -0,0 +1,236 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_sunos_defs_h___
+#define nspr_sunos_defs_h___
+
+#include "md/sunos4.h"
+
+/* On SunOS 4, memset is declared in memory.h */
+#include <memory.h>
+#include <errno.h>
+#include <sys/syscall.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"sunos"
+#define _PR_SI_SYSNAME	"SUNOS"
+#define _PR_SI_ARCHITECTURE "sparc"
+#define PR_DLL_SUFFIX		".so.1.0"
+
+/*
+** For sunos type machines, don't specify an address because the
+** NetBSD/SPARC O.S. does the wrong thing.
+*/
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#undef	HAVE_WEAK_IO_SYMBOLS
+#undef	HAVE_WEAK_MALLOC_SYMBOLS
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define HAVE_BSD_FLOCK
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _MD_GET_SP(_t)    (_t)->md.context[2]
+
+#define PR_NUM_GCREGS	_JBLEN
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+    PR_BEGIN_MACRO				      \
+	int *context = (_thread)->md.context;	      \
+        *status = PR_TRUE;              \
+	asm("ta 3");					\
+	(void) setjmp(context);			      \
+	(_thread)->md.context[2] = (int) ((_sp) - 64); \
+	(_thread)->md.context[2] &= ~7;		\
+	(_thread)->md.context[3] = (int) _main;  \
+	(_thread)->md.context[4] = (int) _main + 4;  \
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    asm("ta 3");			\
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread);	 \
+    longjmp(CONTEXT(_thread), 1);    \
+}
+
+#pragma unknown_control_flow(longjmp)
+#pragma unknown_control_flow(setjmp)
+#pragma unknown_control_flow(_PR_Schedule)
+
+/*
+** Missing function prototypes
+*/
+
+extern int socket (int domain, int type, int protocol);
+extern int getsockname (int s, struct sockaddr *name, int *namelen);
+extern int getpeername (int s, struct sockaddr *name, int *namelen);
+extern int getsockopt (int s, int level, int optname, char* optval, int* optlen);
+extern int setsockopt (int s, int level, int optname, const char* optval, int optlen);
+extern int accept (int s, struct sockaddr *addr, int *addrlen);
+extern int listen (int s, int backlog);
+extern int brk(void *);
+extern void *sbrk(int);
+
+
+/* Machine-dependent (MD) data structures.  SunOS 4 has no native threads. */
+
+struct _MDThread {
+    jmp_buf context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/* These are copied from _solaris.h */
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+
+#endif /* nspr_sparc_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_symbian.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_symbian.cfg
new file mode 100644
index 0000000..2db9af7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_symbian.cfg
@@ -0,0 +1,202 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SYMBIAN
+#define SYMBIAN
+#endif
+
+#define PR_AF_INET6 0x0806  /* same as AF_INET6 */
+
+#ifdef __arm__
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_DOUBLE  8
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__WINS__)
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_DOUBLE  4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif
+
+#ifndef HAVE_LONG_LONG
+#define	HAVE_LONG_LONG
+#endif
+#if PR_ALIGN_OF_DOUBLE == 8
+#define HAVE_ALIGNED_DOUBLES
+#endif
+#if PR_ALIGN_OF_INT64 == 8
+#define HAVE_ALIGNED_LONGLONGS
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_symbian.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_symbian.h
new file mode 100644
index 0000000..1fef115
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_symbian.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_symbian_defs_h___
+#define nspr_symbian_defs_h___
+
+#include "prthread.h"
+
+/*
+ * Internal configuration macros
+ */
+
+#define _PR_SI_SYSNAME  "SYMBIAN"
+#if defined(__WINS__)
+#define _PR_SI_ARCHITECTURE "i386"
+#elif defined(__arm__)
+#define _PR_SI_ARCHITECTURE "arm"
+#else
+#error "Unknown CPU architecture"
+#endif
+#define PR_DLL_SUFFIX		".dll"
+
+#undef	HAVE_STACK_GROWING_UP
+
+#ifdef DYNAMIC_LIBRARY
+#define HAVE_DLL
+#define USE_DLFCN
+#endif
+
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define _PR_NO_LARGE_FILES
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#ifndef _PR_PTHREADS
+#error "Classic NSPR is not implemented"
+#endif
+
+extern void _MD_EarlyInit(void);
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT                  _PR_UnixInit
+#define _MD_GET_INTERVAL                _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC            _PR_UNIX_TicksPerSecond
+
+/* For writev() */
+#include <sys/uio.h>
+
+#endif /* nspr_symbian_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unix_errors.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unix_errors.h
new file mode 100644
index 0000000..a44cbb3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unix_errors.h
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prunixerrors_h___
+#define prunixerrors_h___
+
+#include <unistd.h>
+#include <stddef.h>
+
+PR_BEGIN_EXTERN_C
+
+extern void _MD_unix_map_default_error(int err);
+#define	_PR_MD_MAP_DEFAULT_ERROR	_MD_unix_map_default_error
+
+extern void _MD_unix_map_opendir_error(int err);
+#define	_PR_MD_MAP_OPENDIR_ERROR	_MD_unix_map_opendir_error
+
+extern void _MD_unix_map_closedir_error(int err);
+#define	_PR_MD_MAP_CLOSEDIR_ERROR	_MD_unix_map_closedir_error
+
+extern void _MD_unix_readdir_error(int err);
+#define	_PR_MD_MAP_READDIR_ERROR	_MD_unix_readdir_error
+
+extern void _MD_unix_map_unlink_error(int err);
+#define	_PR_MD_MAP_UNLINK_ERROR	_MD_unix_map_unlink_error
+
+extern void _MD_unix_map_stat_error(int err);
+#define	_PR_MD_MAP_STAT_ERROR	_MD_unix_map_stat_error
+
+extern void _MD_unix_map_fstat_error(int err);
+#define	_PR_MD_MAP_FSTAT_ERROR	_MD_unix_map_fstat_error
+
+extern void _MD_unix_map_rename_error(int err);
+#define	_PR_MD_MAP_RENAME_ERROR	_MD_unix_map_rename_error
+
+extern void _MD_unix_map_access_error(int err);
+#define	_PR_MD_MAP_ACCESS_ERROR	_MD_unix_map_access_error
+
+extern void _MD_unix_map_mkdir_error(int err);
+#define	_PR_MD_MAP_MKDIR_ERROR	_MD_unix_map_mkdir_error
+
+extern void _MD_unix_map_rmdir_error(int err);
+#define	_PR_MD_MAP_RMDIR_ERROR	_MD_unix_map_rmdir_error
+
+extern void _MD_unix_map_read_error(int err);
+#define	_PR_MD_MAP_READ_ERROR	_MD_unix_map_read_error
+
+extern void _MD_unix_map_write_error(int err);
+#define	_PR_MD_MAP_WRITE_ERROR	_MD_unix_map_write_error
+
+extern void _MD_unix_map_lseek_error(int err);
+#define	_PR_MD_MAP_LSEEK_ERROR	_MD_unix_map_lseek_error
+
+extern void _MD_unix_map_fsync_error(int err);
+#define	_PR_MD_MAP_FSYNC_ERROR	_MD_unix_map_fsync_error
+
+extern void _MD_unix_map_close_error(int err);
+#define	_PR_MD_MAP_CLOSE_ERROR	_MD_unix_map_close_error
+
+extern void _MD_unix_map_socket_error(int err);
+#define	_PR_MD_MAP_SOCKET_ERROR	_MD_unix_map_socket_error
+
+extern void _MD_unix_map_socketavailable_error(int err);
+#define	_PR_MD_MAP_SOCKETAVAILABLE_ERROR	_MD_unix_map_socketavailable_error
+
+extern void _MD_unix_map_recv_error(int err);
+#define	_PR_MD_MAP_RECV_ERROR	_MD_unix_map_recv_error
+
+extern void _MD_unix_map_recvfrom_error(int err);
+#define	_PR_MD_MAP_RECVFROM_ERROR	_MD_unix_map_recvfrom_error
+
+extern void _MD_unix_map_send_error(int err);
+#define	_PR_MD_MAP_SEND_ERROR	_MD_unix_map_send_error
+
+extern void _MD_unix_map_sendto_error(int err);
+#define	_PR_MD_MAP_SENDTO_ERROR	_MD_unix_map_sendto_error
+
+extern void _MD_unix_map_writev_error(int err);
+#define	_PR_MD_MAP_WRITEV_ERROR	_MD_unix_map_writev_error
+
+extern void _MD_unix_map_accept_error(int err);
+#define	_PR_MD_MAP_ACCEPT_ERROR	_MD_unix_map_accept_error
+
+extern void _MD_unix_map_connect_error(int err);
+#define	_PR_MD_MAP_CONNECT_ERROR	_MD_unix_map_connect_error
+
+extern void _MD_unix_map_bind_error(int err);
+#define	_PR_MD_MAP_BIND_ERROR	_MD_unix_map_bind_error
+
+extern void _MD_unix_map_listen_error(int err);
+#define	_PR_MD_MAP_LISTEN_ERROR	_MD_unix_map_listen_error
+
+extern void _MD_unix_map_shutdown_error(int err);
+#define	_PR_MD_MAP_SHUTDOWN_ERROR	_MD_unix_map_shutdown_error
+
+extern void _MD_unix_map_socketpair_error(int err);
+#define	_PR_MD_MAP_SOCKETPAIR_ERROR	_MD_unix_map_socketpair_error
+
+extern void _MD_unix_map_getsockname_error(int err);
+#define	_PR_MD_MAP_GETSOCKNAME_ERROR	_MD_unix_map_getsockname_error
+
+extern void _MD_unix_map_getpeername_error(int err);
+#define	_PR_MD_MAP_GETPEERNAME_ERROR	_MD_unix_map_getpeername_error
+
+extern void _MD_unix_map_getsockopt_error(int err);
+#define	_PR_MD_MAP_GETSOCKOPT_ERROR	_MD_unix_map_getsockopt_error
+
+extern void _MD_unix_map_setsockopt_error(int err);
+#define	_PR_MD_MAP_SETSOCKOPT_ERROR	_MD_unix_map_setsockopt_error
+
+extern void _MD_unix_map_open_error(int err);
+#define	_PR_MD_MAP_OPEN_ERROR	_MD_unix_map_open_error
+
+extern void _MD_unix_map_mmap_error(int err);
+#define	_PR_MD_MAP_MMAP_ERROR	_MD_unix_map_mmap_error
+
+extern void _MD_unix_map_gethostname_error(int err);
+#define	_PR_MD_MAP_GETHOSTNAME_ERROR	_MD_unix_map_gethostname_error
+
+extern void _MD_unix_map_select_error(int err);
+#define	_PR_MD_MAP_SELECT_ERROR	_MD_unix_map_select_error
+
+extern void _MD_unix_map_poll_error(int err);
+#define _PR_MD_MAP_POLL_ERROR _MD_unix_map_poll_error
+
+extern void _MD_unix_map_poll_revents_error(int err);
+#define _PR_MD_MAP_POLL_REVENTS_ERROR _MD_unix_map_poll_revents_error
+
+extern void _MD_unix_map_flock_error(int err);
+#define	_PR_MD_MAP_FLOCK_ERROR	_MD_unix_map_flock_error
+
+extern void _MD_unix_map_lockf_error(int err);
+#define	_PR_MD_MAP_LOCKF_ERROR	_MD_unix_map_lockf_error
+
+PR_END_EXTERN_C
+
+#endif /* prunixerrors_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixos.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixos.h
new file mode 100644
index 0000000..2374ee8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixos.h
@@ -0,0 +1,637 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prunixos_h___
+#define prunixos_h___
+
+/*
+ * If FD_SETSIZE is not defined on the command line, set the default value
+ * before include select.h
+ */
+/*
+ * Linux: FD_SETSIZE is defined in /usr/include/sys/select.h and should
+ * not be redefined.
+ */
+#if !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__) \
+    && !defined(DARWIN) && !defined(NEXTSTEP)
+#ifndef FD_SETSIZE
+#define FD_SETSIZE  4096
+#endif
+#endif
+
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "prio.h"
+#include "prmem.h"
+#include "prclist.h"
+
+/*
+ * For select(), fd_set, and struct timeval.
+ *
+ * In The Single UNIX(R) Specification, Version 2,
+ * the header file for select() is <sys/time.h>.
+ * In Version 3, the header file for select() is
+ * changed to <sys/select.h>.
+ *
+ * fd_set is defined in <sys/types.h>.  Usually
+ * <sys/time.h> includes <sys/types.h>, but on some
+ * older systems <sys/time.h> does not include
+ * <sys/types.h>, so we include it explicitly.
+ */
+#include <sys/time.h>
+#include <sys/types.h>
+#if defined(AIX) || defined(SYMBIAN)
+#include <sys/select.h>
+#endif
+
+#ifndef SYMBIAN
+#define HAVE_NETINET_TCP_H
+#endif
+
+#define _PR_HAVE_O_APPEND
+
+#define PR_DIRECTORY_SEPARATOR		'/'
+#define PR_DIRECTORY_SEPARATOR_STR	"/"
+#define PR_PATH_SEPARATOR		':'
+#define PR_PATH_SEPARATOR_STR		":"
+typedef int (*FARPROC)();
+
+/*
+ * intervals at which GLOBAL threads wakeup to check for pending interrupt
+ */
+#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
+extern PRIntervalTime intr_timeout_ticks;
+
+/*
+ * The bit flags for the in_flags and out_flags fields
+ * of _PR_UnixPollDesc
+ */
+#ifdef _PR_USE_POLL
+#define _PR_UNIX_POLL_READ    POLLIN
+#define _PR_UNIX_POLL_WRITE   POLLOUT
+#define _PR_UNIX_POLL_EXCEPT  POLLPRI
+#define _PR_UNIX_POLL_ERR     POLLERR
+#define _PR_UNIX_POLL_NVAL    POLLNVAL
+#define _PR_UNIX_POLL_HUP     POLLHUP
+#else /* _PR_USE_POLL */
+#define _PR_UNIX_POLL_READ    0x1
+#define _PR_UNIX_POLL_WRITE   0x2
+#define _PR_UNIX_POLL_EXCEPT  0x4
+#define _PR_UNIX_POLL_ERR     0x8
+#define _PR_UNIX_POLL_NVAL    0x10
+#define _PR_UNIX_POLL_HUP     0x20
+#endif /* _PR_USE_POLL */
+
+typedef struct _PRUnixPollDesc {
+	PRInt32 osfd;
+	PRInt16 in_flags;
+	PRInt16 out_flags;
+} _PRUnixPollDesc;
+
+typedef struct PRPollQueue {
+    PRCList links;        /* for linking PRPollQueue's together */
+    _PRUnixPollDesc *pds;        /* array of poll descriptors */
+    PRUintn npds;            /* length of the array */
+    PRPackedBool on_ioq;    /* is this on the async i/o work q? */
+    PRIntervalTime timeout;        /* timeout, in ticks */
+    struct PRThread *thr;
+} PRPollQueue;
+
+#define _PR_POLLQUEUE_PTR(_qp) \
+    ((PRPollQueue*) ((char*) (_qp) - offsetof(PRPollQueue,links)))
+
+
+extern PRInt32 _PR_WaitForMultipleFDs(
+    _PRUnixPollDesc *unixpds,
+    PRInt32 pdcnt,
+    PRIntervalTime timeout);
+extern void _PR_Unblock_IO_Wait(struct PRThread *thr);
+
+#if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY)
+#define _MD_CHECK_FOR_EXIT()
+#endif
+
+extern fd_set _pr_md_read_set, _pr_md_write_set, _pr_md_exception_set;
+extern PRInt16 _pr_md_read_cnt[], _pr_md_write_cnt[], _pr_md_exception_cnt[];
+extern PRInt32 _pr_md_ioq_max_osfd;
+extern PRUint32 _pr_md_ioq_timeout;
+
+struct _MDFileDesc {
+    int osfd;
+#if defined(LINUX) && defined(_PR_PTHREADS)
+    int tcp_nodelay;  /* used by pt_LinuxSendFile */
+#endif
+};
+
+struct _MDDir {
+	DIR *d;
+};
+
+struct _PRCPU;
+extern void _MD_unix_init_running_cpu(struct _PRCPU *cpu);
+
+/*
+** Make a redzone at both ends of the stack segment. Disallow access
+** to those pages of memory. It's ok if the mprotect call's don't
+** work - it just means that we don't really have a functional
+** redzone.
+*/
+#include <sys/mman.h>
+#ifndef PROT_NONE
+#define PROT_NONE 0x0
+#endif
+
+#if defined(DEBUG) && !defined(DARWIN) && !defined(NEXTSTEP)
+#if !defined(SOLARIS)	
+#include <string.h>  /* for memset() */
+#define _MD_INIT_STACK(ts,REDZONE)					\
+    PR_BEGIN_MACRO                 					\
+	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE);	\
+	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
+			REDZONE, PROT_NONE);				\
+    /*									\
+    ** Fill stack memory with something that turns into an illegal	\
+    ** pointer value. This will sometimes find runtime references to	\
+    ** uninitialized pointers. We don't do this for solaris because we	\
+    ** can use purify instead.						\
+    */									\
+    if (_pr_debugStacks) {						\
+	memset(ts->allocBase + REDZONE, 0xf7, ts->stackSize);		\
+    }									\
+    PR_END_MACRO
+#else	/* !SOLARIS	*/
+#define _MD_INIT_STACK(ts,REDZONE)					\
+    PR_BEGIN_MACRO                 					\
+	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE);	\
+	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
+			REDZONE, PROT_NONE);				\
+    PR_END_MACRO
+#endif	/* !SOLARIS	*/
+
+/*
+ * _MD_CLEAR_STACK
+ *	Allow access to the redzone pages; the access was turned off in
+ *	_MD_INIT_STACK.
+ */
+#define _MD_CLEAR_STACK(ts)						\
+    PR_BEGIN_MACRO                 					\
+	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_READ|PROT_WRITE);\
+	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
+			REDZONE, PROT_READ|PROT_WRITE);			\
+    PR_END_MACRO
+
+#else	/* DEBUG */
+
+#define _MD_INIT_STACK(ts,REDZONE)
+#define _MD_CLEAR_STACK(ts)
+
+#endif	/* DEBUG */
+
+#if !defined(SOLARIS) 
+
+#define PR_SET_INTSOFF(newval)
+
+#endif
+
+/************************************************************************/
+
+extern void _PR_UnixInit(void);
+
+extern void _PR_UnixCleanup(void);
+#define _MD_EARLY_CLEANUP _PR_UnixCleanup
+
+/************************************************************************/
+
+struct _MDProcess {
+    pid_t pid;
+};
+
+struct PRProcess;
+struct PRProcessAttr;
+
+/* Create a new process (fork() + exec()) */
+#define _MD_CREATE_PROCESS _MD_CreateUnixProcess
+extern struct PRProcess * _MD_CreateUnixProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _MD_DetachUnixProcess
+extern PRStatus _MD_DetachUnixProcess(struct PRProcess *process);
+
+/* Wait for a child process to terminate */
+#define _MD_WAIT_PROCESS _MD_WaitUnixProcess
+extern PRStatus _MD_WaitUnixProcess(struct PRProcess *process,
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _MD_KillUnixProcess
+extern PRStatus _MD_KillUnixProcess(struct PRProcess *process);
+
+/************************************************************************/
+
+extern void _MD_EnableClockInterrupts(void);
+extern void _MD_DisableClockInterrupts(void);
+
+#define _MD_START_INTERRUPTS			_MD_StartInterrupts
+#define _MD_STOP_INTERRUPTS				_MD_StopInterrupts
+#define _MD_DISABLE_CLOCK_INTERRUPTS	_MD_DisableClockInterrupts
+#define _MD_ENABLE_CLOCK_INTERRUPTS		_MD_EnableClockInterrupts
+#define _MD_BLOCK_CLOCK_INTERRUPTS		_MD_BlockClockInterrupts
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS	_MD_UnblockClockInterrupts
+
+/************************************************************************/
+
+extern void		_MD_InitCPUS(void);
+#define _MD_INIT_CPUS           _MD_InitCPUS
+
+extern void		_MD_Wakeup_CPUs(void);
+#define _MD_WAKEUP_CPUS _MD_Wakeup_CPUs
+
+#define _MD_PAUSE_CPU			_MD_PauseCPU
+
+#if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY)
+#define _MD_CLEANUP_BEFORE_EXIT()
+#endif
+
+#ifndef IRIX
+#define _MD_EXIT(status)		_exit(status)
+#endif
+
+/************************************************************************/
+
+#define _MD_GET_ENV				getenv
+#define _MD_PUT_ENV				putenv
+
+/************************************************************************/
+
+#define _MD_INIT_FILEDESC(fd)
+
+extern void		_MD_MakeNonblock(PRFileDesc *fd);
+#define _MD_MAKE_NONBLOCK			_MD_MakeNonblock		
+
+/************************************************************************/
+
+#if !defined(_PR_PTHREADS)
+
+extern void		_MD_InitSegs(void);
+extern PRStatus	_MD_AllocSegment(PRSegment *seg, PRUint32 size,
+				void *vaddr);
+extern void		_MD_FreeSegment(PRSegment *seg);
+
+#define _MD_INIT_SEGS			_MD_InitSegs
+#define _MD_ALLOC_SEGMENT		_MD_AllocSegment
+#define _MD_FREE_SEGMENT		_MD_FreeSegment
+
+#endif /* !defined(_PR_PTHREADS) */
+
+/************************************************************************/
+
+#if !defined(HPUX_LW_TIMER)
+#define _MD_INTERVAL_INIT()
+#endif
+#define _MD_INTERVAL_PER_MILLISEC()	(_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()	(_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/************************************************************************/
+
+#define _MD_ERRNO()             	(errno)
+#define _MD_GET_SOCKET_ERROR()		(errno)
+
+/************************************************************************/
+
+extern PRInt32 _MD_AvailableSocket(PRInt32 osfd);
+
+extern void _MD_StartInterrupts(void);
+extern void _MD_StopInterrupts(void);
+extern void _MD_DisableClockInterrupts(void);
+extern void _MD_BlockClockInterrupts(void);
+extern void _MD_UnblockClockInterrupts(void);
+extern void _MD_PauseCPU(PRIntervalTime timeout);
+
+extern PRStatus _MD_open_dir(struct _MDDir *, const char *);
+extern PRInt32  _MD_close_dir(struct _MDDir *);
+extern char *   _MD_read_dir(struct _MDDir *, PRIntn);
+extern PRInt32  _MD_open(const char *name, PRIntn osflags, PRIntn mode);
+extern PRInt32	_MD_delete(const char *name);
+extern PRInt32	_MD_getfileinfo(const char *fn, PRFileInfo *info);
+extern PRInt32  _MD_getfileinfo64(const char *fn, PRFileInfo64 *info);
+extern PRInt32  _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info);
+extern PRInt32  _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info);
+extern PRInt32	_MD_rename(const char *from, const char *to);
+extern PRInt32	_MD_access(const char *name, PRAccessHow how);
+extern PRInt32	_MD_mkdir(const char *name, PRIntn mode);
+extern PRInt32	_MD_rmdir(const char *name);
+extern PRInt32	_MD_accept_read(PRInt32 sock, PRInt32 *newSock,
+				PRNetAddr **raddr, void *buf, PRInt32 amount);
+extern PRInt32 	_PR_UnixSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+			PRTransmitFileFlags flags, PRIntervalTime timeout);
+
+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_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
+
+
+extern PRInt32		_MD_socket(int af, int type, int flags);
+#define _MD_SOCKET	_MD_socket
+extern PRInt32		_MD_connect(PRFileDesc *fd, const PRNetAddr *addr,
+								PRUint32 addrlen, PRIntervalTime timeout);
+#define _MD_CONNECT	_MD_connect
+extern PRInt32		_MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
+													PRIntervalTime timeout);
+#define _MD_ACCEPT	_MD_accept
+extern PRInt32		_MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
+#define _MD_BIND	_MD_bind
+extern PRInt32		_MD_listen(PRFileDesc *fd, PRIntn backlog);
+#define _MD_LISTEN	_MD_listen
+extern PRInt32		_MD_shutdown(PRFileDesc *fd, PRIntn how);
+#define _MD_SHUTDOWN	_MD_shutdown
+
+extern PRInt32		_MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, 
+                               PRIntn flags, PRIntervalTime timeout);
+#define _MD_RECV	_MD_recv
+extern PRInt32		_MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+									PRIntn flags, PRIntervalTime timeout);
+#define _MD_SEND	_MD_send
+extern PRInt32		_MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+						PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,
+											PRIntervalTime timeout);
+#define _MD_RECVFROM	_MD_recvfrom
+extern PRInt32 _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount,
+							PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen,
+												PRIntervalTime timeout);
+#define _MD_SENDTO	_MD_sendto
+extern PRInt32		_MD_writev(PRFileDesc *fd, const struct PRIOVec *iov,
+								PRInt32 iov_size, PRIntervalTime timeout);
+#define _MD_WRITEV	_MD_writev
+
+extern PRInt32		_MD_socketavailable(PRFileDesc *fd);
+#define	_MD_SOCKETAVAILABLE		_MD_socketavailable
+extern PRInt64		_MD_socketavailable64(PRFileDesc *fd);
+#define	_MD_SOCKETAVAILABLE64		_MD_socketavailable64
+
+#define	_MD_PIPEAVAILABLE		_MD_socketavailable
+
+extern PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds,
+												PRIntervalTime timeout);
+#define _MD_PR_POLL		_MD_pr_poll
+
+extern PRInt32		_MD_close(PRInt32 osfd);
+#define _MD_CLOSE_FILE	_MD_close
+extern PRInt32		_MD_lseek(PRFileDesc*, PRInt32, PRSeekWhence);
+#define _MD_LSEEK	_MD_lseek
+extern PRInt64		_MD_lseek64(PRFileDesc*, PRInt64, PRSeekWhence);
+#define _MD_LSEEK64	_MD_lseek64
+extern PRInt32		_MD_fsync(PRFileDesc *fd);
+#define _MD_FSYNC	_MD_fsync
+
+extern PRInt32 _MD_socketpair(int af, int type, int flags, PRInt32 *osfd);
+#define _MD_SOCKETPAIR		_MD_socketpair
+
+#define _MD_CLOSE_SOCKET	_MD_close
+
+#ifndef NO_NSPR_10_SUPPORT
+#define _MD_STAT	stat
+#endif
+
+extern PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
+											PRUint32 *addrlen);
+#define _MD_GETPEERNAME _MD_getpeername
+extern PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
+											PRUint32 *addrlen);
+#define _MD_GETSOCKNAME _MD_getsockname
+
+extern PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level,
+						PRInt32 optname, char* optval, PRInt32* optlen);
+#define _MD_GETSOCKOPT		_MD_getsockopt
+extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level,
+					PRInt32 optname, const char* optval, PRInt32 optlen);
+#define _MD_SETSOCKOPT		_MD_setsockopt
+
+extern PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable);
+#define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable
+
+extern void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported);
+#define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable
+
+extern void _MD_query_fd_inheritable(PRFileDesc *fd);
+#define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable
+
+extern PRStatus _MD_gethostname(char *name, PRUint32 namelen);
+#define _MD_GETHOSTNAME		_MD_gethostname
+
+extern PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen);
+#define _MD_GETSYSINFO		_MD_getsysinfo
+
+extern int _MD_unix_get_nonblocking_connect_error(int osfd);
+
+/* Memory-mapped files */
+
+struct _MDFileMap {
+    PRIntn prot;
+    PRIntn flags;
+    PRBool isAnonFM; /* when true, PR_CloseFileMap() must close the related fd */
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+#define _MD_GET_MEM_MAP_ALIGNMENT() PR_GetPageSize()
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+/*
+ * The standard (XPG4) gettimeofday() (from BSD) takes two arguments.
+ * On some SVR4 derivatives, gettimeofday() takes only one argument.
+ * The GETTIMEOFDAY macro is intended to hide this difference.
+ */
+#ifdef HAVE_SVID_GETTOD
+#define GETTIMEOFDAY(tp) gettimeofday(tp)
+#else
+#define GETTIMEOFDAY(tp) gettimeofday((tp), NULL)
+#endif
+
+#if defined(_PR_PTHREADS) && !defined(_PR_POLL_AVAILABLE)
+#define _PR_NEED_FAKE_POLL
+#endif
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+/*
+ * Some platforms don't have poll(), but our pthreads code calls poll().
+ * As a temporary measure, I implemented a fake poll() using select().
+ * Here are the struct and macro definitions copied from sys/poll.h
+ * on Solaris 2.5.
+ */
+
+struct pollfd {
+    int fd;
+    short events;
+    short revents;
+};
+
+/* poll events */
+
+#define	POLLIN		0x0001		/* fd is readable */
+#define	POLLPRI		0x0002		/* high priority info at fd */
+#define	POLLOUT		0x0004		/* fd is writeable (won't block) */
+#define	POLLRDNORM	0x0040		/* normal data is readable */
+#define	POLLWRNORM	POLLOUT
+#define	POLLRDBAND	0x0080		/* out-of-band data is readable */
+#define	POLLWRBAND	0x0100		/* out-of-band data is writeable */
+
+#define	POLLNORM	POLLRDNORM
+
+#define	POLLERR		0x0008		/* fd has error condition */
+#define	POLLHUP		0x0010		/* fd has been hung up on */
+#define	POLLNVAL	0x0020		/* invalid pollfd entry */
+
+extern int poll(struct pollfd *, unsigned long, int);
+
+#endif /* _PR_NEED_FAKE_POLL */
+
+/*
+** A vector of the UNIX I/O calls we use. These are here to smooth over
+** the rough edges needed for large files. All of NSPR's implmentaions
+** go through this vector using syntax of the form
+**      result = _md_iovector.xxx64(args);
+*/
+
+#if defined(SOLARIS2_5)
+/*
+** Special case: Solaris 2.5.1
+** Solaris starts to have 64-bit file I/O in 2.6.  We build on Solaris
+** 2.5.1 so that we can use the same binaries on both Solaris 2.5.1 and
+** 2.6.  At run time, we detect whether 64-bit file I/O is available by
+** looking up the 64-bit file function symbols in libc.  At build time,
+** we need to define the 64-bit file I/O datatypes that are compatible
+** with their definitions on Solaris 2.6.
+*/
+typedef PRInt64 off64_t;
+typedef PRUint64 ino64_t;
+typedef PRInt64 blkcnt64_t;
+struct stat64 {
+    dev_t st_dev;
+    long st_pad1[3];
+    ino64_t st_ino;
+    mode_t st_mode;
+    nlink_t st_nlink;
+    uid_t st_uid;
+    gid_t st_gid;
+    dev_t st_rdev;
+    long t_pad2[2];
+    off64_t st_size;
+    timestruc_t st_atim;
+    timestruc_t st_mtim;
+    timestruc_t st_ctim;
+    long st_blksize;
+    blkcnt64_t st_blocks;
+    char st_fstype[_ST_FSTYPSZ];
+    long st_pad4[8];
+};
+typedef struct stat64 _MDStat64;
+typedef off64_t _MDOff64_t;
+
+#elif defined(_PR_HAVE_OFF64_T)
+typedef struct stat64 _MDStat64;
+typedef off64_t _MDOff64_t;
+#elif defined(_PR_HAVE_LARGE_OFF_T)
+typedef struct stat _MDStat64;
+typedef off_t _MDOff64_t;
+#elif defined(_PR_NO_LARGE_FILES)
+typedef struct stat _MDStat64;
+typedef PRInt64 _MDOff64_t;
+#else
+#error "I don't know yet"
+#endif
+
+typedef PRIntn (*_MD_Fstat64)(PRIntn osfd, _MDStat64 *buf);
+typedef PRIntn (*_MD_Open64)(const char *path, int oflag, ...);
+typedef PRIntn (*_MD_Stat64)(const char *path, _MDStat64 *buf);
+typedef _MDOff64_t (*_MD_Lseek64)(PRIntn osfd, _MDOff64_t, PRIntn whence);
+typedef void* (*_MD_Mmap64)(
+    void *addr, PRSize len, PRIntn prot, PRIntn flags,
+    PRIntn fildes, _MDOff64_t offset);
+struct _MD_IOVector
+{
+    _MD_Open64 _open64;
+    _MD_Mmap64 _mmap64;
+    _MD_Stat64 _stat64;
+    _MD_Fstat64 _fstat64;
+    _MD_Lseek64 _lseek64;
+};
+extern struct _MD_IOVector _md_iovector;
+
+#endif /* prunixos_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware.cfg
new file mode 100644
index 0000000..796e748
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware.cfg
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef UNIXWARE
+#define UNIXWARE
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware.h
new file mode 100644
index 0000000..bdc084f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware.h
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_unixware_defs_h___
+#define nspr_unixware_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"unixware"
+#define _PR_SI_SYSNAME		"UnixWare"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE	 	0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ST_ATIM_UNION
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_NETCONFIG
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define HAVE_STRERROR
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP setjmp
+#define _LONGJMP longjmp
+#define _PR_CONTEXT_TYPE         jmp_buf
+#define _MD_GET_SP(_t)           (_t)->md.context[4]
+#define _PR_NUM_GCREGS	_JBLEN
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+{								  \
+    *status = PR_TRUE; \
+    if(_SETJMP(CONTEXT(_thread))) (*_main)(); \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!_SETJMP(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    _LONGJMP(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures.
+ * Don't use SVR4 native threads (yet). 
+ */
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *execptfds, struct timeval *timeout);
+#define _MD_SELECT _select
+
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+#endif /* nspr_unixware_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware7.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware7.cfg
new file mode 100644
index 0000000..6444b00
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_unixware7.cfg
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef UNIXWARE
+#define UNIXWARE
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+#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
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win32_errors.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win32_errors.h
new file mode 100644
index 0000000..d5d8b71
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win32_errors.h
@@ -0,0 +1,154 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_win32_errors_h___
+#define nspr_win32_errors_h___
+
+#include <windows.h>
+#include <winsock.h>
+#include <errno.h>
+
+
+extern void _MD_win32_map_default_error(PRInt32 err);
+#define _PR_MD_MAP_DEFAULT_ERROR	_MD_win32_map_default_error
+
+extern void _MD_win32_map_opendir_error(PRInt32 err);
+#define	_PR_MD_MAP_OPENDIR_ERROR	_MD_win32_map_opendir_error
+
+extern void _MD_win32_map_closedir_error(PRInt32 err);
+#define	_PR_MD_MAP_CLOSEDIR_ERROR	_MD_win32_map_closedir_error
+
+extern void _MD_unix_readdir_error(PRInt32 err);
+#define	_PR_MD_MAP_READDIR_ERROR	_MD_unix_readdir_error
+
+extern void _MD_win32_map_delete_error(PRInt32 err);
+#define	_PR_MD_MAP_DELETE_ERROR	_MD_win32_map_delete_error
+
+extern void _MD_win32_map_stat_error(PRInt32 err);
+#define	_PR_MD_MAP_STAT_ERROR	_MD_win32_map_stat_error
+
+extern void _MD_win32_map_fstat_error(PRInt32 err);
+#define	_PR_MD_MAP_FSTAT_ERROR	_MD_win32_map_fstat_error
+
+extern void _MD_win32_map_rename_error(PRInt32 err);
+#define	_PR_MD_MAP_RENAME_ERROR	_MD_win32_map_rename_error
+
+extern void _MD_win32_map_access_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCESS_ERROR	_MD_win32_map_access_error
+
+extern void _MD_win32_map_mkdir_error(PRInt32 err);
+#define	_PR_MD_MAP_MKDIR_ERROR	_MD_win32_map_mkdir_error
+
+extern void _MD_win32_map_rmdir_error(PRInt32 err);
+#define	_PR_MD_MAP_RMDIR_ERROR	_MD_win32_map_rmdir_error
+
+extern void _MD_win32_map_read_error(PRInt32 err);
+#define	_PR_MD_MAP_READ_ERROR	_MD_win32_map_read_error
+
+extern void _MD_win32_map_transmitfile_error(PRInt32 err);
+#define	_PR_MD_MAP_TRANSMITFILE_ERROR	_MD_win32_map_transmitfile_error
+
+extern void _MD_win32_map_write_error(PRInt32 err);
+#define	_PR_MD_MAP_WRITE_ERROR	_MD_win32_map_write_error
+
+extern void _MD_win32_map_lseek_error(PRInt32 err);
+#define	_PR_MD_MAP_LSEEK_ERROR	_MD_win32_map_lseek_error
+
+extern void _MD_win32_map_fsync_error(PRInt32 err);
+#define	_PR_MD_MAP_FSYNC_ERROR	_MD_win32_map_fsync_error
+
+extern void _MD_win32_map_close_error(PRInt32 err);
+#define	_PR_MD_MAP_CLOSE_ERROR	_MD_win32_map_close_error
+
+extern void _MD_win32_map_socket_error(PRInt32 err);
+#define	_PR_MD_MAP_SOCKET_ERROR	_MD_win32_map_socket_error
+
+extern void _MD_win32_map_recv_error(PRInt32 err);
+#define	_PR_MD_MAP_RECV_ERROR	_MD_win32_map_recv_error
+
+extern void _MD_win32_map_recvfrom_error(PRInt32 err);
+#define	_PR_MD_MAP_RECVFROM_ERROR	_MD_win32_map_recvfrom_error
+
+extern void _MD_win32_map_send_error(PRInt32 err);
+#define	_PR_MD_MAP_SEND_ERROR	_MD_win32_map_send_error
+
+extern void _MD_win32_map_sendto_error(PRInt32 err);
+#define	_PR_MD_MAP_SENDTO_ERROR	_MD_win32_map_sendto_error
+
+extern void _MD_win32_map_accept_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCEPT_ERROR	_MD_win32_map_accept_error
+
+extern void _MD_win32_map_acceptex_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCEPTEX_ERROR	_MD_win32_map_acceptex_error
+
+extern PRInt32 _MD_win32_map_connect_error(PRInt32 err);
+#define	_PR_MD_MAP_CONNECT_ERROR	_MD_win32_map_connect_error
+
+extern void _MD_win32_map_bind_error(PRInt32 err);
+#define	_PR_MD_MAP_BIND_ERROR	_MD_win32_map_bind_error
+
+extern void _MD_win32_map_listen_error(PRInt32 err);
+#define	_PR_MD_MAP_LISTEN_ERROR	_MD_win32_map_listen_error
+
+extern void _MD_win32_map_shutdown_error(PRInt32 err);
+#define	_PR_MD_MAP_SHUTDOWN_ERROR	_MD_win32_map_shutdown_error
+
+extern void _MD_win32_map_getsockname_error(PRInt32 err);
+#define	_PR_MD_MAP_GETSOCKNAME_ERROR	_MD_win32_map_getsockname_error
+
+extern void _MD_win32_map_getpeername_error(PRInt32 err);
+#define	_PR_MD_MAP_GETPEERNAME_ERROR	_MD_win32_map_getpeername_error
+
+extern void _MD_win32_map_getsockopt_error(PRInt32 err);
+#define	_PR_MD_MAP_GETSOCKOPT_ERROR	_MD_win32_map_getsockopt_error
+
+extern void _MD_win32_map_setsockopt_error(PRInt32 err);
+#define	_PR_MD_MAP_SETSOCKOPT_ERROR	_MD_win32_map_setsockopt_error
+
+extern void _MD_win32_map_open_error(PRInt32 err);
+#define	_PR_MD_MAP_OPEN_ERROR	_MD_win32_map_open_error
+
+extern void _MD_win32_map_gethostname_error(PRInt32 err);
+#define	_PR_MD_MAP_GETHOSTNAME_ERROR	_MD_win32_map_gethostname_error
+
+extern void _MD_win32_map_select_error(PRInt32 err);
+#define	_PR_MD_MAP_SELECT_ERROR	_MD_win32_map_select_error
+
+extern void _MD_win32_map_lockf_error(int err);
+#define _PR_MD_MAP_LOCKF_ERROR  _MD_win32_map_lockf_error
+
+#endif /* nspr_win32_errors_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win95.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win95.cfg
new file mode 100644
index 0000000..8a84f68
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win95.cfg
@@ -0,0 +1,310 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_PC
+#define XP_PC
+#endif
+
+#ifndef WIN32
+#define WIN32
+#endif
+
+#ifdef _WIN32_WCE
+#ifndef WINCE
+#define WINCE
+#endif
+#else
+#ifndef WIN95
+#define WIN95
+#endif
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD	4
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	32
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	5
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	4
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2	2
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#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_WORD	8
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	64
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	8
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#elif defined(_M_IA64) || defined(_IA64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#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_WORD	8
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	64
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	8
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#elif defined(_M_ARM) || defined(_ARM_)
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD    32
+#define PR_BITS_PER_DWORD   64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2   5
+#define PR_BITS_PER_DWORD_LOG2  6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD    4
+#define PR_ALIGN_OF_DWORD   8
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#else /* defined(_M_IX86) || defined(_X86_) */
+
+#error unknown processor architecture
+
+#endif /* defined(_M_IX86) || defined(_X86_) */
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE      PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT     PR_BYTES_PER_SHORT
+#define BYTES_PER_INT       PR_BYTES_PER_INT
+#define BYTES_PER_INT64     PR_BYTES_PER_INT64
+#define BYTES_PER_LONG      PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT     PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE    PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD      PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD     PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE       PR_BITS_PER_BYTE
+#define BITS_PER_SHORT      PR_BITS_PER_SHORT
+#define BITS_PER_INT        PR_BITS_PER_INT
+#define BITS_PER_INT64      PR_BITS_PER_INT64
+#define BITS_PER_LONG       PR_BITS_PER_LONG
+#define BITS_PER_FLOAT      PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE     PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD       PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2  PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2   PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2  PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2    PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2  PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT      PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT        PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG       PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64      PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT      PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE     PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER    PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD       PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2		PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2    PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2    PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win95.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win95.h
new file mode 100644
index 0000000..c0d3aa6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_win95.h
@@ -0,0 +1,570 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_win95_defs_h___
+#define nspr_win95_defs_h___
+
+#include "prio.h"
+
+#include <windows.h>
+#include <winsock.h>
+#include <errno.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH      "win32"
+#define _PR_SI_SYSNAME        "WIN95"
+#if defined(_M_IX86) || defined(_X86_)
+#define _PR_SI_ARCHITECTURE   "x86"
+#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)
+#define _PR_SI_ARCHITECTURE   "x86-64"
+#elif defined(_M_IA64) || defined(_IA64_)
+#define _PR_SI_ARCHITECTURE   "ia64"
+#elif defined(_M_ARM) || defined(_ARM_)
+#define _PR_SI_ARCHITECTURE   "arm"
+#else
+#error unknown processor architecture
+#endif
+
+#define HAVE_DLL
+#undef  HAVE_THREAD_AFFINITY
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#ifndef _PR_INET6
+#define AF_INET6 23
+/* newer ws2tcpip.h provides these */
+#ifndef AI_CANONNAME
+#define AI_CANONNAME 0x2
+#define AI_NUMERICHOST 0x4
+#define NI_NUMERICHOST 0x02
+struct addrinfo {
+    int ai_flags;
+    int ai_family;
+    int ai_socktype;
+    int ai_protocol;
+    size_t ai_addrlen;
+    char *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#endif
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* isomorphic to struct in6_addr on Windows */
+struct _md_in6_addr {
+    union {
+        PRUint8  _S6_u8[16];
+        PRUint16 _S6_u16[8];
+    } _S6_un;
+};
+/* isomorphic to struct sockaddr_in6 on Windows */
+struct _md_sockaddr_in6 {
+    PRInt16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+};
+#endif
+#define _PR_HAVE_THREADSAFE_GETHOST
+#define _PR_HAVE_ATOMIC_OPS
+#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY
+
+/* --- Common User-Thread/Native-Thread Definitions --------------------- */
+
+/* --- Globals --- */
+extern struct PRLock                      *_pr_schedLock;
+
+/* --- Typedefs --- */
+typedef void (*FiberFunc)(void *);
+
+#define PR_NUM_GCREGS           8
+typedef PRInt32	                PR_CONTEXT_TYPE[PR_NUM_GCREGS];
+#define GC_VMBASE               0x40000000
+#define GC_VMLIMIT              0x00FFFFFF
+
+#define _MD_MAGIC_THREAD	0x22222222
+#define _MD_MAGIC_THREADSTACK	0x33333333
+#define _MD_MAGIC_SEGMENT	0x44444444
+#define _MD_MAGIC_DIR		0x55555555
+#define _MD_MAGIC_CV        0x66666666
+
+struct _MDCPU {
+    int              unused;
+};
+
+struct _MDThread {
+    HANDLE           blocked_sema;      /* Threads block on this when waiting
+                                         * for IO or CondVar.
+                                         */
+    PRBool           inCVWaitQueue;     /* PR_TRUE if the thread is in the
+                                         * wait queue of some cond var.
+                                         * PR_FALSE otherwise.  */
+    HANDLE           handle;            /* Win32 thread handle */
+    PRUint32         id;
+    void            *sp;                /* only valid when suspended */
+    PRUint32         magic;             /* for debugging */
+    PR_CONTEXT_TYPE  gcContext;         /* Thread context for GC */
+    struct PRThread *prev, *next;       /* used by the cvar wait queue to
+                                         * chain the PRThread structures
+                                         * together */
+    void (*start)(void *);              /* used by _PR_MD_CREATE_THREAD to
+                                         * pass its 'start' argument to
+                                         * pr_root. */
+};
+
+struct _MDThreadStack {
+    PRUint32           magic;          /* for debugging */
+};
+
+struct _MDSegment {
+    PRUint32           magic;          /* for debugging */
+};
+
+#undef PROFILE_LOCKS
+
+struct _MDDir {
+    HANDLE           d_hdl;
+    WIN32_FIND_DATAA d_entry;
+    PRBool           firstEntry;     /* Is this the entry returned
+                                      * by FindFirstFile()? */
+    PRUint32         magic;          /* for debugging */
+};
+
+#ifdef MOZ_UNICODE
+struct _MDDirUTF16 {
+    HANDLE           d_hdl;
+    WIN32_FIND_DATAW d_entry;
+    PRBool           firstEntry;     /* Is this the entry returned
+                                      * by FindFirstFileW()? */
+    PRUint32         magic;          /* for debugging */
+};
+#endif /* MOZ_UNICODE */
+
+struct _MDCVar {
+    PRUint32 magic;
+    struct PRThread *waitHead, *waitTail;  /* the wait queue: a doubly-
+                                            * linked list of threads
+                                            * waiting on this condition
+                                            * variable */
+    PRIntn nwait;                          /* number of threads in the
+                                            * wait queue */
+};
+
+#define _MD_CV_NOTIFIED_LENGTH 6
+typedef struct _MDNotified _MDNotified;
+struct _MDNotified {
+    PRIntn length;                     /* # of used entries in this
+                                        * structure */
+    struct {
+        struct _MDCVar *cv;            /* the condition variable notified */
+        PRIntn times;                  /* and the number of times notified */
+        struct PRThread *notifyHead;   /* list of threads to wake up */
+    } cv[_MD_CV_NOTIFIED_LENGTH];
+    _MDNotified *link;                 /* link to another of these, or NULL */
+};
+
+struct _MDLock {
+    CRITICAL_SECTION mutex;          /* this is recursive on NT */
+
+    /*
+     * When notifying cvars, there is no point in actually
+     * waking up the threads waiting on the cvars until we've
+     * released the lock.  So, we temporarily record the cvars.
+     * When doing an unlock, we'll then wake up the waiting threads.
+     */
+    struct _MDNotified notified;     /* array of conditions notified */
+#ifdef PROFILE_LOCKS
+    PRInt32 hitcount;
+    PRInt32 misscount;
+#endif
+};
+
+struct _MDSemaphore {
+    HANDLE           sem;
+};
+
+struct _MDFileDesc {
+    PROsfd osfd;     /* The osfd can come from one of three spaces:
+                      * - For stdin, stdout, and stderr, we are using
+                      *   the libc file handle (0, 1, 2), which is an int.
+                      * - For files and pipes, we are using Win32 HANDLE,
+                      *   which is a void*.
+                      * - For sockets, we are using Winsock SOCKET, which
+                      *   is a u_int.
+                      */
+};
+
+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(PROsfd 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
+
+/* --- UTF16 IO stuff --- */
+extern PRBool _pr_useUnicode;
+#ifdef MOZ_UNICODE
+#define _MD_OPEN_FILE_UTF16           _PR_MD_OPEN_FILE_UTF16
+#define _MD_OPEN_DIR_UTF16            _PR_MD_OPEN_DIR_UTF16
+#define _MD_READ_DIR_UTF16            _PR_MD_READ_DIR_UTF16
+#define _MD_CLOSE_DIR_UTF16           _PR_MD_CLOSE_DIR_UTF16
+#define _MD_GETFILEINFO64_UTF16       _PR_MD_GETFILEINFO64_UTF16
+#endif /* MOZ_UNICODE */
+
+/* --- Socket IO stuff --- */
+extern void _PR_MD_InitSockets(void);
+extern void _PR_MD_CleanupSockets(void);
+#define _MD_EACCES                WSAEACCES
+#define _MD_EADDRINUSE            WSAEADDRINUSE
+#define _MD_EADDRNOTAVAIL         WSAEADDRNOTAVAIL
+#define _MD_EAFNOSUPPORT          WSAEAFNOSUPPORT
+#define _MD_EAGAIN                WSAEWOULDBLOCK
+#define _MD_EALREADY              WSAEALREADY
+#define _MD_EBADF                 WSAEBADF
+#define _MD_ECONNREFUSED          WSAECONNREFUSED
+#define _MD_ECONNRESET            WSAECONNRESET
+#define _MD_EFAULT                WSAEFAULT
+#define _MD_EINPROGRESS           WSAEINPROGRESS
+#define _MD_EINTR                 WSAEINTR
+#define _MD_EINVAL                EINVAL
+#define _MD_EISCONN               WSAEISCONN
+#define _MD_ENETUNREACH           WSAENETUNREACH
+#define _MD_ENOENT                ENOENT
+#define _MD_ENOTCONN              WSAENOTCONN
+#define _MD_ENOTSOCK              WSAENOTSOCK
+#define _MD_EOPNOTSUPP            WSAEOPNOTSUPP
+#define _MD_EWOULDBLOCK           WSAEWOULDBLOCK
+#define _MD_GET_SOCKET_ERROR()    WSAGetLastError()
+#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
+
+#define _MD_INIT_FILEDESC(fd)
+extern void _MD_MakeNonblock(PRFileDesc *f);
+#define _MD_MAKE_NONBLOCK             _MD_MakeNonblock
+#define _MD_INIT_FD_INHERITABLE       _PR_MD_INIT_FD_INHERITABLE
+#define _MD_QUERY_FD_INHERITABLE      _PR_MD_QUERY_FD_INHERITABLE
+#define _MD_SHUTDOWN                  _PR_MD_SHUTDOWN
+#define _MD_LISTEN                    _PR_MD_LISTEN
+extern PRInt32 _MD_CloseSocket(PROsfd osfd);
+#define _MD_CLOSE_SOCKET              _MD_CloseSocket
+#define _MD_SENDTO                    _PR_MD_SENDTO
+#define _MD_RECVFROM                  _PR_MD_RECVFROM
+#define _MD_SOCKETPAIR(s, type, proto, sv) -1
+#define _MD_GETSOCKNAME               _PR_MD_GETSOCKNAME
+#define _MD_GETPEERNAME               _PR_MD_GETPEERNAME
+#define _MD_GETSOCKOPT                _PR_MD_GETSOCKOPT
+#define _MD_SETSOCKOPT                _PR_MD_SETSOCKOPT
+#define _MD_SET_FD_INHERITABLE        _PR_MD_SET_FD_INHERITABLE
+#define _MD_SELECT                    select
+#define _MD_FSYNC                     _PR_MD_FSYNC
+#define READ_FD                       1
+#define WRITE_FD                      2
+
+#define _MD_INIT_ATOMIC()
+#if defined(_M_IX86) || defined(_X86_)
+#define _MD_ATOMIC_INCREMENT          _PR_MD_ATOMIC_INCREMENT
+#define _MD_ATOMIC_ADD          	  _PR_MD_ATOMIC_ADD
+#define _MD_ATOMIC_DECREMENT          _PR_MD_ATOMIC_DECREMENT
+#else /* non-x86 processors */
+#define _MD_ATOMIC_INCREMENT(x)       InterlockedIncrement((PLONG)x)
+#define _MD_ATOMIC_ADD(ptr,val)    (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val)
+#define _MD_ATOMIC_DECREMENT(x)       InterlockedDecrement((PLONG)x)
+#endif /* x86 */
+#define _MD_ATOMIC_SET(x,y)           InterlockedExchange((PLONG)x, (LONG)y)
+
+#define _MD_INIT_IO                   _PR_MD_INIT_IO
+
+
+/* win95 doesn't have async IO */
+#define _MD_SOCKET                    _PR_MD_SOCKET
+extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd);
+#define _MD_SOCKETAVAILABLE           _MD_SocketAvailable
+#define _MD_PIPEAVAILABLE             _PR_MD_PIPEAVAILABLE
+#define _MD_CONNECT                   _PR_MD_CONNECT
+extern PROsfd _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
+        PRIntervalTime timeout);
+#define _MD_ACCEPT                    _MD_Accept
+#define _MD_BIND                      _PR_MD_BIND
+#define _MD_RECV                      _PR_MD_RECV
+#define _MD_SEND                      _PR_MD_SEND
+#define _MD_PR_POLL                   _PR_MD_PR_POLL
+
+/* --- Scheduler stuff --- */
+// #define _MD_PAUSE_CPU                 _PR_MD_PAUSE_CPU
+#define _MD_PAUSE_CPU
+
+/* --- DIR stuff --- */
+#define PR_DIRECTORY_SEPARATOR        '\\'
+#define PR_DIRECTORY_SEPARATOR_STR    "\\"
+#define PR_PATH_SEPARATOR		';'
+#define PR_PATH_SEPARATOR_STR		";"
+#define _MD_ERRNO()                   GetLastError()
+#define _MD_OPEN_DIR                  _PR_MD_OPEN_DIR
+#define _MD_CLOSE_DIR                 _PR_MD_CLOSE_DIR
+#define _MD_READ_DIR                  _PR_MD_READ_DIR
+
+/* --- Segment stuff --- */
+#define _MD_INIT_SEGS()
+#define _MD_ALLOC_SEGMENT(seg, size, vaddr)   0
+#define _MD_FREE_SEGMENT(seg)
+
+/* --- Environment Stuff --- */
+#define _MD_GET_ENV                 _PR_MD_GET_ENV
+#define _MD_PUT_ENV                 _PR_MD_PUT_ENV
+
+/* --- Threading Stuff --- */
+#define _MD_DEFAULT_STACK_SIZE            0
+#define _MD_INIT_THREAD             _PR_MD_INIT_THREAD
+#define _MD_INIT_ATTACHED_THREAD    _PR_MD_INIT_THREAD
+#define _MD_CREATE_THREAD           _PR_MD_CREATE_THREAD
+#define _MD_YIELD                   _PR_MD_YIELD
+#define _MD_SET_PRIORITY            _PR_MD_SET_PRIORITY
+#define _MD_CLEAN_THREAD            _PR_MD_CLEAN_THREAD
+#define _MD_SETTHREADAFFINITYMASK   _PR_MD_SETTHREADAFFINITYMASK
+#define _MD_GETTHREADAFFINITYMASK   _PR_MD_GETTHREADAFFINITYMASK
+#define _MD_EXIT_THREAD             _PR_MD_EXIT_THREAD
+#define _MD_EXIT                    _PR_MD_EXIT
+#define _MD_SUSPEND_THREAD          _PR_MD_SUSPEND_THREAD
+#define _MD_RESUME_THREAD           _PR_MD_RESUME_THREAD
+#define _MD_SUSPEND_CPU             _PR_MD_SUSPEND_CPU
+#define _MD_RESUME_CPU              _PR_MD_RESUME_CPU
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_END_RESUME_ALL()
+
+/* --- Lock stuff --- */
+#define _PR_LOCK                      _MD_LOCK
+#define _PR_UNLOCK					  _MD_UNLOCK
+
+#define _MD_NEW_LOCK(lock)            (InitializeCriticalSection(&((lock)->mutex)),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS)
+#define _MD_FREE_LOCK(lock)           DeleteCriticalSection(&((lock)->mutex))
+#define _MD_LOCK(lock)                EnterCriticalSection(&((lock)->mutex))
+#define _MD_TEST_AND_LOCK(lock)       (EnterCriticalSection(&((lock)->mutex)),0)
+#define _MD_UNLOCK                    _PR_MD_UNLOCK
+
+/* --- lock and cv waiting --- */
+#define _MD_WAIT                      _PR_MD_WAIT
+#define _MD_WAKEUP_WAITER             _PR_MD_WAKEUP_WAITER
+
+/* --- CVar ------------------- */
+#define _MD_WAIT_CV					  _PR_MD_WAIT_CV
+#define _MD_NEW_CV					  _PR_MD_NEW_CV
+#define _MD_FREE_CV					  _PR_MD_FREE_CV
+#define _MD_NOTIFY_CV				  _PR_MD_NOTIFY_CV	
+#define _MD_NOTIFYALL_CV			  _PR_MD_NOTIFYALL_CV
+
+   /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
+// extern  struct _MDLock              _pr_ioq_lock;
+#define _MD_IOQ_LOCK()                
+#define _MD_IOQ_UNLOCK()              
+
+
+/* --- Initialization stuff --- */
+#define _MD_START_INTERRUPTS()
+#define _MD_STOP_INTERRUPTS()
+#define _MD_DISABLE_CLOCK_INTERRUPTS()
+#define _MD_ENABLE_CLOCK_INTERRUPTS()
+#define _MD_BLOCK_CLOCK_INTERRUPTS()
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _MD_EARLY_INIT                _PR_MD_EARLY_INIT
+#define _MD_FINAL_INIT()
+#define _MD_EARLY_CLEANUP()
+#define _MD_INIT_CPUS()
+#define _MD_INIT_RUNNING_CPU(cpu)
+
+struct PRProcess;
+struct PRProcessAttr;
+
+#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess
+extern struct PRProcess * _PR_CreateWindowsProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess
+extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process);
+
+/* --- Wait for a child process to terminate --- */
+#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess
+extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, 
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _PR_KillWindowsProcess
+extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
+
+#define _MD_CLEANUP_BEFORE_EXIT           _PR_MD_CLEANUP_BEFORE_EXIT
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+    PR_BEGIN_MACRO \
+    *status = PR_TRUE; \
+    PR_END_MACRO
+#define _MD_SWITCH_CONTEXT
+#define _MD_RESTORE_CONTEXT
+
+/* --- Intervals --- */
+#define _MD_INTERVAL_INIT                 _PR_MD_INTERVAL_INIT
+#define _MD_GET_INTERVAL                  _PR_MD_GET_INTERVAL
+#define _MD_INTERVAL_PER_SEC              _PR_MD_INTERVAL_PER_SEC
+#define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/* --- Time --- */
+extern void _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm);
+
+#ifdef WINCE
+extern void _MD_InitTime(void);
+extern void _MD_CleanupTime(void);
+#endif
+
+/* --- Native-Thread Specific Definitions ------------------------------- */
+
+extern struct PRThread * _MD_CURRENT_THREAD(void);
+
+#ifdef _PR_USE_STATIC_TLS
+extern __declspec(thread) struct PRThread *_pr_currentThread;
+#define _MD_GET_ATTACHED_THREAD() _pr_currentThread
+#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
+
+extern __declspec(thread) struct PRThread *_pr_thread_last_run;
+#define _MD_LAST_THREAD() _pr_thread_last_run
+#define _MD_SET_LAST_THREAD(_thread) (_pr_thread_last_run = 0)
+
+extern __declspec(thread) struct _PRCPU *_pr_currentCPU;
+#define _MD_CURRENT_CPU() _pr_currentCPU
+#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = 0)
+#else /* _PR_USE_STATIC_TLS */
+extern DWORD _pr_currentThreadIndex;
+#define _MD_GET_ATTACHED_THREAD() ((PRThread *) TlsGetValue(_pr_currentThreadIndex))
+#define _MD_SET_CURRENT_THREAD(_thread) TlsSetValue(_pr_currentThreadIndex, (_thread))
+
+extern DWORD _pr_lastThreadIndex;
+#define _MD_LAST_THREAD() ((PRThread *) TlsGetValue(_pr_lastThreadIndex))
+#define _MD_SET_LAST_THREAD(_thread) TlsSetValue(_pr_lastThreadIndex, 0)
+
+extern DWORD _pr_currentCPUIndex;
+#define _MD_CURRENT_CPU() ((struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex))
+#define _MD_SET_CURRENT_CPU(_cpu) TlsSetValue(_pr_currentCPUIndex, 0)
+#endif /* _PR_USE_STATIC_TLS */
+
+/* --- Scheduler stuff --- */
+#define LOCK_SCHEDULER()                 0
+#define UNLOCK_SCHEDULER()               0
+#define _PR_LockSched()                	 0
+#define _PR_UnlockSched()                0
+
+/* --- Initialization stuff --- */
+#define _MD_INIT_LOCKS()
+
+/* --- Stack stuff --- */
+#define _MD_INIT_STACK(stack, redzone)
+#define _MD_CLEAR_STACK(stack)
+
+/* --- Memory-mapped files stuff --- */
+
+struct _MDFileMap {
+    HANDLE hFileMap;
+    DWORD dwAccess;
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+extern PRInt32 _MD_GetMemMapAlignment(void);
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+/* --- Named semaphores stuff --- */
+#define _PR_HAVE_NAMED_SEMAPHORES
+#define _MD_OPEN_SEMAPHORE            _PR_MD_OPEN_SEMAPHORE
+#define _MD_WAIT_SEMAPHORE            _PR_MD_WAIT_SEMAPHORE
+#define _MD_POST_SEMAPHORE            _PR_MD_POST_SEMAPHORE
+#define _MD_CLOSE_SEMAPHORE           _PR_MD_CLOSE_SEMAPHORE
+#define _MD_DELETE_SEMAPHORE(name)    PR_SUCCESS  /* no op */
+
+#endif /* nspr_win32_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_winnt.cfg b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_winnt.cfg
new file mode 100644
index 0000000..280b22e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_winnt.cfg
@@ -0,0 +1,256 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_PC
+#define XP_PC
+#endif
+
+#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
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD	4
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	32
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	5
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	4
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2	2
+#define PR_BYTES_PER_DWORD_LOG2	2
+
+#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#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_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD    64
+#define PR_BITS_PER_DWORD   64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD    8
+#define PR_ALIGN_OF_DWORD   8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#elif defined(_M_IA64) || defined(_IA64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#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_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD    64
+#define PR_BITS_PER_DWORD   64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD    8
+#define PR_ALIGN_OF_DWORD   8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#else /* defined(_M_IX86) || defined(_X86_) */
+
+#error unknown processor architecture
+
+#endif /* defined(_M_IX86) || defined(_X86_) */
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE      PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT     PR_BYTES_PER_SHORT
+#define BYTES_PER_INT       PR_BYTES_PER_INT
+#define BYTES_PER_INT64     PR_BYTES_PER_INT64
+#define BYTES_PER_LONG      PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT     PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE    PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD      PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD     PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE       PR_BITS_PER_BYTE
+#define BITS_PER_SHORT      PR_BITS_PER_SHORT
+#define BITS_PER_INT        PR_BITS_PER_INT
+#define BITS_PER_INT64      PR_BITS_PER_INT64
+#define BITS_PER_LONG       PR_BITS_PER_LONG
+#define BITS_PER_FLOAT      PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE     PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD       PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2  PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2   PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2  PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2    PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2  PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT      PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT        PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG       PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64      PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT      PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE     PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER    PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD       PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2		PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2    PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2    PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_winnt.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_winnt.h
new file mode 100644
index 0000000..628fe95
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/_winnt.h
@@ -0,0 +1,624 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_win32_defs_h___
+#define nspr_win32_defs_h___
+
+/* Need to force service-pack 3 extensions to be defined by
+** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h.
+*/ 
+#ifndef  _WIN32_WINNT
+    #define _WIN32_WINNT 0x0400
+#elif   (_WIN32_WINNT < 0x0400)
+    #undef  _WIN32_WINNT
+    #define _WIN32_WINNT 0x0400
+#endif /* _WIN32_WINNT */
+
+#include <windows.h>
+#include <winsock.h>
+#ifdef __MINGW32__
+#include <mswsock.h>
+#endif
+#include <errno.h>
+
+#include "prio.h"
+#include "prclist.h"
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH      "win32"
+#define _PR_SI_SYSNAME        "WINNT"
+#if defined(_M_IX86) || defined(_X86_)
+#define _PR_SI_ARCHITECTURE   "x86"
+#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)
+#define _PR_SI_ARCHITECTURE   "x86-64"
+#elif defined(_M_IA64) || defined(_IA64_)
+#define _PR_SI_ARCHITECTURE   "ia64"
+#else
+#error unknown processor architecture
+#endif
+
+#define HAVE_DLL
+#define HAVE_CUSTOM_USER_THREADS
+#define HAVE_THREAD_AFFINITY
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#ifndef _PR_INET6
+#define AF_INET6 23
+/* newer ws2tcpip.h provides these */
+#ifndef AI_CANONNAME
+#define AI_CANONNAME 0x2
+#define AI_NUMERICHOST 0x4
+#define NI_NUMERICHOST 0x02
+struct addrinfo {
+    int ai_flags;
+    int ai_family;
+    int ai_socktype;
+    int ai_protocol;
+    size_t ai_addrlen;
+    char *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#endif
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* isomorphic to struct in6_addr on Windows */
+struct _md_in6_addr {
+    union {
+        PRUint8  _S6_u8[16];
+        PRUint16 _S6_u16[8];
+    } _S6_un;
+};
+/* isomorphic to struct sockaddr_in6 on Windows */
+struct _md_sockaddr_in6 {
+    PRInt16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+};
+#endif
+#define _PR_HAVE_THREADSAFE_GETHOST
+#define _PR_HAVE_ATOMIC_OPS
+#if defined(_M_IX86) || defined(_X86_)
+#define _PR_HAVE_ATOMIC_CAS
+#endif
+#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY
+#define _PR_HAVE_PEEK_BUFFER
+#define _PR_PEEK_BUFFER_MAX (32 * 1024)
+#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) \
+    (!(fd)->secret->nonblocking && (fd)->secret->inheritable != _PR_TRI_TRUE)
+#define _PR_NEED_SECRET_AF
+
+/* --- Common User-Thread/Native-Thread Definitions --------------------- */
+
+/* --- Globals --- */
+extern struct PRLock                      *_pr_schedLock;
+
+/* --- Typedefs --- */
+typedef void (*FiberFunc)(void *);
+
+#define PR_NUM_GCREGS           8
+typedef PRInt32	                PR_CONTEXT_TYPE[PR_NUM_GCREGS];
+#define GC_VMBASE               0x40000000
+#define GC_VMLIMIT              0x00FFFFFF
+
+#define _MD_MAGIC_THREAD	0x22222222
+#define _MD_MAGIC_THREADSTACK	0x33333333
+#define _MD_MAGIC_SEGMENT	0x44444444
+#define _MD_MAGIC_DIR		0x55555555
+
+struct _MDCPU {
+    int              unused;
+};
+
+enum _MDIOModel {
+    _MD_BlockingIO = 0x38,
+    _MD_MultiWaitIO = 0x49
+};
+
+typedef struct _MDOverlapped {
+    OVERLAPPED overlapped;              /* Used for async I/O */
+
+    enum _MDIOModel ioModel;            /* The I/O model to implement
+                                         * using overlapped I/O.
+                                         */
+    union {
+        struct _MDThread *mdThread;     /* For blocking I/O, this structure
+                                         * is embedded in the _MDThread
+                                         * structure.
+                                         */
+        struct {
+            PRCList links;              /* for group->io_ready list */
+            struct PRRecvWait *desc;    /* For multiwait I/O, this structure
+                                         * is associated with a PRRecvWait
+                                         * structure.
+                                         */
+            struct PRWaitGroup *group;
+            struct TimerEvent *timer;
+            DWORD error;
+        } mw;
+    } data;
+} _MDOverlapped;
+
+struct _MDThread {
+        /* The overlapped structure must be first! */
+    struct _MDOverlapped overlapped;    /* Used for async IO for this thread */
+    void            *acceptex_buf;      /* Used for AcceptEx() */
+    TRANSMIT_FILE_BUFFERS *xmit_bufs;   /* Used for TransmitFile() */
+    HANDLE           blocked_sema;      /* Threads block on this when waiting
+                                         * for IO or CondVar.
+                                         */
+    PRInt32          blocked_io_status; /* Status of the completed IO */
+    PRInt32          blocked_io_bytes;  /* Bytes transferred for completed IO */
+    PRInt32          blocked_io_error;  /* Save error if status is FALSE */
+    HANDLE           handle;
+    PRUint32         id;
+    void            *sp;                /* only valid when suspended */
+    PRUint32         magic;             /* for debugging */
+    PR_CONTEXT_TYPE  gcContext;         /* Thread context for GC */
+	struct _PRCPU    *thr_bound_cpu;		/* thread bound to cpu */
+	PRBool   		 interrupt_disabled;/* thread cannot be interrupted */
+	HANDLE 			 thr_event;			/* For native-threads-only support,
+											thread blocks on this event		*/
+
+    /* The following are used only if this is a fiber */
+    void            *fiber_id;          /* flag whether or not this is a fiber*/
+    FiberFunc        fiber_fn;          /* main fiber routine */
+    void            *fiber_arg;         /* arg to main fiber routine */
+    PRUint32         fiber_stacksize;   /* stacksize for fiber */
+    PRInt32          fiber_last_error;  /* last error for the fiber */
+    void (*start)(void *);              /* used by _PR_MD_CREATE_THREAD to
+                                         * pass its 'start' argument to
+                                         * pr_root. */
+};
+
+struct _MDThreadStack {
+    PRUint32           magic;          /* for debugging */
+};
+
+struct _MDSegment {
+    PRUint32           magic;          /* for debugging */
+};
+
+#undef PROFILE_LOCKS
+
+struct _MDLock {
+    CRITICAL_SECTION mutex;          /* this is recursive on NT */
+#ifdef PROFILE_LOCKS
+    PRInt32 hitcount;
+    PRInt32 misscount;
+#endif
+};
+
+struct _MDDir {
+    HANDLE           d_hdl;
+    WIN32_FIND_DATA  d_entry;
+    PRBool           firstEntry;     /* Is this the entry returned
+                                      * by FindFirstFile()? */
+    PRUint32         magic;          /* for debugging */
+};
+
+struct _MDCVar {
+    PRUint32         unused;
+};
+
+struct _MDSemaphore {
+    HANDLE           sem;
+};
+
+struct _MDFileDesc {
+    PROsfd osfd;     /* The osfd can come from one of three spaces:
+                      * - For stdin, stdout, and stderr, we are using
+                      *   the libc file handle (0, 1, 2), which is an int.
+                      * - For files and pipes, we are using Win32 HANDLE,
+                      *   which is a void*.
+                      * - For sockets, we are using Winsock SOCKET, which
+                      *   is a u_int.
+                      */
+    PRBool io_model_committed;  /* The io model (blocking or nonblocking)
+                                 * for this osfd has been committed and
+                                 * cannot be changed.  The osfd has been
+                                 * either associated with the io
+                                 * completion port or made nonblocking. */
+    PRBool sync_file_io;        /* Use synchronous file I/O on the osfd
+                                 * (a file handle) */
+    PRBool accepted_socket;     /* Is this an accepted socket (on the
+                                 * server side)? */
+    PRNetAddr peer_addr;        /* If this is an accepted socket, cache
+                                 * the peer's address returned by
+                                 * AcceptEx().  This is to work around
+                                 * the bug that getpeername() on an
+                                 * socket accepted by AcceptEx() returns
+                                 * an all-zero net address. */
+};
+
+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(PROsfd 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)
+
+#define _MD_INIT_FILEDESC(fd)
+#define _MD_MAKE_NONBLOCK             _PR_MD_MAKE_NONBLOCK
+#define _MD_INIT_FD_INHERITABLE       _PR_MD_INIT_FD_INHERITABLE
+#define _MD_QUERY_FD_INHERITABLE      _PR_MD_QUERY_FD_INHERITABLE
+#define _MD_SHUTDOWN                  _PR_MD_SHUTDOWN
+#define _MD_LISTEN                    _PR_MD_LISTEN
+#define _MD_CLOSE_SOCKET(s)           _PR_MD_CLOSE(s, PR_TRUE)
+#define _MD_SENDTO                    _PR_MD_SENDTO
+#define _MD_RECVFROM                  _PR_MD_RECVFROM
+#define _MD_SOCKETPAIR(s, type, proto, sv) -1
+#define _MD_GETSOCKNAME               _PR_MD_GETSOCKNAME
+#define _MD_GETPEERNAME               _PR_MD_GETPEERNAME
+#define _MD_GETSOCKOPT                _PR_MD_GETSOCKOPT
+#define _MD_SETSOCKOPT                _PR_MD_SETSOCKOPT
+#define _MD_SELECT                    select
+extern int _PR_NTFiberSafeSelect(int, fd_set *, fd_set *, fd_set *,
+    const struct timeval *);
+#define _MD_FSYNC                     _PR_MD_FSYNC
+#define _MD_SOCKETAVAILABLE           _PR_MD_SOCKETAVAILABLE
+#define _MD_PIPEAVAILABLE             _PR_MD_PIPEAVAILABLE
+#define _MD_SET_FD_INHERITABLE        _PR_MD_SET_FD_INHERITABLE
+
+#define _MD_INIT_ATOMIC()
+#if defined(_M_IX86) || defined(_X86_)
+#define _MD_ATOMIC_INCREMENT          _PR_MD_ATOMIC_INCREMENT
+#define _MD_ATOMIC_ADD          	  _PR_MD_ATOMIC_ADD
+#define _MD_ATOMIC_DECREMENT          _PR_MD_ATOMIC_DECREMENT
+#else /* non-x86 processors */
+#define _MD_ATOMIC_INCREMENT(x)       InterlockedIncrement((PLONG)x)
+#define _MD_ATOMIC_ADD(ptr,val)    (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val)
+#define _MD_ATOMIC_DECREMENT(x)       InterlockedDecrement((PLONG)x)
+#endif /* x86 */
+#define _MD_ATOMIC_SET(x,y)           InterlockedExchange((PLONG)x, (LONG)y)
+
+#define _MD_INIT_IO                   _PR_MD_INIT_IO
+#define _MD_SOCKET                    _PR_MD_SOCKET
+#define _MD_CONNECT                   _PR_MD_CONNECT
+
+#define _MD_ACCEPT(s, a, l, to)       \
+        _MD_FAST_ACCEPT(s, a, l, to, PR_FALSE, NULL, NULL)
+#define _MD_FAST_ACCEPT(s, a, l, to, fast, cb, cba) \
+        _PR_MD_FAST_ACCEPT(s, a, l, to, fast, cb, cba)
+#define _MD_ACCEPT_READ(s, ns, ra, buf, l, t) \
+        _MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, PR_FALSE, NULL, NULL)
+#define _MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, fast, cb, cba) \
+        _PR_MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, fast, cb, cba)
+#define _MD_UPDATE_ACCEPT_CONTEXT     _PR_MD_UPDATE_ACCEPT_CONTEXT
+
+#define _MD_BIND                      _PR_MD_BIND
+#define _MD_RECV                      _PR_MD_RECV
+#define _MD_SEND                      _PR_MD_SEND
+#define _MD_SENDFILE              	  _PR_MD_SENDFILE
+#define _MD_PR_POLL                   _PR_MD_PR_POLL
+
+/* --- Scheduler stuff --- */
+#define _MD_PAUSE_CPU                   _PR_MD_PAUSE_CPU
+
+/* --- DIR stuff --- */
+#define PR_DIRECTORY_SEPARATOR        '\\'
+#define PR_DIRECTORY_SEPARATOR_STR    "\\"
+#define PR_PATH_SEPARATOR		';'
+#define PR_PATH_SEPARATOR_STR		";"
+#define _MD_ERRNO()                   GetLastError()
+#define _MD_OPEN_DIR                  _PR_MD_OPEN_DIR
+#define _MD_CLOSE_DIR                 _PR_MD_CLOSE_DIR
+#define _MD_READ_DIR                  _PR_MD_READ_DIR
+
+/* --- Segment stuff --- */
+#define _MD_INIT_SEGS()
+#define _MD_ALLOC_SEGMENT(seg, size, vaddr)   0
+#define _MD_FREE_SEGMENT(seg)
+
+/* --- Environment Stuff --- */
+#define _MD_GET_ENV                 _PR_MD_GET_ENV
+#define _MD_PUT_ENV                 _PR_MD_PUT_ENV
+
+/* --- Threading Stuff --- */
+#define _MD_DEFAULT_STACK_SIZE            0
+#define _MD_INIT_THREAD             _PR_MD_INIT_THREAD
+#define _MD_INIT_ATTACHED_THREAD    _PR_MD_INIT_THREAD
+#define _MD_CREATE_THREAD           _PR_MD_CREATE_THREAD
+#define _MD_JOIN_THREAD             _PR_MD_JOIN_THREAD
+#define _MD_END_THREAD              _PR_MD_END_THREAD
+#define _MD_YIELD                   _PR_MD_YIELD
+#define _MD_SET_PRIORITY            _PR_MD_SET_PRIORITY
+#define _MD_CLEAN_THREAD            _PR_MD_CLEAN_THREAD
+#define _MD_SETTHREADAFFINITYMASK   _PR_MD_SETTHREADAFFINITYMASK
+#define _MD_GETTHREADAFFINITYMASK   _PR_MD_GETTHREADAFFINITYMASK
+#define _MD_EXIT_THREAD             _PR_MD_EXIT_THREAD
+#define _MD_SUSPEND_THREAD          _PR_MD_SUSPEND_THREAD
+#define _MD_RESUME_THREAD           _PR_MD_RESUME_THREAD
+#define _MD_SUSPEND_CPU             _PR_MD_SUSPEND_CPU
+#define _MD_RESUME_CPU              _PR_MD_RESUME_CPU
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_END_RESUME_ALL()
+
+extern void _PR_Unblock_IO_Wait(PRThread *thr);
+
+/* --- Lock stuff --- */
+#define _MD_NEW_LOCK(lock)            (InitializeCriticalSection(&((lock)->mutex)),PR_SUCCESS)
+#define _MD_FREE_LOCK(lock)           DeleteCriticalSection(&((lock)->mutex))
+#ifndef PROFILE_LOCKS
+#define _MD_LOCK(lock)                EnterCriticalSection(&((lock)->mutex))
+#define _MD_TEST_AND_LOCK(lock)       (TryEnterCriticalSection(&((lock)->mutex))== FALSE)
+#define _MD_UNLOCK(lock)              LeaveCriticalSection(&((lock)->mutex))
+#else
+#define _MD_LOCK(lock)                 \
+    PR_BEGIN_MACRO \
+    BOOL rv = TryEnterCriticalSection(&((lock)->mutex)); \
+    if (rv == TRUE) { \
+        InterlockedIncrement(&((lock)->hitcount)); \
+    } else { \
+        InterlockedIncrement(&((lock)->misscount)); \
+        EnterCriticalSection(&((lock)->mutex)); \
+    } \
+    PR_END_MACRO
+#define _MD_TEST_AND_LOCK(lock)       0  /* XXXMB */
+#define _MD_UNLOCK(lock)              LeaveCriticalSection(&((lock)->mutex))
+#endif
+#define _PR_LOCK                      _MD_LOCK
+#define _PR_UNLOCK					  _MD_UNLOCK
+
+/* --- lock and cv waiting --- */
+#define _MD_WAIT                      _PR_MD_WAIT
+#define _MD_WAKEUP_WAITER             _PR_MD_WAKEUP_WAITER
+
+   /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
+extern  struct _MDLock              _pr_ioq_lock;
+#define _MD_IOQ_LOCK()                _MD_LOCK(&_pr_ioq_lock)
+#define _MD_IOQ_UNLOCK()              _MD_UNLOCK(&_pr_ioq_lock)
+
+
+/* --- Initialization stuff --- */
+#define _MD_START_INTERRUPTS()
+#define _MD_STOP_INTERRUPTS()
+#define _MD_DISABLE_CLOCK_INTERRUPTS()
+#define _MD_ENABLE_CLOCK_INTERRUPTS()
+#define _MD_BLOCK_CLOCK_INTERRUPTS()
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _MD_EARLY_INIT                _PR_MD_EARLY_INIT
+#define _MD_FINAL_INIT()
+#define _MD_EARLY_CLEANUP()
+#define _MD_INIT_CPUS()
+#define _MD_INIT_RUNNING_CPU(cpu)
+
+struct PRProcess;
+struct PRProcessAttr;
+
+/* --- Create a new process --- */
+#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess
+extern struct PRProcess * _PR_CreateWindowsProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess
+extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process);
+
+/* --- Wait for a child process to terminate --- */
+#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess
+extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, 
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _PR_KillWindowsProcess
+extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
+
+/* --- User Threading stuff --- */
+#define HAVE_FIBERS
+#define _MD_CREATE_USER_THREAD            _PR_MD_CREATE_USER_THREAD
+#define _MD_CREATE_PRIMORDIAL_USER_THREAD _PR_MD_CREATE_PRIMORDIAL_USER_THREAD
+#define _MD_CLEANUP_BEFORE_EXIT           _PR_MD_CLEANUP_BEFORE_EXIT
+#define _MD_EXIT                          _PR_MD_EXIT
+#define _MD_INIT_CONTEXT                  _PR_MD_INIT_CONTEXT
+#define _MD_SWITCH_CONTEXT                _PR_MD_SWITCH_CONTEXT
+#define _MD_RESTORE_CONTEXT               _PR_MD_RESTORE_CONTEXT
+
+/* --- Intervals --- */
+#define _MD_INTERVAL_INIT                 _PR_MD_INTERVAL_INIT
+#define _MD_GET_INTERVAL                  _PR_MD_GET_INTERVAL
+#define _MD_INTERVAL_PER_SEC              _PR_MD_INTERVAL_PER_SEC
+#define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/* --- Time --- */
+extern void _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm);
+
+/* --- Native-Thread Specific Definitions ------------------------------- */
+
+extern BOOL _pr_use_static_tls;
+
+extern __declspec(thread) struct PRThread *_pr_current_fiber;
+extern DWORD _pr_currentFiberIndex;
+
+#define _MD_GET_ATTACHED_THREAD() \
+    (_pr_use_static_tls ? _pr_current_fiber \
+    : (PRThread *) TlsGetValue(_pr_currentFiberIndex))
+
+extern struct PRThread * _MD_CURRENT_THREAD(void);
+
+#define _MD_SET_CURRENT_THREAD(_thread) \
+    PR_BEGIN_MACRO \
+        if (_pr_use_static_tls) { \
+            _pr_current_fiber = (_thread); \
+        } else { \
+            TlsSetValue(_pr_currentFiberIndex, (_thread)); \
+        } \
+    PR_END_MACRO
+
+extern __declspec(thread) struct PRThread *_pr_fiber_last_run;
+extern DWORD _pr_lastFiberIndex;
+
+#define _MD_LAST_THREAD() \
+    (_pr_use_static_tls ? _pr_fiber_last_run \
+    : (PRThread *) TlsGetValue(_pr_lastFiberIndex))
+
+#define _MD_SET_LAST_THREAD(_thread) \
+    PR_BEGIN_MACRO \
+        if (_pr_use_static_tls) { \
+            _pr_fiber_last_run = (_thread); \
+        } else { \
+            TlsSetValue(_pr_lastFiberIndex, (_thread)); \
+        } \
+    PR_END_MACRO
+
+extern __declspec(thread) struct _PRCPU *_pr_current_cpu;
+extern DWORD _pr_currentCPUIndex;
+
+#define _MD_CURRENT_CPU() \
+    (_pr_use_static_tls ? _pr_current_cpu \
+    : (struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex))
+
+#define _MD_SET_CURRENT_CPU(_cpu) \
+    PR_BEGIN_MACRO \
+        if (_pr_use_static_tls) { \
+            _pr_current_cpu = (_cpu); \
+        } else { \
+            TlsSetValue(_pr_currentCPUIndex, (_cpu)); \
+        } \
+    PR_END_MACRO
+
+extern __declspec(thread) PRUintn _pr_ints_off;
+extern DWORD _pr_intsOffIndex;
+
+#define _MD_GET_INTSOFF() \
+    (_pr_use_static_tls ? _pr_ints_off \
+    : (PRUintn) TlsGetValue(_pr_intsOffIndex))
+
+#define _MD_SET_INTSOFF(_val) \
+    PR_BEGIN_MACRO \
+        if (_pr_use_static_tls) { \
+            _pr_ints_off = (_val); \
+        } else { \
+            TlsSetValue(_pr_intsOffIndex, (LPVOID) (_val)); \
+        } \
+    PR_END_MACRO
+
+/* --- Initialization stuff --- */
+#define _MD_INIT_LOCKS()
+
+/* --- Stack stuff --- */
+#define _MD_INIT_STACK(stack, redzone)
+#define _MD_CLEAR_STACK(stack)
+
+/* --- Memory-mapped files stuff --- */
+
+struct _MDFileMap {
+    HANDLE hFileMap;
+    DWORD dwAccess;
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+extern PRInt32 _MD_GetMemMapAlignment(void);
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+/* --- Named semaphores stuff --- */
+#define _PR_HAVE_NAMED_SEMAPHORES
+#define _MD_OPEN_SEMAPHORE            _PR_MD_OPEN_SEMAPHORE
+#define _MD_WAIT_SEMAPHORE            _PR_MD_WAIT_SEMAPHORE
+#define _MD_POST_SEMAPHORE            _PR_MD_POST_SEMAPHORE
+#define _MD_CLOSE_SEMAPHORE           _PR_MD_CLOSE_SEMAPHORE
+#define _MD_DELETE_SEMAPHORE(name)    PR_SUCCESS  /* no op */
+
+#endif /* nspr_win32_defs_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/prosdep.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/prosdep.h
new file mode 100644
index 0000000..7e20ab4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/prosdep.h
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prosdep_h___
+#define prosdep_h___
+
+/*
+** Get OS specific header information
+*/
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+#ifdef XP_PC
+
+#include "md/_pcos.h"
+#ifdef WINNT
+#include "md/_winnt.h"
+#include "md/_win32_errors.h"
+#elif defined(WIN95) || defined(WINCE)
+#include "md/_win95.h"
+#include "md/_win32_errors.h"
+#elif defined(OS2)
+#include "md/_os2.h"
+#include "md/_os2_errors.h"
+#else
+#error unknown Windows platform
+#endif
+
+#elif defined(XP_UNIX)
+
+#if defined(AIX)
+#include "md/_aix.h"
+
+#elif defined(FREEBSD)
+#include "md/_freebsd.h"
+
+#elif defined(NETBSD)
+#include "md/_netbsd.h"
+
+#elif defined(OPENBSD)
+#include "md/_openbsd.h"
+
+#elif defined(BSDI)
+#include "md/_bsdi.h"
+
+#elif defined(HPUX)
+#include "md/_hpux.h"
+
+#elif defined(IRIX)
+#include "md/_irix.h"
+
+#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__)
+#include "md/_linux.h"
+
+#elif defined(OSF1)
+#include "md/_osf1.h"
+
+#elif defined(DARWIN)
+#include "md/_darwin.h"
+
+#elif defined(NEXTSTEP)
+#include "md/_nextstep.h"
+
+#elif defined(SOLARIS)
+#include "md/_solaris.h"
+
+#elif defined(SUNOS4)
+#include "md/_sunos4.h"
+
+#elif defined(SNI)
+#include "md/_reliantunix.h"
+
+#elif defined(SONY)
+#include "md/_sony.h"
+
+#elif defined(NEC)
+#include "md/_nec.h"
+
+#elif defined(SCO)
+#include "md/_scoos.h"
+
+#elif defined(UNIXWARE)
+#include "md/_unixware.h"
+
+#elif defined(NCR)
+#include "md/_ncr.h"
+
+#elif defined(DGUX)
+#include "md/_dgux.h"
+
+#elif defined(QNX)
+#include "md/_qnx.h"
+
+#elif defined(NTO)
+#include "md/_nto.h"
+
+#elif defined(RISCOS)
+#include "md/_riscos.h"
+
+#elif defined(SYMBIAN)
+#include "md/_symbian.h"
+
+#else
+#error unknown Unix flavor
+
+#endif
+
+#include "md/_unixos.h"
+#include "md/_unix_errors.h"
+
+#elif defined(XP_BEOS)
+
+#include "md/_beos.h"
+#include "md/_unix_errors.h"
+
+#else
+
+#error "The platform is not BeOS, Unix, Windows, or Mac"
+
+#endif
+
+#ifdef _PR_PTHREADS
+#include "md/_pth.h"
+#endif
+
+PR_END_EXTERN_C
+
+#endif /* prosdep_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/md/sunos4.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/sunos4.h
new file mode 100644
index 0000000..0a8f36d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/md/sunos4.h
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef pr_sunos4_h___
+#define pr_sunos4_h___
+
+#ifndef SVR4
+
+/*
+** Hodge podge of random missing prototypes for the Sunos4 system
+*/
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include <limits.h>
+#include <sys/types.h>
+
+#define PATH_MAX _POSIX_PATH_MAX
+
+struct timeval;
+struct timezone;
+struct itimerval;
+struct sockaddr;
+struct stat;
+struct tm;
+
+/* ctype.h */
+extern int tolower(int);
+extern int toupper(int);
+
+/* errno.h */
+extern char *sys_errlist[];
+extern int sys_nerr;
+
+#define strerror(e) sys_errlist[((unsigned)(e) < sys_nerr) ? e : 0]
+
+extern void perror(const char *);
+
+/* getopt */
+extern char *optarg;
+extern int optind;
+extern int getopt(int argc, char **argv, char *spec);
+
+/* math.h */
+extern int srandom(long val);
+extern long random(void);
+
+/* memory.h */
+#define memmove(to,from,len) bcopy((char*)(from),(char*)(to),len)
+
+extern void bcopy(const char *, char *, int);
+
+/* signal.h */
+/*
+** SunOS4 sigaction hides interrupts by default, so we can safely define
+** SA_RESTART to 0.
+*/
+#define SA_RESTART 0
+
+/* stdio.h */
+extern int printf(const char *, ...);
+extern int fprintf(FILE *, const char *, ...);
+extern int vprintf(const char *, va_list);
+extern int vfprintf(FILE *, const char *, va_list);
+extern char *vsprintf(char *, const char *, va_list);
+extern int scanf(const char *, ...);
+extern int sscanf(const char *, const char *, ...);
+extern int fscanf(FILE *, const char *, ...);
+extern int fgetc(FILE *);
+extern int fputc(int, FILE *);
+extern int fputs(const char *, FILE *);
+extern int puts(const char *);
+extern int fread(void *, size_t, size_t, FILE *);
+extern int fwrite(const char *, int, int, FILE *);
+extern int fseek(FILE *, long, int);
+extern long ftell(FILE *);
+extern int rewind(FILE *);
+extern int fflush(FILE *);
+extern int _flsbuf(unsigned char, FILE *);
+extern int fclose(FILE *);
+extern int remove(const char *);
+extern int setvbuf(FILE *, char *, int, size_t);
+extern int system(const char *);
+extern FILE *popen(const char *, const char *);
+extern int pclose(FILE *);
+
+/* stdlib.h */
+#define strtoul strtol
+
+extern int isatty(int fildes);
+extern long strtol(const char *, char **, int);
+extern int putenv(const char *);
+extern void srand48(long);
+extern long lrand48(void);
+extern double drand48(void);
+
+/* string.h */
+extern int strcasecmp(const char *, const char *);
+extern int strncasecmp(const char *, const char *, size_t);
+extern int strcoll(const char *, const char *);
+
+/* time.h */
+extern time_t mktime(struct tm *);
+extern size_t strftime(char *, size_t, const char *, const struct tm *);
+extern int gettimeofday(struct timeval *, struct timezone *);
+extern int setitimer(int, struct itimerval *, struct itimerval *);
+extern time_t time(time_t *);
+extern time_t timegm(struct tm *);
+extern struct tm *localtime(const time_t *);
+extern struct tm *gmtime(const time_t *);
+
+/* unistd.h */
+extern int rename(const char *, const char *);
+extern int ioctl(int, int, int *arg);
+extern int connect(int, struct sockaddr *, int);
+extern int readlink(const char *, char *, int);
+extern int symlink(const char *, const char *);
+extern int ftruncate(int, off_t);
+extern int fchmod(int, mode_t);
+extern int fchown(int, uid_t, gid_t);
+extern int lstat(const char *, struct stat *);
+extern int fstat(int, struct stat *);
+extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern int gethostname(char *, int);
+extern char *getwd(char *);
+extern int getpagesize(void);
+
+#endif /* SVR4 */
+
+#endif /* pr_sunos4_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/nspr.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/nspr.h
new file mode 100644
index 0000000..cf3bfad
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/nspr.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_h___
+#define nspr_h___
+
+#include "pratom.h"
+#include "prbit.h"
+#include "prclist.h"
+#include "prcmon.h"
+#include "prcvar.h"
+#include "prdtoa.h"
+#include "prenv.h"
+#include "prerror.h"
+#include "prinet.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "pripcsem.h"
+#include "prlink.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prlong.h"
+#include "prmem.h"
+#include "prmon.h"
+#include "prmwait.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#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___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/Makefile.in
new file mode 100644
index 0000000..1add484
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/Makefile.in
@@ -0,0 +1,60 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)/obsolete
+
+include_subdir = obsolete
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(RELEASE_HEADERS)
+	$(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)/obsolete
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/pralarm.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/pralarm.h
new file mode 100644
index 0000000..20476e4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/pralarm.h
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:		pralarm.h
+** Description:	API to periodic alarms.
+**
+**
+** Alarms are defined to invoke some client specified function at 
+** a time in the future. The notification may be a one time event
+** or repeated at a fixed interval. The interval at which the next
+** notification takes place may be modified by the client code only
+** during the respective notification.
+**
+** The notification is delivered on a thread that is part of the
+** alarm context (PRAlarm). The thread will inherit the priority
+** of the Alarm creator.
+**
+** Any number of periodic alarms (PRAlarmID) may be created within
+** the context of a single alarm (PRAlarm). The notifications will be
+** scheduled as close to the desired time as possible.
+**
+** Repeating periodic notifies are expected to run at a fixed rate.
+** That rate is expressed as some number of notifies per period where
+** the period is much larger than a PRIntervalTime (see prinrval.h).
+*/
+
+#if !defined(pralarm_h)
+#define pralarm_h
+
+#include "prtypes.h"
+#include "prinrval.h"
+
+
+PR_BEGIN_EXTERN_C
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+typedef struct PRAlarm PRAlarm;
+typedef struct PRAlarmID PRAlarmID;
+
+typedef PRBool (PR_CALLBACK *PRPeriodicAlarmFn)(
+    PRAlarmID *id, void *clientData, PRUint32 late);
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/***********************************************************************
+** FUNCTION:    PR_CreateAlarm
+** DESCRIPTION:
+**  Create an alarm context.
+** INPUTS:      void
+** OUTPUTS:     None
+** RETURN:      PRAlarm*
+**  
+** SIDE EFFECTS:
+**  This creates an alarm context, which is an object used for subsequent
+**  notification creations. It also creates a thread that will be used to
+** deliver the notifications that are expected to be defined. The client
+** is resposible for destroying the context when appropriate.
+** RESTRICTIONS:
+**  None. 
+** MEMORY:      The object (PRAlarm) and a thread to support notifications.
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRAlarm*) PR_CreateAlarm(void);
+
+/***********************************************************************
+** FUNCTION:    PR_DestroyAlarm
+** DESCRIPTION:
+**  Destroys the context created by PR_CreateAlarm().
+** INPUTS:      PRAlarm*
+** OUTPUTS:     None
+** RETURN:      PRStatus
+**  
+** SIDE EFFECTS:
+**  This destroys the context that was created by PR_CreateAlarm().
+**  If there are any active alarms (PRAlarmID), they will be cancelled.
+**  Once that is done, the thread that was used to deliver the alarms
+**  will be joined. 
+** RESTRICTIONS:
+**  None. 
+** MEMORY:      N/A
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRStatus) PR_DestroyAlarm(PRAlarm *alarm);
+
+/***********************************************************************
+** FUNCTION:    PR_SetAlarm
+** DESCRIPTION:
+**  Creates a periodic notifier that is to be delivered to a specified
+**  function at some fixed interval.
+** INPUTS:      PRAlarm *alarm              Parent alarm context
+**              PRIntervalTime period       Interval over which the notifies
+**                                          are delivered.
+**              PRUint32 rate               The rate within the interval that
+**                                          the notifies will be delivered.
+**              PRPeriodicAlarmFn function  Entry point where the notifies
+**                                          will be delivered.
+** OUTPUTS:     None
+** RETURN:      PRAlarmID*                  Handle to the notifier just created
+**                                          or NULL if the request failed.
+**  
+** SIDE EFFECTS:
+**  A periodic notifier is created. The notifications will be delivered
+**  by the alarm's internal thread at a fixed interval whose rate is the
+**  number of interrupts per interval specified. The first notification
+**  will be delivered as soon as possible, and they will continue until
+**  the notifier routine indicates that they should cease of the alarm
+**  context is destroyed (PR_DestroyAlarm).
+** RESTRICTIONS:
+**  None. 
+** MEMORY:      Memory for the notifier object.
+** ALGORITHM:   The rate at which notifications are delivered are stated
+**              to be "'rate' notifies per 'interval'". The exact time of
+**              the notification is computed based on a epoch established
+**              when the notifier was set. Each notification is delivered
+**              not ealier than the epoch plus the fixed rate times the
+**              notification sequence number. Such notifications have the
+**              potential to be late by not more than 'interval'/'rate'.
+**              The amount of lateness of one notification is taken into
+**              account on the next in an attempt to avoid long term slew.  
+***********************************************************************/
+NSPR_API(PRAlarmID*) PR_SetAlarm(
+    PRAlarm *alarm, PRIntervalTime period, PRUint32 rate,
+    PRPeriodicAlarmFn function, void *clientData);
+
+/***********************************************************************
+** FUNCTION:    PR_ResetAlarm
+** DESCRIPTION:
+**  Resets an existing alarm.
+** INPUTS:      PRAlarmID *id               Identify of the notifier.
+**              PRIntervalTime period       Interval over which the notifies
+**                                          are delivered.
+**              PRUint32 rate               The rate within the interval that
+**                                          the notifies will be delivered.
+** OUTPUTS:     None
+** RETURN:      PRStatus                    Indication of completion.
+**  
+** SIDE EFFECTS:
+**  An existing alarm may have its period and rate redefined. The
+**  additional side effect is that the notifier's epoch is recomputed.
+**  The first notification delivered by the newly refreshed alarm is
+**  defined to be 'interval'/'rate' from the time of the reset.
+** RESTRICTIONS:
+**  This function may only be called in the notifier for that alarm.
+** MEMORY:      N/A.
+** ALGORITHM:   See PR_SetAlarm().  
+***********************************************************************/
+NSPR_API(PRStatus) PR_ResetAlarm(
+	PRAlarmID *id, PRIntervalTime period, PRUint32 rate);
+
+PR_END_EXTERN_C
+
+#endif /* !defined(pralarm_h) */
+
+/* prinrval.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/probslet.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/probslet.h
new file mode 100644
index 0000000..bad5947
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/probslet.h
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** A collection of things thought to be obsolete
+*/
+
+#if defined(PROBSLET_H)
+#else
+#define PROBSLET_H
+
+#include "prio.h"
+#include "private/pprio.h"  /* for PROsfd */
+
+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);
+
+/************************************************************************/
+/************* 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.
+**
+** Override PR_MAX_SELECT_DESC if you need more space in the select set.
+*/
+#ifndef PR_MAX_SELECT_DESC
+#define PR_MAX_SELECT_DESC 1024
+#endif
+typedef struct PR_fd_set {
+    PRUint32      hsize;
+    PRFileDesc   *harray[PR_MAX_SELECT_DESC];
+    PRUint32      nsize;
+    PROsfd        narray[PR_MAX_SELECT_DESC];
+} PR_fd_set;
+
+/*
+*************************************************************************
+** FUNCTION:    PR_Select
+** DESCRIPTION:
+**
+** The call returns as soon as I/O is ready on one or more of the underlying
+** file/socket descriptors or an exceptional condition is pending. A count of the 
+** number of ready descriptors is returned unless a timeout occurs in which case 
+** zero is returned.  On return, PR_Select replaces the given descriptor sets with 
+** subsets consisting of those descriptors that are ready for the requested condition.
+** The total number of ready descriptors in all the sets is the return value.
+**
+** INPUTS:
+**   PRInt32 num             
+**       This argument is unused but is provided for select(unix) interface
+**       compatability.  All input PR_fd_set arguments are self-describing
+**       with its own maximum number of elements in the set.
+**                               
+**   PR_fd_set *readfds
+**       A set describing the io descriptors for which ready for reading
+**       condition is of interest.  
+**                               
+**   PR_fd_set *writefds
+**       A set describing the io descriptors for which ready for writing
+**       condition is of interest.  
+**                               
+**   PR_fd_set *exceptfds
+**       A set describing the io descriptors for which exception pending
+**       condition is of interest.  
+**
+**   Any of the above readfds, writefds or exceptfds may be given as NULL 
+**   pointers if no descriptors are of interest for that particular condition.                          
+**   
+**   PRIntervalTime timeout  
+**       Amount of time the call will block waiting for I/O to become ready. 
+**       If this time expires without any I/O becoming ready, the result will
+**       be zero.
+**
+** OUTPUTS:    
+**   PR_fd_set *readfds
+**       A set describing the io descriptors which are ready for reading.
+**                               
+**   PR_fd_set *writefds
+**       A set describing the io descriptors which are ready for writing.
+**                               
+**   PR_fd_set *exceptfds
+**       A set describing the io descriptors which have pending exception.
+**
+** RETURN:PRInt32
+**   Number of io descriptors with asked for conditions or zero if the function
+**   timed out or -1 on failure.  The reason for the failure is obtained by 
+**   calling PR_GetError().
+** XXX can we implement this on windoze and mac?
+**************************************************************************
+*/
+NSPR_API(PRInt32) PR_Select(
+    PRInt32 num, PR_fd_set *readfds, PR_fd_set *writefds,
+    PR_fd_set *exceptfds, PRIntervalTime timeout);
+
+/* 
+** The following are not thread safe for two threads operating on them at the
+** same time.
+**
+** The following routines are provided for manipulating io descriptor sets.
+** PR_FD_ZERO(&fdset) initializes a descriptor set fdset to the null set.
+** PR_FD_SET(fd, &fdset) includes a particular file descriptor fd in fdset.
+** PR_FD_CLR(fd, &fdset) removes a file descriptor fd from fdset.  
+** PR_FD_ISSET(fd, &fdset) is nonzero if file descriptor fd is a member of 
+** fdset, zero otherwise.
+**
+** PR_FD_NSET(osfd, &fdset) includes a particular native file descriptor osfd
+** in fdset.
+** PR_FD_NCLR(osfd, &fdset) removes a native file descriptor osfd from fdset.  
+** PR_FD_NISSET(osfd, &fdset) is nonzero if native file descriptor osfd is a member of 
+** fdset, zero otherwise.
+*/
+
+NSPR_API(void)        PR_FD_ZERO(PR_fd_set *set);
+NSPR_API(void)        PR_FD_SET(PRFileDesc *fd, PR_fd_set *set);
+NSPR_API(void)        PR_FD_CLR(PRFileDesc *fd, PR_fd_set *set);
+NSPR_API(PRInt32)     PR_FD_ISSET(PRFileDesc *fd, PR_fd_set *set);
+NSPR_API(void)        PR_FD_NSET(PROsfd osfd, PR_fd_set *set);
+NSPR_API(void)        PR_FD_NCLR(PROsfd osfd, PR_fd_set *set);
+NSPR_API(PRInt32)     PR_FD_NISSET(PROsfd osfd, PR_fd_set *set);
+
+/*
+** The next two entry points should not be in the API, but they are
+** declared here for historical reasons.
+*/
+
+NSPR_API(PRInt32) PR_GetSysfdTableMax(void);
+
+NSPR_API(PRInt32) PR_SetSysfdTableSize(PRIntn table_size);
+
+#ifndef NO_NSPR_10_SUPPORT
+#include <sys/stat.h>
+
+NSPR_API(PRInt32) PR_Stat(const char *path, struct stat *buf);
+#endif /* NO_NSPR_10_SUPPORT */
+
+PR_END_EXTERN_C
+
+#endif /* defined(PROBSLET_H) */
+
+/* probslet.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/protypes.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/protypes.h
new file mode 100644
index 0000000..d8e947a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/protypes.h
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This header typedefs the old 'native' types to the new PR<type>s.
+ * These definitions are scheduled to be eliminated at the earliest
+ * possible time. The NSPR API is implemented and documented using
+ * the new definitions.
+ */
+
+#if !defined(PROTYPES_H)
+#define PROTYPES_H
+
+typedef PRUintn uintn;
+#ifndef _XP_Core_
+typedef PRIntn intn;
+#endif
+
+/*
+ * It is trickier to define uint, int8, uint8, int16, uint16,
+ * int32, uint32, int64, and uint64 because some of these int
+ * types are defined by standard header files on some platforms.
+ * Our strategy here is to include all such standard headers
+ * first, and then define these int types only if they are not
+ * defined by those standard headers.
+ */
+
+/*
+ * BeOS defines all the int types below in its standard header
+ * file SupportDefs.h.
+ */
+#ifdef XP_BEOS
+#include <support/SupportDefs.h>
+#endif
+
+/*
+ * SVR4 typedef of uint is commonly found on UNIX machines.
+ *
+ * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h)
+ * defines the types int8, int16, int32, and int64.
+ *
+ * On OS/2, sys/types.h defines uint.
+ */
+#if defined(XP_UNIX) || defined(XP_OS2)
+#include <sys/types.h>
+#endif
+
+/* model.h on HP-UX defines int8, int16, and int32. */
+#ifdef HPUX
+#include <model.h>
+#endif
+
+/*
+ * uint
+ */
+
+#if !defined(XP_BEOS) && !defined(XP_OS2) && !defined(XP_UNIX) || defined(NTO)
+typedef PRUintn uint;
+#endif
+
+/*
+ * uint64
+ */
+
+#if !defined(XP_BEOS)
+typedef PRUint64 uint64;
+#endif
+
+/*
+ * uint32
+ */
+
+#if !defined(XP_BEOS)
+#if !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO)
+typedef PRUint32 uint32;
+#else
+typedef unsigned long uint32;
+#endif
+#endif
+
+/*
+ * uint16
+ */
+
+#if !defined(XP_BEOS)
+typedef PRUint16 uint16;
+#endif
+
+/*
+ * uint8
+ */
+
+#if !defined(XP_BEOS)
+typedef PRUint8 uint8;
+#endif
+
+/*
+ * int64
+ */
+
+#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES)
+typedef PRInt64 int64;
+#endif
+
+/*
+ * int32
+ */
+
+#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \
+    && !defined(HPUX)
+#if !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO)
+typedef PRInt32 int32;
+#else
+typedef long int32;
+#endif
+#endif
+
+/*
+ * int16
+ */
+
+#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \
+    && !defined(HPUX)
+typedef PRInt16 int16;
+#endif
+
+/*
+ * int8
+ */
+
+#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \
+    && !defined(HPUX)
+typedef PRInt8 int8;
+#endif
+
+typedef PRFloat64 float64;
+typedef PRUptrdiff uptrdiff_t;
+typedef PRUword uprword_t;
+typedef PRWord prword_t;
+
+
+/* Re: prbit.h */
+#define TEST_BIT	PR_TEST_BIT
+#define SET_BIT		PR_SET_BIT
+#define CLEAR_BIT	PR_CLEAR_BIT
+
+/* Re: prarena.h->plarena.h */
+#define PRArena PLArena
+#define PRArenaPool PLArenaPool
+#define PRArenaStats PLArenaStats
+#define PR_ARENA_ALIGN PL_ARENA_ALIGN
+#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL
+#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE
+#define PR_ARENA_GROW PL_ARENA_GROW
+#define PR_ARENA_MARK PL_ARENA_MARK
+#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED
+#define PR_CLEAR_ARENA PL_CLEAR_ARENA
+#define PR_ARENA_RELEASE PL_ARENA_RELEASE
+#define PR_COUNT_ARENA PL_COUNT_ARENA
+#define PR_ARENA_DESTROY PL_ARENA_DESTROY
+#define PR_InitArenaPool PL_InitArenaPool
+#define PR_FreeArenaPool PL_FreeArenaPool
+#define PR_FinishArenaPool PL_FinishArenaPool
+#define PR_CompactArenaPool PL_CompactArenaPool
+#define PR_ArenaFinish PL_ArenaFinish
+#define PR_ArenaAllocate PL_ArenaAllocate
+#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: 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
+#define PR_NewHashTable PL_NewHashTable
+#define PR_HashTableDestroy PL_HashTableDestroy
+#define PR_HashTableRawLookup PL_HashTableRawLookup
+#define PR_HashTableRawAdd PL_HashTableRawAdd
+#define PR_HashTableRawRemove PL_HashTableRawRemove
+#define PR_HashTableAdd PL_HashTableAdd
+#define PR_HashTableRemove PL_HashTableRemove
+#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries
+#define PR_HashTableLookup PL_HashTableLookup
+#define PR_HashTableDump PL_HashTableDump
+#define PR_HashString PL_HashString
+#define PR_CompareStrings PL_CompareStrings
+#define PR_CompareValues PL_CompareValues
+
+#endif /* !defined(PROTYPES_H) */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/prsem.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/prsem.h
new file mode 100644
index 0000000..fd0863a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/obsolete/prsem.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prsem_h___
+#define prsem_h___
+
+/*
+** API for counting semaphores. Semaphores are counting synchronizing 
+** variables based on a lock and a condition variable.  They are lightweight 
+** contention control for a given count of resources.
+*/
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRSemaphore PRSemaphore;
+
+/*
+** Create a new semaphore object.
+*/
+NSPR_API(PRSemaphore*) PR_NewSem(PRUintn value);
+
+/*
+** Destroy the given semaphore object.
+**
+*/
+NSPR_API(void) PR_DestroySem(PRSemaphore *sem);
+
+/*
+** Wait on a Semaphore.
+** 
+** This routine allows a calling thread to wait or proceed depending upon the 
+** state of the semahore sem. The thread can proceed only if the counter value 
+** of the semaphore sem is currently greater than 0. If the value of semaphore 
+** sem is positive, it is decremented by one and the routine returns immediately 
+** allowing the calling thread to continue. If the value of semaphore sem is 0, 
+** the calling thread blocks awaiting the semaphore to be released by another 
+** thread.
+** 
+** This routine can return PR_PENDING_INTERRUPT if the waiting thread 
+** has been interrupted.
+*/
+NSPR_API(PRStatus) PR_WaitSem(PRSemaphore *sem);
+
+/*
+** This routine increments the counter value of the semaphore. If other threads 
+** are blocked for the semaphore, then the scheduler will determine which ONE 
+** thread will be unblocked.
+*/
+NSPR_API(void) PR_PostSem(PRSemaphore *sem);
+
+/*
+** Returns the value of the semaphore referenced by sem without affecting
+** the state of the semaphore.  The value represents the semaphore vaule
+F** at the time of the call, but may not be the actual value when the
+** caller inspects it.
+*/
+NSPR_API(PRUintn) PR_GetValueSem(PRSemaphore *sem);
+
+PR_END_EXTERN_C
+
+#endif /* prsem_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/pratom.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/pratom.h
new file mode 100644
index 0000000..24c03e1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/pratom.h
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* GLOBAL FUNCTIONS:
+** DESCRIPTION:
+**     PR Atomic operations
+*/
+
+#ifndef pratom_h___
+#define pratom_h___
+
+#include "prtypes.h"
+#include "prlock.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** FUNCTION: PR_AtomicIncrement
+** DESCRIPTION:
+**    Atomically increment a 32 bit value.
+** INPUTS:
+**    val:  a pointer to the value to increment
+** RETURN:
+**    the returned value is the result of the increment
+*/
+NSPR_API(PRInt32)	PR_AtomicIncrement(PRInt32 *val);
+
+/*
+** FUNCTION: PR_AtomicDecrement
+** DESCRIPTION:
+**    Atomically decrement a 32 bit value.
+** INPUTS:
+**    val:  a pointer to the value to decrement
+** RETURN:
+**    the returned value is the result of the decrement
+*/
+NSPR_API(PRInt32)	PR_AtomicDecrement(PRInt32 *val);
+
+/*
+** FUNCTION: PR_AtomicSet
+** DESCRIPTION:
+**    Atomically set a 32 bit value.
+** INPUTS:
+**    val: A pointer to a 32 bit value to be set
+**    newval: The newvalue to assign to val
+** RETURN:
+**    Returns the prior value
+*/
+NSPR_API(PRInt32) PR_AtomicSet(PRInt32 *val, PRInt32 newval);
+
+/*
+** FUNCTION: PR_AtomicAdd
+** DESCRIPTION:
+**    Atomically add a 32 bit value.
+** INPUTS:
+**    ptr:  a pointer to the value to increment
+**	  val:  value to be added
+** RETURN:
+**    the returned value is the result of the addition
+*/
+NSPR_API(PRInt32)	PR_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+
+/*
+** MACRO: PR_ATOMIC_INCREMENT
+** MACRO: PR_ATOMIC_DECREMENT
+** MACRO: PR_ATOMIC_SET
+** MACRO: PR_ATOMIC_ADD
+** DESCRIPTION:
+**    Macro versions of the atomic operations.  They may be implemented
+**    as compiler intrinsics.
+**
+** IMPORTANT NOTE TO NSPR MAINTAINERS:
+**    Implement these macros with compiler intrinsics only on platforms
+**    where the PR_AtomicXXX functions are truly atomic (i.e., where the
+**    configuration macro _PR_HAVE_ATOMIC_OPS is defined).  Otherwise,
+**    the macros and functions won't be compatible and can't be used
+**    interchangeably.
+*/
+#if defined(_WIN32) && !defined(_WIN32_WCE) && \
+    defined(_MSC_VER) && (_MSC_VER >= 1310)
+
+long __cdecl _InterlockedIncrement(long volatile *Addend);
+#pragma intrinsic(_InterlockedIncrement)
+
+long __cdecl _InterlockedDecrement(long volatile *Addend);
+#pragma intrinsic(_InterlockedDecrement)
+
+long __cdecl _InterlockedExchange(long volatile *Target, long Value);
+#pragma intrinsic(_InterlockedExchange)
+
+long __cdecl _InterlockedExchangeAdd(long volatile *Addend, long Value);
+#pragma intrinsic(_InterlockedExchangeAdd)
+
+#define PR_ATOMIC_INCREMENT(val) _InterlockedIncrement((long volatile *)(val))
+#define PR_ATOMIC_DECREMENT(val) _InterlockedDecrement((long volatile *)(val))
+#define PR_ATOMIC_SET(val, newval) \
+        _InterlockedExchange((long volatile *)(val), (long)(newval))
+#define PR_ATOMIC_ADD(ptr, val) \
+        (_InterlockedExchangeAdd((long volatile *)(ptr), (long)(val)) + (val))
+
+#elif ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && \
+      ((defined(DARWIN) && \
+           (defined(__ppc__) || defined(__i386__) || defined(__x86_64__))) || \
+       (defined(LINUX) && \
+           ((defined(__i386__) && \
+           defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \
+           defined(__ia64__) || defined(__x86_64__) || \
+           (defined(__powerpc__) && !defined(__powerpc64__)) || \
+           defined(__alpha))))
+
+/*
+ * Because the GCC manual warns that some processors may support
+ * reduced functionality of __sync_lock_test_and_set, we test for the
+ * processors that we believe support a full atomic exchange operation.
+ */
+
+#define PR_ATOMIC_INCREMENT(val) __sync_add_and_fetch(val, 1)
+#define PR_ATOMIC_DECREMENT(val) __sync_sub_and_fetch(val, 1)
+#define PR_ATOMIC_SET(val, newval) __sync_lock_test_and_set(val, newval)
+#define PR_ATOMIC_ADD(ptr, val) __sync_add_and_fetch(ptr, val)
+
+#else
+
+#define PR_ATOMIC_INCREMENT(val) PR_AtomicIncrement(val)
+#define PR_ATOMIC_DECREMENT(val) PR_AtomicDecrement(val)
+#define PR_ATOMIC_SET(val, newval) PR_AtomicSet(val, newval)
+#define PR_ATOMIC_ADD(ptr, val) PR_AtomicAdd(ptr, val)
+
+#endif
+
+/*
+** LIFO linked-list (stack)
+*/
+typedef struct PRStackElemStr PRStackElem;
+
+struct PRStackElemStr {
+    PRStackElem	*prstk_elem_next;	/* next pointer MUST be at offset 0;
+									  assembly language code relies on this */
+};
+
+typedef struct PRStackStr PRStack;
+
+/*
+** FUNCTION: PR_CreateStack
+** DESCRIPTION:
+**    Create a stack, a LIFO linked list
+** INPUTS:
+**    stack_name:  a pointer to string containing the name of the stack
+** RETURN:
+**    A pointer to the created stack, if successful, else NULL.
+*/
+NSPR_API(PRStack *)	PR_CreateStack(const char *stack_name);
+
+/*
+** FUNCTION: PR_StackPush
+** DESCRIPTION:
+**    Push an element on the top of the stack
+** INPUTS:
+**    stack:		pointer to the stack
+**    stack_elem:	pointer to the stack element
+** RETURN:
+**    None
+*/
+NSPR_API(void)			PR_StackPush(PRStack *stack, PRStackElem *stack_elem);
+
+/*
+** FUNCTION: PR_StackPop
+** DESCRIPTION:
+**    Remove the element on the top of the stack
+** INPUTS:
+**    stack:		pointer to the stack
+** RETURN:
+**    A pointer to the stack element removed from the top of the stack,
+**	  if non-empty,
+**    else NULL
+*/
+NSPR_API(PRStackElem *)	PR_StackPop(PRStack *stack);
+
+/*
+** FUNCTION: PR_DestroyStack
+** DESCRIPTION:
+**    Destroy the stack
+** INPUTS:
+**    stack:		pointer to the stack
+** RETURN:
+**    PR_SUCCESS - if successfully deleted
+**	  PR_FAILURE - if the stack is not empty
+**					PR_GetError will return
+**						PR_INVALID_STATE_ERROR - stack is not empty
+*/
+NSPR_API(PRStatus)		PR_DestroyStack(PRStack *stack);
+
+PR_END_EXTERN_C
+
+#endif /* pratom_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prbit.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prbit.h
new file mode 100644
index 0000000..3de054b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prbit.h
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prbit_h___
+#define prbit_h___
+
+#include "prtypes.h"
+PR_BEGIN_EXTERN_C
+
+/* replace compare/jump/add/shift sequence with x86 BSF/BSR instruction */
+#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64))
+  unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask);
+  unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask);
+# pragma  intrinsic(_BitScanForward,_BitScanReverse)
+  __forceinline static int __prBitScanForward32(unsigned int val)
+  { 
+    unsigned long idx;
+    _BitScanForward(&idx, (unsigned long)val);
+    return( (int)idx );
+  }
+  __forceinline static int __prBitScanReverse32(unsigned int val)
+  {
+    unsigned long idx;
+    _BitScanReverse(&idx, (unsigned long)val);
+    return( (int)(31-idx) );
+  }
+# define pr_bitscan_ctz32(val)  __prBitScanForward32(val)
+# define pr_bitscan_clz32(val)  __prBitScanReverse32(val)
+# define  PR_HAVE_BUILTIN_BITSCAN32
+#elif ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && \
+       (defined(__i386__) || defined(__x86_64__) || defined(__arm__))
+# define pr_bitscan_ctz32(val)  __builtin_ctz(val)
+# define pr_bitscan_clz32(val)  __builtin_clz(val)
+# define  PR_HAVE_BUILTIN_BITSCAN32
+#endif /* MSVC || GCC */
+
+/*
+** A prbitmap_t is a long integer that can be used for bitmaps
+*/
+typedef unsigned long prbitmap_t;
+
+#define PR_TEST_BIT(_map,_bit) \
+    ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] & (1L << ((_bit) & (PR_BITS_PER_LONG-1))))
+#define PR_SET_BIT(_map,_bit) \
+    ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] |= (1L << ((_bit) & (PR_BITS_PER_LONG-1))))
+#define PR_CLEAR_BIT(_map,_bit) \
+    ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] &= ~(1L << ((_bit) & (PR_BITS_PER_LONG-1))))
+
+/*
+** Compute the log of the least power of 2 greater than or equal to n
+*/
+NSPR_API(PRIntn) PR_CeilingLog2(PRUint32 i); 
+
+/*
+** Compute the log of the greatest power of 2 less than or equal to n
+*/
+NSPR_API(PRIntn) PR_FloorLog2(PRUint32 i); 
+
+/*
+** Macro version of PR_CeilingLog2: Compute the log of the least power of
+** 2 greater than or equal to _n. The result is returned in _log2.
+*/
+#ifdef PR_HAVE_BUILTIN_BITSCAN32 
+#define PR_CEILING_LOG2(_log2,_n)      \
+  PR_BEGIN_MACRO                       \
+    PRUint32 j_ = (PRUint32)(_n);      \
+    (_log2) = (j_ <= 1 ? 0 : 32 - pr_bitscan_clz32(j_ - 1)); \
+  PR_END_MACRO
+#else
+#define PR_CEILING_LOG2(_log2,_n)   \
+  PR_BEGIN_MACRO                    \
+    PRUint32 j_ = (PRUint32)(_n); 	\
+    (_log2) = 0;                    \
+    if ((j_) & ((j_)-1))            \
+	(_log2) += 1;               \
+    if ((j_) >> 16)                 \
+	(_log2) += 16, (j_) >>= 16; \
+    if ((j_) >> 8)                  \
+	(_log2) += 8, (j_) >>= 8;   \
+    if ((j_) >> 4)                  \
+	(_log2) += 4, (j_) >>= 4;   \
+    if ((j_) >> 2)                  \
+	(_log2) += 2, (j_) >>= 2;   \
+    if ((j_) >> 1)                  \
+	(_log2) += 1;               \
+  PR_END_MACRO
+#endif /* PR_HAVE_BUILTIN_BITSCAN32 */
+
+/*
+** Macro version of PR_FloorLog2: Compute the log of the greatest power of
+** 2 less than or equal to _n. The result is returned in _log2.
+**
+** This is equivalent to finding the highest set bit in the word.
+*/
+#ifdef PR_HAVE_BUILTIN_BITSCAN32
+#define PR_FLOOR_LOG2(_log2,_n)     \
+  PR_BEGIN_MACRO                    \
+    PRUint32 j_ = (PRUint32)(_n);   \
+    (_log2) = 31 - pr_bitscan_clz32((j_) | 1); \
+  PR_END_MACRO
+#else
+#define PR_FLOOR_LOG2(_log2,_n)   \
+  PR_BEGIN_MACRO                    \
+    PRUint32 j_ = (PRUint32)(_n); 	\
+    (_log2) = 0;                    \
+    if ((j_) >> 16)                 \
+	(_log2) += 16, (j_) >>= 16; \
+    if ((j_) >> 8)                  \
+	(_log2) += 8, (j_) >>= 8;   \
+    if ((j_) >> 4)                  \
+	(_log2) += 4, (j_) >>= 4;   \
+    if ((j_) >> 2)                  \
+	(_log2) += 2, (j_) >>= 2;   \
+    if ((j_) >> 1)                  \
+	(_log2) += 1;               \
+  PR_END_MACRO
+#endif /* PR_HAVE_BUILTIN_BITSCAN32 */
+
+/*
+** Macros for rotate left and right. The argument 'a' must be an unsigned
+** 32-bit integer type such as PRUint32.
+**
+** There is no rotate operation in the C Language, so the construct
+** (a << 4) | (a >> 28) is frequently used instead. Most compilers convert
+** this to a rotate instruction, but MSVC doesn't without a little help.
+** To get MSVC to generate a rotate instruction, we have to use the _rotl
+** or _rotr intrinsic and use a pragma to make it inline.
+**
+** Note: MSVC in VS2005 will do an inline rotate instruction on the above
+** construct.
+*/
+
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \
+    defined(_M_X64))
+#include <stdlib.h>
+#pragma intrinsic(_rotl, _rotr)
+#define PR_ROTATE_LEFT32(a, bits) _rotl(a, bits)
+#define PR_ROTATE_RIGHT32(a, bits) _rotr(a, bits)
+#else
+#define PR_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits))))
+#define PR_ROTATE_RIGHT32(a, bits) (((a) >> (bits)) | ((a) << (32 - (bits))))
+#endif
+
+PR_END_EXTERN_C
+#endif /* prbit_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prclist.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prclist.h
new file mode 100644
index 0000000..1680ac1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prclist.h
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prclist_h___
+#define prclist_h___
+
+#include "prtypes.h"
+
+typedef struct PRCListStr PRCList;
+
+/*
+** Circular linked list
+*/
+struct PRCListStr {
+    PRCList	*next;
+    PRCList	*prev;
+};
+
+/*
+** Insert element "_e" into the list, before "_l".
+*/
+#define PR_INSERT_BEFORE(_e,_l)	 \
+    PR_BEGIN_MACRO		 \
+	(_e)->next = (_l);	 \
+	(_e)->prev = (_l)->prev; \
+	(_l)->prev->next = (_e); \
+	(_l)->prev = (_e);	 \
+    PR_END_MACRO
+
+/*
+** Insert element "_e" into the list, after "_l".
+*/
+#define PR_INSERT_AFTER(_e,_l)	 \
+    PR_BEGIN_MACRO		 \
+	(_e)->next = (_l)->next; \
+	(_e)->prev = (_l);	 \
+	(_l)->next->prev = (_e); \
+	(_l)->next = (_e);	 \
+    PR_END_MACRO
+
+/*
+** Return the element following element "_e"
+*/
+#define PR_NEXT_LINK(_e)	 \
+    	((_e)->next)
+/*
+** Return the element preceding element "_e"
+*/
+#define PR_PREV_LINK(_e)	 \
+    	((_e)->prev)
+
+/*
+** Append an element "_e" to the end of the list "_l"
+*/
+#define PR_APPEND_LINK(_e,_l) PR_INSERT_BEFORE(_e,_l)
+
+/*
+** Insert an element "_e" at the head of the list "_l"
+*/
+#define PR_INSERT_LINK(_e,_l) PR_INSERT_AFTER(_e,_l)
+
+/* Return the head/tail of the list */
+#define PR_LIST_HEAD(_l) (_l)->next
+#define PR_LIST_TAIL(_l) (_l)->prev
+
+/*
+** Remove the element "_e" from it's circular list.
+*/
+#define PR_REMOVE_LINK(_e)	       \
+    PR_BEGIN_MACRO		       \
+	(_e)->prev->next = (_e)->next; \
+	(_e)->next->prev = (_e)->prev; \
+    PR_END_MACRO
+
+/*
+** Remove the element "_e" from it's circular list. Also initializes the
+** linkage.
+*/
+#define PR_REMOVE_AND_INIT_LINK(_e)    \
+    PR_BEGIN_MACRO		       \
+	(_e)->prev->next = (_e)->next; \
+	(_e)->next->prev = (_e)->prev; \
+	(_e)->next = (_e);	       \
+	(_e)->prev = (_e);	       \
+    PR_END_MACRO
+
+/*
+** Return non-zero if the given circular list "_l" is empty, zero if the
+** circular list is not empty
+*/
+#define PR_CLIST_IS_EMPTY(_l) \
+    ((_l)->next == (_l))
+
+/*
+** Initialize a circular list
+*/
+#define PR_INIT_CLIST(_l)  \
+    PR_BEGIN_MACRO	   \
+	(_l)->next = (_l); \
+	(_l)->prev = (_l); \
+    PR_END_MACRO
+
+#define PR_INIT_STATIC_CLIST(_l) \
+    {(_l), (_l)}
+
+#endif /* prclist_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prcmon.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prcmon.h
new file mode 100644
index 0000000..f61cf56
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prcmon.h
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prcmon_h___
+#define prcmon_h___
+
+/*
+** Interface to cached monitors. Cached monitors use an address to find a
+** given PR monitor. In this way a monitor can be associated with another
+** object without preallocating a monitor for all objects.
+**
+** A hash table is used to quickly map addresses to individual monitors
+** and the system automatically grows the hash table as needed.
+**
+** Cache monitors are about 5 times slower to use than uncached monitors.
+*/
+#include "prmon.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+/**
+** Like PR_EnterMonitor except use the "address" to find a monitor in the
+** monitor cache. If successful, returns the PRMonitor now associated
+** with "address". Note that you must PR_CExitMonitor the address to
+** release the monitor cache entry (otherwise the monitor cache will fill
+** up). This call will return NULL if the monitor cache needs to be
+** expanded and the system is out of memory.
+*/
+NSPR_API(PRMonitor*) PR_CEnterMonitor(void *address);
+
+/*
+** Like PR_ExitMonitor except use the "address" to find a monitor in the
+** monitor cache.
+*/
+NSPR_API(PRStatus) PR_CExitMonitor(void *address);
+
+/*
+** Like PR_Wait except use the "address" to find a monitor in the
+** monitor cache.
+*/
+NSPR_API(PRStatus) PR_CWait(void *address, PRIntervalTime timeout);
+
+/*
+** Like PR_Notify except use the "address" to find a monitor in the
+** monitor cache.
+*/
+NSPR_API(PRStatus) PR_CNotify(void *address);
+
+/*
+** Like PR_NotifyAll except use the "address" to find a monitor in the
+** monitor cache.
+*/
+NSPR_API(PRStatus) PR_CNotifyAll(void *address);
+
+/*
+** Set a callback to be invoked each time a monitor is recycled from the cache
+** freelist, with the monitor's cache-key passed in address.
+*/
+NSPR_API(void) PR_CSetOnMonitorRecycle(void (PR_CALLBACK *callback)(void *address));
+
+PR_END_EXTERN_C
+
+#endif /* prcmon_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prcountr.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prcountr.h
new file mode 100644
index 0000000..4b197e9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prcountr.h
@@ -0,0 +1,557 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prcountr_h___
+#define prcountr_h___
+
+/*----------------------------------------------------------------------------
+** prcountr.h -- NSPR Instrumentation counters
+**
+** The NSPR Counter Feature provides a means to "count
+** something." Counters can be dynamically defined, incremented,
+** decremented, set, and deleted under application program
+** control.
+** 																                   
+** The Counter Feature is intended to be used as instrumentation,                  
+** not as operational data. If you need a counter for operational                  
+** data, use native integral types.                                                
+** 																                   
+** Counters are 32bit unsigned intergers. On overflow, a counter                   
+** will wrap. No exception is recognized or reported.                              
+**                                                                                 
+** A counter can be dynamically created using a two level naming
+** convention. A "handle" is returned when the counter is
+** created. The counter can subsequently be addressed by its
+** handle. An API is provided to get an existing counter's handle
+** given the names with  which it was originally created. 
+** Similarly, a counter's name can be retrieved given its handle.
+** 
+** The counter naming convention is a two-level hierarchy. The
+** QName is the higher level of the hierarchy; RName is the
+** lower level. RNames can be thought of as existing within a
+** QName. The same RName can exist within multiple QNames. QNames
+** are unique. The NSPR Counter is not a near-zero overhead
+** feature. Application designers should be aware of 
+** serialization issues when using the Counter API. Creating a
+** counter locks a large asset, potentially causing a stall. This
+** suggest that applications should create counters at component
+** initialization, for example, and not create and destroy them
+** willy-nilly. ... You have been warned.
+** 
+** Incrementing and Adding to counters uses atomic operations.
+** The performance of these operations will vary from platform
+** to platform. On platforms where atomic operations are not
+** supported the overhead may be substantial.
+** 
+** When traversing the counter database with FindNext functions,
+** the instantaneous values of any given counter is that at the
+** moment of extraction. The state of the entire counter database
+** may not be viewed as atomic.
+** 
+** The counter interface may be disabled (No-Op'd) at compile
+** time. When DEBUG is defined at compile time, the Counter
+** Feature is compiled into NSPR and applications invoking it.
+** When DEBUG is not defined, the counter macros compile to
+** nothing. To force the Counter Feature to be compiled into an
+** optimized build, define FORCE_NSPR_COUNTERS at compile time
+** for both NSPR and the application intending to use it.
+** 
+** Application designers should use the macro form of the Counter
+** Feature methods to minimize performance impact in optimized
+** builds. The macros normally compile to nothing on optimized
+** builds.
+** 
+** Application designers should be aware of the effects of
+** debug and optimized build differences when using result of the
+** Counter Feature macros in expressions.
+** 
+** The Counter Feature is thread-safe and SMP safe.
+** 
+** /lth. 09-Jun-1998.
+*/
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Opaque counter handle type.
+** ... don't even think of looking in here.
+**
+*/
+typedef void *  PRCounterHandle;
+
+#define PRCOUNTER_NAME_MAX 31
+#define PRCOUNTER_DESC_MAX 255
+
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DEFINE_COUNTER() -- Define a PRCounterHandle
+** 
+** DESCRIPTION: PR_DEFINE_COUNTER() is used to define a counter
+** handle.
+** 
+*/
+#define PR_DEFINE_COUNTER(name) PRCounterHandle name
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_INIT_COUNTER_HANDLE() -- Set the value of a PRCounterHandle
+** 
+** DESCRIPTION: 
+** PR_INIT_COUNTER_HANDLE() sets the value of a PRCounterHandle
+** to value.
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_INIT_COUNTER_HANDLE(handle,value)\
+    (handle) = (PRCounterHandle)(value)
+#else
+#define PR_INIT_COUNTER_HANDLE(handle,value)
+#endif
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_CreateCounter() -- Create a counter
+** 
+** DESCRIPTION: PR_CreateCounter() creates a counter object and
+** initializes it to zero.
+** 
+** The macro form takes as its first argument the name of the
+** PRCounterHandle to receive the handle returned from
+** PR_CreateCounter().
+** 
+** INPUTS:
+**  qName: The QName for the counter object. The maximum length
+** of qName is defined by PRCOUNTER_NAME_MAX
+** 
+**  rName: The RName for the counter object. The maximum length
+** of qName is defined by PRCOUNTER_NAME_MAX
+** 
+**  descrioption: The description of the counter object. The
+** maximum length of description is defined by
+** PRCOUNTER_DESC_MAX.
+** 
+** OUTPUTS:
+** 
+** RETURNS:
+**  PRCounterHandle.
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_CREATE_COUNTER(handle,qName,rName,description)\
+   (handle) = PR_CreateCounter((qName),(rName),(description))
+#else
+#define PR_CREATE_COUNTER(handle,qName,rName,description)
+#endif
+
+NSPR_API(PRCounterHandle) 
+	PR_CreateCounter( 
+		const char *qName, 
+    	const char *rName, 
+        const char *description 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DestroyCounter() -- Destroy a counter object.
+** 
+** DESCRIPTION: PR_DestroyCounter() removes a counter and
+** unregisters its handle from the counter database.
+** 
+** INPUTS:
+**  handle: the PRCounterHandle of the counter to be destroyed.
+** 
+** OUTPUTS: 
+**  The counter is destroyed.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_DESTROY_COUNTER(handle) PR_DestroyCounter((handle))
+#else
+#define PR_DESTROY_COUNTER(handle)
+#endif
+
+NSPR_API(void) 
+	PR_DestroyCounter( 
+		PRCounterHandle handle 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetCounterHandleFromName() -- Retreive a
+** counter's handle give its name.
+** 
+** DESCRIPTION: PR_GetCounterHandleFromName() retreives a
+** counter's handle from the counter database, given the name
+** the counter was originally created with.
+** 
+** INPUTS:
+**  qName: Counter's original QName.
+**  rName: Counter's original RName.
+** 
+** OUTPUTS:
+** 
+** RETURNS: 
+**  PRCounterHandle or PRCounterError.
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)\
+    (handle) = PR_GetCounterHandleFromName((qName),(rName))
+#else
+#define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)
+#endif
+
+NSPR_API(PRCounterHandle) 
+	PR_GetCounterHandleFromName( 
+    	const char *qName, 
+    	const char *rName 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetCounterNameFromHandle() -- Retreive a
+** counter's name, given its handle.
+** 
+** DESCRIPTION: PR_GetCounterNameFromHandle() retreives a
+** counter's name given its handle.
+** 
+** INPUTS:
+**  qName: Where to store a pointer to qName.
+**  rName: Where to store a pointer to rName.
+**  description: Where to store a pointer to description.
+** 
+** OUTPUTS: Pointers to the Counter Feature's copies of the names
+** used when the counters were created.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description)\
+    PR_GetCounterNameFromHandle((handle),(qName),(rName),(description))
+#else
+#define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description )
+#endif
+
+NSPR_API(void) 
+	PR_GetCounterNameFromHandle( 
+    	PRCounterHandle handle,  
+	    const char **qName, 
+	    const char **rName, 
+		const char **description 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_IncrementCounter() -- Add one to the referenced
+** counter.
+** 
+** DESCRIPTION: Add one to the referenced counter.
+** 
+** INPUTS:
+**  handle: The PRCounterHandle of the counter to be incremented
+** 
+** OUTPUTS: The counter is incrementd.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_INCREMENT_COUNTER(handle) PR_IncrementCounter(handle)
+#else
+#define PR_INCREMENT_COUNTER(handle)
+#endif
+
+NSPR_API(void) 
+	PR_IncrementCounter( 
+		PRCounterHandle handle
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DecrementCounter() -- Subtract one from the
+** referenced counter
+** 
+** DESCRIPTION: Subtract one from the referenced counter.
+** 
+** INPUTS: 
+**  handle: The PRCounterHandle of the coutner to be
+** decremented.
+** 
+** OUTPUTS: the counter is decremented.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_DECREMENT_COUNTER(handle) PR_DecrementCounter(handle)
+#else
+#define PR_DECREMENT_COUNTER(handle)
+#endif
+
+NSPR_API(void) 
+	PR_DecrementCounter( 
+		PRCounterHandle handle
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_AddToCounter() -- Add a value to a counter.
+** 
+** DESCRIPTION: Add value to the counter referenced by handle.
+** 
+** INPUTS:
+**  handle: the PRCounterHandle of the counter to be added to.
+** 
+**  value: the value to be added to the counter.
+** 
+** OUTPUTS: new value for counter.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_ADD_TO_COUNTER(handle,value)\
+    PR_AddToCounter((handle),(value))
+#else
+#define PR_ADD_TO_COUNTER(handle,value)
+#endif
+
+NSPR_API(void) 
+	PR_AddToCounter( 
+    	PRCounterHandle handle, 
+	    PRUint32 value 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_SubtractFromCounter() -- A value is subtracted
+** from a counter.
+** 
+** DESCRIPTION:
+** Subtract a value from a counter.
+** 
+** INPUTS:
+**  handle: the PRCounterHandle of the counter to be subtracted
+** from.
+** 
+**  value: the value to be subtracted from the counter.
+** 
+** OUTPUTS: new value for counter
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_SUBTRACT_FROM_COUNTER(handle,value)\
+    PR_SubtractFromCounter((handle),(value))
+#else
+#define PR_SUBTRACT_FROM_COUNTER(handle,value)
+#endif
+
+NSPR_API(void) 
+	PR_SubtractFromCounter( 
+    	PRCounterHandle handle, 
+	    PRUint32 value 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetCounter() -- Retreive the value of a counter
+** 
+** DESCRIPTION:
+** Retreive the value of a counter.
+** 
+** INPUTS:
+**  handle: the PR_CounterHandle of the counter to be retreived
+** 
+** OUTPUTS:
+** 
+** RETURNS: The value of the referenced counter
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_GET_COUNTER(counter,handle)\
+    (counter) = PR_GetCounter((handle))
+#else
+#define PR_GET_COUNTER(counter,handle) 0
+#endif
+
+NSPR_API(PRUint32) 
+	PR_GetCounter( 
+		PRCounterHandle handle 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_SetCounter() -- Replace the content of counter
+** with value.
+** 
+** DESCRIPTION: The contents of the referenced counter are
+** replaced by value.
+** 
+** INPUTS:
+**  handle: the PRCounterHandle of the counter whose contents
+** are to be replaced.
+** 
+**  value: the new value of the counter.
+** 
+** OUTPUTS:
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_SET_COUNTER(handle,value) PR_SetCounter((handle),(value))
+#else
+#define PR_SET_COUNTER(handle,value)
+#endif
+
+NSPR_API(void) 
+	PR_SetCounter( 
+		PRCounterHandle handle, 
+		PRUint32 value 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_FindNextCounterQname() -- Retreive the next QName counter
+** handle iterator
+** 
+** DESCRIPTION:
+** PR_FindNextCounterQname() retreives the first or next Qname
+** the counter data base, depending on the value of handle. When
+** handle is NULL, the function attempts to retreive the first
+** QName handle in the database. When handle is a handle previosly
+** retreived QName handle, then the function attempts to retreive
+** the next QName handle.
+** 
+** INPUTS: 
+**  handle: PRCounterHandle or NULL.
+** 
+** OUTPUTS: returned
+** 
+** RETURNS: PRCounterHandle or NULL when no more QName counter
+** handles are present.
+** 
+** RESTRICTIONS:
+**  A concurrent PR_CreateCounter() or PR_DestroyCounter() may
+** cause unpredictable results.
+** 
+** A PRCounterHandle returned from this function may only be used
+** in another PR_FindNextCounterQname() function call; other
+** operations may cause unpredictable results.
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_FIND_NEXT_COUNTER_QNAME(next,handle)\
+    (next) = PR_FindNextCounterQname((handle))
+#else
+#define PR_FIND_NEXT_COUNTER_QNAME(next,handle) NULL
+#endif
+
+NSPR_API(PRCounterHandle) 
+	PR_FindNextCounterQname( 
+        PRCounterHandle handle
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_FindNextCounterRname() -- Retreive the next RName counter
+** handle iterator
+** 
+** DESCRIPTION:
+** PR_FindNextCounterRname() retreives the first or next RNname
+** handle from the counter data base, depending on the
+** value of handle. When handle is NULL, the function attempts to
+** retreive the first RName handle in the database. When handle is
+** a handle previosly retreived RName handle, then the function
+** attempts to retreive the next RName handle.
+** 
+** INPUTS:
+**  handle: PRCounterHandle or NULL.
+**  qhandle: PRCounterHandle of a previously aquired via
+** PR_FIND_NEXT_QNAME_HANDLE()
+** 
+** OUTPUTS: returned
+** 
+** RETURNS: PRCounterHandle or NULL when no more RName counter
+** handles are present.
+** 
+** RESTRICTIONS:
+**  A concurrent PR_CreateCounter() or PR_DestroyCounter() may
+** cause unpredictable results.
+** 
+** A PRCounterHandle returned from this function may only be used
+** in another PR_FindNextCounterRname() function call; other
+** operations may cause unpredictable results.
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)\
+    (next) = PR_FindNextCounterRname((rhandle),(qhandle))
+#else
+#define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)
+#endif
+
+NSPR_API(PRCounterHandle) 
+	PR_FindNextCounterRname( 
+        PRCounterHandle rhandle,
+        PRCounterHandle qhandle
+);
+
+PR_END_EXTERN_C
+
+#endif /* prcountr_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prcvar.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prcvar.h
new file mode 100644
index 0000000..c668493
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prcvar.h
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prcvar_h___
+#define prcvar_h___
+
+#include "prlock.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRCondVar PRCondVar;
+
+/*
+** Create a new condition variable.
+**
+** 	"lock" is the lock used to protect the condition variable.
+**
+** Condition variables are synchronization objects that threads can use
+** to wait for some condition to occur.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low. In such cases, a NULL will be returned.
+*/
+NSPR_API(PRCondVar*) PR_NewCondVar(PRLock *lock);
+
+/*
+** Destroy a condition variable. There must be no thread
+** waiting on the condvar. The caller is responsible for guaranteeing
+** that the condvar is no longer in use.
+**
+*/
+NSPR_API(void) PR_DestroyCondVar(PRCondVar *cvar);
+
+/*
+** The thread that waits on a condition is blocked in a "waiting on
+** condition" state until another thread notifies the condition or a
+** caller specified amount of time expires. The lock associated with
+** the condition variable will be released, which must have be held
+** prior to the call to wait.
+**
+** Logically a notified thread is moved from the "waiting on condition"
+** state and made "ready." When scheduled, it will attempt to reacquire
+** the lock that it held when wait was called.
+**
+** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and
+** PR_INTERVAL_NO_WAIT. The former value requires that a condition be
+** notified (or the thread interrupted) before it will resume from the
+** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect
+** is to release the lock, possibly causing a rescheduling within the
+** runtime, then immediately attempting to reacquire the lock and resume.
+**
+** Any other value for timeout will cause the thread to be rescheduled
+** either due to explicit notification or an expired interval. The latter
+** must be determined by treating time as one part of the monitored data
+** being protected by the lock and tested explicitly for an expired
+** interval.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable or the thread was interrupted (PR_Interrupt()).
+** The particular reason can be extracted with PR_GetError().
+*/
+NSPR_API(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout);
+
+/*
+** Notify ONE thread that is currently waiting on 'cvar'. Which thread is
+** dependent on the implementation of the runtime. Common sense would dictate
+** that all threads waiting on a single condition have identical semantics,
+** therefore which one gets notified is not significant. 
+**
+** The calling thead must hold the lock that protects the condition, as
+** well as the invariants that are tightly bound to the condition, when
+** notify is called.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+*/
+NSPR_API(PRStatus) PR_NotifyCondVar(PRCondVar *cvar);
+
+/*
+** Notify all of the threads waiting on the condition variable. The order
+** that the threads are notified is indeterminant. The lock that protects
+** the condition must be held.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+*/
+NSPR_API(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar);
+
+PR_END_EXTERN_C
+
+#endif /* prcvar_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prdtoa.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prdtoa.h
new file mode 100644
index 0000000..c71725a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prdtoa.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prdtoa_h___
+#define prdtoa_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** PR_strtod() returns as a double-precision floating-point number
+** the  value represented by the character string pointed to by
+** s00. The string is scanned up to the first unrecognized
+** character.
+**a
+** If the value of se is not (char **)NULL, a  pointer  to
+** the  character terminating the scan is returned in the location pointed
+** to by se. If no number can be formed, se is set to s00, and
+** zero is returned.
+*/
+NSPR_API(PRFloat64)
+PR_strtod(const char *s00, char **se);
+
+/*
+** PR_cnvtf()
+** conversion routines for floating point
+** prcsn - number of digits of precision to generate floating
+** point value.
+*/
+NSPR_API(void) PR_cnvtf(char *buf, PRIntn bufsz, PRIntn prcsn, PRFloat64 fval);
+
+/*
+** PR_dtoa() converts double to a string.
+**
+** ARGUMENTS:
+** If rve is not null, *rve is set to point to the end of the return value.
+** If d is +-Infinity or NaN, then *decpt is set to 9999.
+**
+** mode:
+**     0 ==> shortest string that yields d when read in
+**           and rounded to nearest.
+*/
+NSPR_API(PRStatus) PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits,
+	PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize);
+
+PR_END_EXTERN_C
+
+#endif /* prdtoa_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prenv.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prenv.h
new file mode 100644
index 0000000..c73fffc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prenv.h
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prenv_h___
+#define prenv_h___
+
+#include "prtypes.h"
+
+/*******************************************************************************/
+/*******************************************************************************/
+/****************** THESE FUNCTIONS MAY NOT BE THREAD SAFE *********************/
+/*******************************************************************************/
+/*******************************************************************************/
+
+PR_BEGIN_EXTERN_C
+
+/*
+** PR_GetEnv() -- Retrieve value of environment variable
+** 
+** Description:
+** PR_GetEnv() is modeled on Unix getenv().
+** 
+** 
+** Inputs: 
+**   var -- The name of the environment variable
+** 
+** Returns:
+**   The value of the environment variable 'var' or NULL if
+** the variable is undefined.
+** 
+** Restrictions:
+**   You'd think that a POSIX getenv(), putenv() would be
+**   consistently implemented everywhere. Surprise! It is not. On
+**   some platforms, a putenv() where the argument is of
+**   the form "name"  causes the named environment variable to
+**   be un-set; that is: a subsequent getenv() returns NULL. On
+**   other platforms, the putenv() fails, on others, it is a
+**   no-op. Similarly, a putenv() where the argument is of the
+**   form "name=" causes the named environment variable to be
+**   un-set; a subsequent call to getenv() returns NULL. On
+**   other platforms, a subsequent call to getenv() returns a
+**   pointer to a null-string (a byte of zero).
+** 
+**   PR_GetEnv(), PR_SetEnv() provide a consistent behavior 
+**   across all supported platforms. There are, however, some
+**   restrictions and some practices you must use to achieve
+**   consistent results everywhere.
+** 
+**   When manipulating the environment there is no way to un-set
+**   an environment variable across all platforms. We suggest
+**   you interpret the return of a pointer to null-string to
+**   mean the same as a return of NULL from PR_GetEnv().
+** 
+**   A call to PR_SetEnv() where the parameter is of the form
+**   "name" will return PR_FAILURE; the environment remains
+**   unchanged. A call to PR_SetEnv() where the parameter is
+**   of the form "name=" may un-set the envrionment variable on
+**   some platforms; on others it may set the value of the
+**   environment variable to the null-string.
+** 
+**   For example, to test for NULL return or return of the
+**   null-string from PR_GetEnv(), use the following code
+**   fragment:
+** 
+**      char *val = PR_GetEnv("foo");
+**      if ((NULL == val) || ('\0' == *val)) { 
+**          ... interpret this as un-set ... 
+**      }
+** 
+**   The caller must ensure that the string passed
+**   to PR_SetEnv() is persistent. That is: The string should
+**   not be on the stack, where it can be overwritten
+**   on return from the function calling PR_SetEnv().
+**   Similarly, the string passed to PR_SetEnv() must not be
+**   overwritten by other actions of the process. ... Some
+**   platforms use the string by reference rather than copying
+**   it into the environment space. ... You have been warned!
+** 
+**   Use of platform-native functions that manipulate the
+**   environment (getenv(), putenv(), 
+**   SetEnvironmentVariable(), etc.) must not be used with
+**   NSPR's similar functions. The platform-native functions
+**   may not be thread safe and/or may operate on different
+**   conceptual environment space than that operated upon by
+**   NSPR's functions or other environment manipulating
+**   functions on the same platform. (!)
+** 
+*/
+NSPR_API(char*) PR_GetEnv(const char *var);
+
+/*
+** PR_SetEnv() -- set, unset or change an environment variable
+** 
+** Description:
+** PR_SetEnv() is modeled on the Unix putenv() function.
+** 
+** Inputs: 
+**   string -- pointer to a caller supplied
+**   constant, persistent string of the form name=value. Where
+**   name is the name of the environment variable to be set or
+**   changed; value is the value assigned to the variable.
+**
+** Returns: 
+**   PRStatus.
+** 
+** Restrictions: 
+**   See the Restrictions documented in the description of
+**   PR_GetEnv() in this header file.
+** 
+** 
+*/
+NSPR_API(PRStatus) PR_SetEnv(const char *string);
+
+PR_END_EXTERN_C
+
+#endif /* prenv_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prerr.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prerr.h
new file mode 100644
index 0000000..eba68f1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prerr.h
@@ -0,0 +1,281 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prerr_h___
+#define prerr_h___
+
+/*
+ *
+ * prerr.h
+ * This file is automatically generated; please do not edit it.
+ */
+
+/* Memory allocation attempt failed */
+#define PR_OUT_OF_MEMORY_ERROR                   (-6000L)
+
+/* Invalid file descriptor */
+#define PR_BAD_DESCRIPTOR_ERROR                  (-5999L)
+
+/* The operation would have blocked */
+#define PR_WOULD_BLOCK_ERROR                     (-5998L)
+
+/* Invalid memory address argument */
+#define PR_ACCESS_FAULT_ERROR                    (-5997L)
+
+/* Invalid function for file type */
+#define PR_INVALID_METHOD_ERROR                  (-5996L)
+
+/* Invalid memory address argument */
+#define PR_ILLEGAL_ACCESS_ERROR                  (-5995L)
+
+/* Some unknown error has occurred */
+#define PR_UNKNOWN_ERROR                         (-5994L)
+
+/* Operation interrupted by another thread */
+#define PR_PENDING_INTERRUPT_ERROR               (-5993L)
+
+/* function not implemented */
+#define PR_NOT_IMPLEMENTED_ERROR                 (-5992L)
+
+/* I/O function error */
+#define PR_IO_ERROR                              (-5991L)
+
+/* I/O operation timed out */
+#define PR_IO_TIMEOUT_ERROR                      (-5990L)
+
+/* I/O operation on busy file descriptor */
+#define PR_IO_PENDING_ERROR                      (-5989L)
+
+/* The directory could not be opened */
+#define PR_DIRECTORY_OPEN_ERROR                  (-5988L)
+
+/* Invalid function argument */
+#define PR_INVALID_ARGUMENT_ERROR                (-5987L)
+
+/* Network address not available (in use?) */
+#define PR_ADDRESS_NOT_AVAILABLE_ERROR           (-5986L)
+
+/* Network address type not supported */
+#define PR_ADDRESS_NOT_SUPPORTED_ERROR           (-5985L)
+
+/* Already connected */
+#define PR_IS_CONNECTED_ERROR                    (-5984L)
+
+/* Network address is invalid */
+#define PR_BAD_ADDRESS_ERROR                     (-5983L)
+
+/* Local Network address is in use */
+#define PR_ADDRESS_IN_USE_ERROR                  (-5982L)
+
+/* Connection refused by peer */
+#define PR_CONNECT_REFUSED_ERROR                 (-5981L)
+
+/* Network address is presently unreachable */
+#define PR_NETWORK_UNREACHABLE_ERROR             (-5980L)
+
+/* Connection attempt timed out */
+#define PR_CONNECT_TIMEOUT_ERROR                 (-5979L)
+
+/* Network file descriptor is not connected */
+#define PR_NOT_CONNECTED_ERROR                   (-5978L)
+
+/* Failure to load dynamic library */
+#define PR_LOAD_LIBRARY_ERROR                    (-5977L)
+
+/* Failure to unload dynamic library */
+#define PR_UNLOAD_LIBRARY_ERROR                  (-5976L)
+
+/* Symbol not found in any of the loaded dynamic libraries */
+#define PR_FIND_SYMBOL_ERROR                     (-5975L)
+
+/* Insufficient system resources */
+#define PR_INSUFFICIENT_RESOURCES_ERROR          (-5974L)
+
+/* A directory lookup on a network address has failed */
+#define PR_DIRECTORY_LOOKUP_ERROR                (-5973L)
+
+/* Attempt to access a TPD key that is out of range */
+#define PR_TPD_RANGE_ERROR                       (-5972L)
+
+/* Process open FD table is full */
+#define PR_PROC_DESC_TABLE_FULL_ERROR            (-5971L)
+
+/* System open FD table is full */
+#define PR_SYS_DESC_TABLE_FULL_ERROR             (-5970L)
+
+/* Network operation attempted on non-network file descriptor */
+#define PR_NOT_SOCKET_ERROR                      (-5969L)
+
+/* TCP-specific function attempted on a non-TCP file descriptor */
+#define PR_NOT_TCP_SOCKET_ERROR                  (-5968L)
+
+/* TCP file descriptor is already bound */
+#define PR_SOCKET_ADDRESS_IS_BOUND_ERROR         (-5967L)
+
+/* Access Denied */
+#define PR_NO_ACCESS_RIGHTS_ERROR                (-5966L)
+
+/* The requested operation is not supported by the platform */
+#define PR_OPERATION_NOT_SUPPORTED_ERROR         (-5965L)
+
+/* The host operating system does not support the protocol requested */
+#define PR_PROTOCOL_NOT_SUPPORTED_ERROR          (-5964L)
+
+/* Access to the remote file has been severed */
+#define PR_REMOTE_FILE_ERROR                     (-5963L)
+
+/* The value requested is too large to be stored in the data buffer provided */
+#define PR_BUFFER_OVERFLOW_ERROR                 (-5962L)
+
+/* TCP connection reset by peer */
+#define PR_CONNECT_RESET_ERROR                   (-5961L)
+
+/* Unused */
+#define PR_RANGE_ERROR                           (-5960L)
+
+/* The operation would have deadlocked */
+#define PR_DEADLOCK_ERROR                        (-5959L)
+
+/* The file is already locked */
+#define PR_FILE_IS_LOCKED_ERROR                  (-5958L)
+
+/* Write would result in file larger than the system allows */
+#define PR_FILE_TOO_BIG_ERROR                    (-5957L)
+
+/* The device for storing the file is full */
+#define PR_NO_DEVICE_SPACE_ERROR                 (-5956L)
+
+/* Unused */
+#define PR_PIPE_ERROR                            (-5955L)
+
+/* Unused */
+#define PR_NO_SEEK_DEVICE_ERROR                  (-5954L)
+
+/* Cannot perform a normal file operation on a directory */
+#define PR_IS_DIRECTORY_ERROR                    (-5953L)
+
+/* Symbolic link loop */
+#define PR_LOOP_ERROR                            (-5952L)
+
+/* File name is too long */
+#define PR_NAME_TOO_LONG_ERROR                   (-5951L)
+
+/* File not found */
+#define PR_FILE_NOT_FOUND_ERROR                  (-5950L)
+
+/* Cannot perform directory operation on a normal file */
+#define PR_NOT_DIRECTORY_ERROR                   (-5949L)
+
+/* Cannot write to a read-only file system */
+#define PR_READ_ONLY_FILESYSTEM_ERROR            (-5948L)
+
+/* Cannot delete a directory that is not empty */
+#define PR_DIRECTORY_NOT_EMPTY_ERROR             (-5947L)
+
+/* Cannot delete or rename a file object while the file system is busy */
+#define PR_FILESYSTEM_MOUNTED_ERROR              (-5946L)
+
+/* Cannot rename a file to a file system on another device */
+#define PR_NOT_SAME_DEVICE_ERROR                 (-5945L)
+
+/* The directory object in the file system is corrupted */
+#define PR_DIRECTORY_CORRUPTED_ERROR             (-5944L)
+
+/* Cannot create or rename a filename that already exists */
+#define PR_FILE_EXISTS_ERROR                     (-5943L)
+
+/* Directory is full.  No additional filenames may be added */
+#define PR_MAX_DIRECTORY_ENTRIES_ERROR           (-5942L)
+
+/* The required device was in an invalid state */
+#define PR_INVALID_DEVICE_STATE_ERROR            (-5941L)
+
+/* The device is locked */
+#define PR_DEVICE_IS_LOCKED_ERROR                (-5940L)
+
+/* No more entries in the directory */
+#define PR_NO_MORE_FILES_ERROR                   (-5939L)
+
+/* Encountered end of file */
+#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)
+
+/* 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 */
+#define PR_GROUP_EMPTY_ERROR                     (-5932L)
+
+/* Object state improper for request */
+#define PR_INVALID_STATE_ERROR                   (-5931L)
+
+/* Network is down */
+#define PR_NETWORK_DOWN_ERROR                    (-5930L)
+
+/* Socket shutdown */
+#define PR_SOCKET_SHUTDOWN_ERROR                 (-5929L)
+
+/* Connection aborted */
+#define PR_CONNECT_ABORTED_ERROR                 (-5928L)
+
+/* Host is unreachable */
+#define PR_HOST_UNREACHABLE_ERROR                (-5927L)
+
+/* The library is not loaded */
+#define PR_LIBRARY_NOT_LOADED_ERROR              (-5926L)
+
+/* The one-time function was previously called and failed. Its error code is no longer available */
+#define PR_CALL_ONCE_ERROR                       (-5925L)
+
+/* Placeholder for the end of the list */
+#define PR_MAX_ERROR                             (-5924L)
+
+extern void nspr_InitializePRErrorTable(void);
+#define ERROR_TABLE_BASE_nspr (-6000L)
+
+#endif /* prerr_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prerror.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prerror.h
new file mode 100644
index 0000000..cf94872
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prerror.h
@@ -0,0 +1,326 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prerror_h___
+#define prerror_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef PRInt32 PRErrorCode;
+
+#define PR_NSPR_ERROR_BASE -6000
+
+#include "prerr.h"
+
+/*
+** Set error will preserve an error condition within a thread context.
+** The values stored are the NSPR (platform independent) translation of
+** the error. Also, if available, the platform specific oserror is stored.
+** If there is no appropriate OS error number, a zero my be supplied.
+*/
+NSPR_API(void) PR_SetError(PRErrorCode errorCode, PRInt32 oserr);
+
+/*
+** The text value specified may be NULL. If it is not NULL and the text length
+** is zero, the string is assumed to be a null terminated C string. Otherwise
+** the text is assumed to be the length specified and possibly include NULL
+** characters (e.g., a multi-national string).
+**
+** The text will be copied into to thread structure and remain there
+** until the next call to PR_SetError.
+*/
+NSPR_API(void) PR_SetErrorText(
+    PRIntn textLength, const char *text);
+
+/*
+** Return the current threads last set error code.
+*/
+NSPR_API(PRErrorCode) PR_GetError(void);
+
+/*
+** Return the current threads last set os error code. This is used for
+** machine specific code that desires the underlying os error.
+*/
+NSPR_API(PRInt32) PR_GetOSError(void);
+
+/*
+** Get the length of the error text. If a zero is returned, then there
+** is no text. Otherwise, the value returned is sufficient to contain
+** the error text currently available.
+*/
+NSPR_API(PRInt32) PR_GetErrorTextLength(void);
+
+/*
+** Copy the current threads current error text. Then actual number of bytes
+** copied is returned as the result. If the result is zero, the 'text' area
+** is unaffected.
+*/
+NSPR_API(PRInt32) PR_GetErrorText(char *text);
+
+
+/*
+Copyright (C) 1987, 1988 Student Information Processing Board of the
+Massachusetts Institute of Technology.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.  M.I.T. and the M.I.T. S.I.P.B.
+make no representations about the suitability of this software for any
+purpose.  It is provided "as is" without express or implied warranty.
+*/
+
+
+/*
+ * NOTE:
+ *		The interfaces for error-code-translation described in the rest of
+ *		this file are preliminary in the 3.1 release of nspr and are subject 
+ *		to change in future releases.
+ */
+
+/*
+** Description:	Localizable error code to string function.
+**
+**
+** NSPR provides a mechanism for converting an error code to a
+** descriptive string, in a caller-specified language.
+**
+** Error codes themselves are 32 bit (signed) integers.  Typically,
+** the high order 24 bits are an identifier of which error table the
+** error code is from, and the low order 8 bits are a sequential error
+** number within the table.  NSPR supports error tables whose first
+** error code is not a multiple of 256, such error code assignments
+** should be avoided when possible.
+**
+** Error table 0 is defined to match the UNIX system call error table
+** (sys_errlist); this allows errno values to be used directly in the
+** library.  Other error table numbers are typically formed by
+** compacting together the first four characters of the error table
+** name.  The mapping between characters in the name and numeric
+** values in the error code are defined in a system-independent
+** fashion, so that two systems that can pass integral values between
+** them can reliably pass error codes without loss of meaning; this
+** should work even if the character sets used are not the
+** same. (However, if this is to be done, error table 0 should be
+** avoided, since the local system call error tables may differ.)
+**
+** Libraries defining error codes need only provide a table mapping
+** error code numbers to names and default English descriptions,
+** calling a routine to install the table, making it ``known'' to NSPR
+** library.  Once installed, a table may not be removed.  Any error
+** code the library generates can be converted to the corresponding
+** error message.  There is also a default format for error codes
+** accidentally returned before making the table known, which is of
+** the form "unknown code foo 32", where "foo" would be the name of
+** the table.
+**
+** Normally, the error code conversion routine only supports the
+** languages "i-default" and "en", returning the error-table-provided
+** English description for both languages.  The application may
+** provide a localization plugin, allowing support for additional
+** languages.
+**
+**/
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+/*
+ * PRLanguageCode --
+ *
+ *    NSPR represents a language code as a non-negative integer.
+ *    Languages 0 is always "i-default" the language you get without
+ *    explicit negotiation.  Language 1 is always "en", English
+ *    which has been explicitly negotiated.  Additional language
+ *    codes are defined by an application-provided localization plugin.
+ */
+typedef PRUint32 PRLanguageCode;
+#define PR_LANGUAGE_I_DEFAULT 0 /* i-default, the default language */
+#define PR_LANGUAGE_EN 1 /* English, explicitly negotiated */
+
+/*
+ * struct PRErrorMessage --
+ *
+ *    An error message in an error table.
+ */
+struct PRErrorMessage {
+    const char * name;    /* Macro name for error */
+    const char * en_text; /* Default English text */
+};
+
+/*
+ * struct PRErrorTable --
+ *
+ *    An error table, provided by a library.
+ */
+struct PRErrorTable {
+    const struct PRErrorMessage * msgs; /* Array of error information */
+    const char *name; /* Name of error table source */
+    PRErrorCode base; /* Error code for first error in table */
+    int n_msgs; /* Number of codes in table */
+};
+
+/*
+ * struct PRErrorCallbackPrivate --
+ *
+ *    A private structure for the localization plugin 
+ */
+struct PRErrorCallbackPrivate;
+
+/*
+ * struct PRErrorCallbackTablePrivate --
+ *
+ *    A data structure under which the localization plugin may store information,
+ *    associated with an error table, that is private to itself.
+ */
+struct PRErrorCallbackTablePrivate;
+
+/*
+ * PRErrorCallbackLookupFn --
+ *
+ *    A function of PRErrorCallbackLookupFn type is a localization
+ *    plugin callback which converts an error code into a description
+ *    in the requested language.  The callback is provided the
+ *    appropriate error table, private data for the plugin and the table.
+ *    The callback returns the appropriate UTF-8 encoded description, or NULL
+ *    if no description can be found.
+ */
+typedef const char *
+PRErrorCallbackLookupFn(PRErrorCode code, PRLanguageCode language, 
+		   const struct PRErrorTable *table,
+		   struct PRErrorCallbackPrivate *cb_private,
+		   struct PRErrorCallbackTablePrivate *table_private);
+
+/*
+ * PRErrorCallbackNewTableFn --
+ *
+ *    A function PRErrorCallbackNewTableFn type is a localization plugin
+ *    callback which is called once with each error table registered
+ *    with NSPR.  The callback is provided with the error table and
+ *    the plugin's private structure.  The callback returns any table private
+ *    data it wishes to associate with the error table.  Does not need to be thread
+ *    safe.
+ */
+typedef struct PRErrorCallbackTablePrivate *
+PRErrorCallbackNewTableFn(const struct PRErrorTable *table,
+			struct PRErrorCallbackPrivate *cb_private);
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorToString
+** DESCRIPTION:
+**  Returns the UTF-8 message for an error code in
+**  the requested language.  May return the message
+**  in the default language if a translation in the requested
+**  language is not available.  The returned string is
+**  valid for the duration of the process.  Never returns NULL.
+**
+***********************************************************************/
+NSPR_API(const char *) PR_ErrorToString(PRErrorCode code,
+    PRLanguageCode language);
+
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorToName
+** DESCRIPTION:
+**  Returns the macro name for an error code, or NULL
+**  if the error code is not known.  The returned string is
+**  valid for the duration of the process.
+**
+**  Does not work for error table 0, the system error codes.
+**
+***********************************************************************/
+NSPR_API(const char *) PR_ErrorToName(PRErrorCode code);
+
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorLanguages
+** DESCRIPTION:
+**  Returns the RFC 1766 language tags for the language
+**  codes PR_ErrorToString() supports.  The returned array is valid
+**  for the duration of the process.  Never returns NULL.  The first
+**  item in the returned array is the language tag for PRLanguageCode 0,
+**  the second is for PRLanguageCode 1, and so on.  The array is terminated
+**  with a null pointer.
+**
+***********************************************************************/
+NSPR_API(const char * const *) PR_ErrorLanguages(void);
+
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorInstallTable
+** DESCRIPTION:
+**  Registers an error table with NSPR.  Must be done exactly once per
+**  table.  Memory pointed to by `table' must remain valid for the life
+**  of the process.
+**
+**  NOT THREAD SAFE!
+**  
+***********************************************************************/
+NSPR_API(PRErrorCode) PR_ErrorInstallTable(const struct PRErrorTable *table);
+
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorInstallCallback
+** DESCRIPTION:
+**  Registers an error localization plugin with NSPR.  May be called
+**  at most one time.  `languages' contains the language codes supported
+**  by this plugin.  Languages 0 and 1 must be "i-default" and "en"
+**  respectively.  `lookup' and `newtable' contain pointers to
+**  the plugin callback functions.  `cb_private' contains any information
+**  private to the plugin functions.
+**
+**  NOT THREAD SAFE!
+**
+***********************************************************************/
+NSPR_API(void) PR_ErrorInstallCallback(const char * const * languages,
+			      PRErrorCallbackLookupFn *lookup, 
+			      PRErrorCallbackNewTableFn *newtable,
+			      struct PRErrorCallbackPrivate *cb_private);
+
+PR_END_EXTERN_C
+
+#endif /* prerror_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prinet.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prinet.h
new file mode 100644
index 0000000..7c3f4bd
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prinet.h
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:		prinet.h
+ * Description:
+ *     Header file used to find the system header files for socket support[1].
+ *     This file serves the following purposes:
+ *     - A cross-platform, "get-everything" socket header file.  On
+ *       Unix, socket support is scattered in several header files,
+ *       while Windows has a "get-everything" socket header file[2].
+ *     - NSPR needs the following macro definitions and function
+ *       prototype declarations from these header files:
+ *           AF_INET
+ *           INADDR_ANY, INADDR_LOOPBACK, INADDR_BROADCAST
+ *           ntohl(), ntohs(), htonl(), ntons().
+ *       NSPR does not define its own versions of these macros and
+ *       functions.  It simply uses the native versions, which have
+ *       the same names on all supported platforms.
+ *     This file is intended to be included by NSPR public header
+ *     files, such as prio.h.  One should not include this file directly.
+ *
+ * Notes:
+ *     1. This file should have been an internal header.  Please do not
+ *        depend on it to pull in the system header files you need.
+ *     2. WARNING: This file is no longer cross-platform as it is a no-op
+ *        for WIN32!  See the comment in the WIN32 section for details.
+ */
+
+#ifndef prinet_h__
+#define prinet_h__
+
+#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+#include <sys/types.h>
+#include <sys/socket.h>		/* AF_INET */
+#include <netinet/in.h>         /* INADDR_ANY, ..., ntohl(), ... */
+#ifdef XP_OS2
+#include <sys/ioctl.h>
+#endif
+#ifdef XP_UNIX
+#ifdef AIX
+/*
+ * On AIX 4.3, the header <arpa/inet.h> refers to struct
+ * ether_addr and struct sockaddr_dl that are not declared.
+ * The following struct declarations eliminate the compiler
+ * warnings.
+ */
+struct ether_addr;
+struct sockaddr_dl;
+#endif /* AIX */
+#include <arpa/inet.h>
+#endif /* XP_UNIX */
+#include <netdb.h>
+
+#if defined(FREEBSD) || defined(BSDI) || defined(QNX)
+#include <rpc/types.h> /* the only place that defines INADDR_LOOPBACK */
+#endif
+
+/*
+ * OS/2 hack.  For some reason INADDR_LOOPBACK is not defined in the
+ * socket headers.
+ */
+#if defined(OS2) && !defined(INADDR_LOOPBACK)
+#define INADDR_LOOPBACK 0x7f000001
+#endif
+
+/*
+ * Prototypes of ntohl() etc. are declared in <machine/endian.h>
+ * on these platforms.
+ */
+#if defined(BSDI) || defined(OSF1)
+#include <machine/endian.h>
+#endif
+
+#elif defined(WIN32)
+
+/*
+ * Do not include any system header files.
+ *
+ * Originally we were including <windows.h>.  It slowed down the
+ * compilation of files that included NSPR headers, so we removed
+ * the <windows.h> inclusion at customer's request, which created
+ * an unfortunate inconsistency with other platforms.
+ */
+
+#else
+
+#error Unknown platform
+
+#endif
+
+#endif /* prinet_h__ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prinit.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prinit.h
new file mode 100644
index 0000000..38f4ffe
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prinit.h
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prinit_h___
+#define prinit_h___
+
+#include "prthread.h"
+#include "prtypes.h"
+#include "prwin16.h"
+#include <stdio.h>
+
+PR_BEGIN_EXTERN_C
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+
+/*
+** NSPR's name, this should persist until at least the turn of the
+** century.
+*/
+#define PR_NAME     "NSPR"
+
+/*
+** 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>[.<patch level>] [<Beta>]"
+*/
+#define PR_VERSION  "4.8.6"
+#define PR_VMAJOR   4
+#define PR_VMINOR   8
+#define PR_VPATCH   6
+#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
+** that the underling library will perform as the caller expects.
+**
+** The only argument is a string, which should be the verson identifier
+** of the library in question. That string will be compared against an
+** equivalent string that represents the actual build version of the
+** exporting library.
+**
+** The result will be the logical union of the directly called library
+** and all dependent libraries.
+*/
+
+typedef PRBool (*PRVersionCheck)(const char*);
+
+/*
+** PR_VersionCheck
+**
+** NSPR's existance proof of the version check function.
+**
+** Note that NSPR has no cooperating dependencies.
+*/
+
+NSPR_API(PRBool) PR_VersionCheck(const char *importedVersion);
+
+
+/************************************************************************/
+/*******************************INITIALIZATION***************************/
+/************************************************************************/
+
+/*
+** Initialize the runtime. Attach a thread object to the currently
+** executing native thread of type "type".
+**
+** The specificaiton of 'maxPTDs' is ignored.
+*/
+NSPR_API(void) PR_Init(
+    PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs);
+
+/*
+** And alternate form of initialization, one that may become the default if
+** not the only mechanism, provides a method to get the NSPR runtime init-
+** ialized and place NSPR between the caller and the runtime library. This
+** allows main() to be treated as any other thread root function, signalling
+** its compeletion by returning and allowing the runtime to coordinate the
+** completion of the other threads of the runtime.
+**
+** The priority of the main (or primordial) thread will be PR_PRIORITY_NORMAL.
+** The thread may adjust its own priority by using PR_SetPriority(), though
+** at this time the support for priorities is somewhat weak.
+**
+** The specificaiton of 'maxPTDs' is ignored.
+**
+** The value returned by PR_Initialize is the value returned from the root
+** function, 'prmain'.
+*/
+
+typedef PRIntn (PR_CALLBACK *PRPrimordialFn)(PRIntn argc, char **argv);
+
+NSPR_API(PRIntn) PR_Initialize(
+    PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs);
+
+/*
+** Return PR_TRUE if PR_Init has already been called.
+*/
+NSPR_API(PRBool) PR_Initialized(void);
+
+/*
+ * Perform a graceful shutdown of NSPR.  PR_Cleanup() may be called by
+ * the primordial thread near the end of the main() function.
+ *
+ * PR_Cleanup() attempts to synchronize the natural termination of
+ * process.  It does that by blocking the caller, if and only if it is
+ * the primordial thread, until the number of user threads has dropped
+ * to zero.  When the primordial thread returns from main(), the process
+ * will immediately and silently exit.  That is, it will (if necessary)
+ * forcibly terminate any existing threads and exit without significant
+ * blocking and there will be no error messages or core files.
+ *
+ * PR_Cleanup() returns PR_SUCCESS if NSPR is successfully shutdown,
+ * or PR_FAILURE if the calling thread of this function is not the
+ * primordial thread.
+ */
+NSPR_API(PRStatus) PR_Cleanup(void);
+
+/*
+** Disable Interrupts
+**		Disables timer signals used for pre-emptive scheduling.
+*/
+NSPR_API(void) PR_DisableClockInterrupts(void);
+
+/*
+** Enables Interrupts
+**		Enables timer signals used for pre-emptive scheduling.
+*/
+NSPR_API(void) PR_EnableClockInterrupts(void);
+
+/*
+** Block Interrupts
+**		Blocks the timer signal used for pre-emptive scheduling
+*/
+NSPR_API(void) PR_BlockClockInterrupts(void);
+
+/*
+** Unblock Interrupts
+**		Unblocks the timer signal used for pre-emptive scheduling
+*/
+NSPR_API(void) PR_UnblockClockInterrupts(void);
+
+/*
+** Create extra virtual processor threads. Generally used with MP systems.
+*/
+NSPR_API(void) PR_SetConcurrency(PRUintn numCPUs);
+
+/*
+** Control the method and size of the file descriptor (PRFileDesc*)
+** cache used by the runtime. Setting 'high' to zero is for performance,
+** any other value probably for debugging (see memo on FD caching).
+*/
+NSPR_API(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high);
+
+/*
+ * Cause an immediate, nongraceful, forced termination of the process.
+ * It takes a PRIntn argument, which is the exit status code of the
+ * process.
+ */
+NSPR_API(void) PR_ProcessExit(PRIntn status);
+
+/*
+** Abort the process in a non-graceful manner. This will cause a core file,
+** call to the debugger or other moral equivalent as well as causing the
+** entire process to stop.
+*/
+NSPR_API(void) PR_Abort(void);
+
+/*
+ ****************************************************************
+ *
+ * Module initialization:
+ *
+ ****************************************************************
+ */
+
+typedef struct PRCallOnceType {
+    PRIntn initialized;
+    PRInt32 inProgress;
+    PRStatus status;
+} PRCallOnceType;
+
+typedef PRStatus (PR_CALLBACK *PRCallOnceFN)(void);
+
+typedef PRStatus (PR_CALLBACK *PRCallOnceWithArgFN)(void *arg);
+
+NSPR_API(PRStatus) PR_CallOnce(
+    PRCallOnceType *once,
+    PRCallOnceFN    func
+);
+
+NSPR_API(PRStatus) PR_CallOnceWithArg(
+    PRCallOnceType      *once,
+    PRCallOnceWithArgFN  func,
+    void                *arg
+);
+
+
+PR_END_EXTERN_C
+
+#endif /* prinit_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prinrval.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prinrval.h
new file mode 100644
index 0000000..67d2f42
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prinrval.h
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:		prinrval.h
+** Description:	API to interval timing functions of NSPR.
+**
+**
+** NSPR provides interval times that are independent of network time
+** of day values. Interval times are (in theory) accurate regardless
+** of host processing requirements and also very cheap to acquire. It
+** is expected that getting an interval time while in a synchronized
+** function (holding one's lock).
+**/
+
+#if !defined(prinrval_h)
+#define prinrval_h
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+typedef PRUint32 PRIntervalTime;
+
+/***********************************************************************
+** DEFINES:     PR_INTERVAL_MIN
+**              PR_INTERVAL_MAX
+** DESCRIPTION:
+**  These two constants define the range (in ticks / second) of the
+**  platform dependent type, PRIntervalTime. These constants bound both
+**  the period and the resolution of a PRIntervalTime. 
+***********************************************************************/
+#define PR_INTERVAL_MIN 1000UL
+#define PR_INTERVAL_MAX 100000UL
+
+/***********************************************************************
+** DEFINES:     PR_INTERVAL_NO_WAIT
+**              PR_INTERVAL_NO_TIMEOUT
+** DESCRIPTION:
+**  Two reserved constants are defined in the PRIntervalTime namespace.
+**  They are used to indicate that the process should wait no time (return
+**  immediately) or wait forever (never time out), respectively.
+**  Note: PR_INTERVAL_NO_TIMEOUT passed as input to PR_Connect is 
+**  interpreted as use the OS's connect timeout.
+**  
+***********************************************************************/
+#define PR_INTERVAL_NO_WAIT 0UL
+#define PR_INTERVAL_NO_TIMEOUT 0xffffffffUL
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/***********************************************************************
+** FUNCTION:    PR_IntervalNow
+** DESCRIPTION:
+**  Return the value of NSPR's free running interval timer. That timer
+**  can be used to establish epochs and determine intervals (be computing
+**  the difference between two times).
+** INPUTS:      void
+** OUTPUTS:     void
+** RETURN:      PRIntervalTime
+**  
+** SIDE EFFECTS:
+**  None
+** RESTRICTIONS:
+**  The units of PRIntervalTime are platform dependent. They are chosen
+**  such that they are appropriate for the host OS, yet provide sufficient
+**  resolution and period to be useful to clients. 
+** MEMORY:      N/A
+** ALGORITHM:   Platform dependent
+***********************************************************************/
+NSPR_API(PRIntervalTime) PR_IntervalNow(void);
+
+/***********************************************************************
+** FUNCTION:    PR_TicksPerSecond
+** DESCRIPTION:
+**  Return the number of ticks per second for PR_IntervalNow's clock.
+**  The value will be in the range [PR_INTERVAL_MIN..PR_INTERVAL_MAX].
+** INPUTS:      void
+** OUTPUTS:     void
+** RETURN:      PRUint32
+**  
+** SIDE EFFECTS:
+**  None
+** RESTRICTIONS:
+**  None
+** MEMORY:      N/A
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRUint32) PR_TicksPerSecond(void);
+
+/***********************************************************************
+** FUNCTION:    PR_SecondsToInterval
+**              PR_MillisecondsToInterval
+**              PR_MicrosecondsToInterval
+** DESCRIPTION:
+**  Convert standard clock units to platform dependent intervals.
+** INPUTS:      PRUint32
+** OUTPUTS:     void
+** RETURN:      PRIntervalTime
+**  
+** SIDE EFFECTS:
+**  None
+** RESTRICTIONS:
+**  Conversion may cause overflow, which is not reported.
+** MEMORY:      N/A
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds);
+NSPR_API(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli);
+NSPR_API(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro);
+
+/***********************************************************************
+** FUNCTION:    PR_IntervalToSeconds
+**              PR_IntervalToMilliseconds
+**              PR_IntervalToMicroseconds
+** DESCRIPTION:
+**  Convert platform dependent intervals to standard clock units.
+** INPUTS:      PRIntervalTime
+** OUTPUTS:     void
+** RETURN:      PRUint32
+**  
+** SIDE EFFECTS:
+**  None
+** RESTRICTIONS:
+**  Conversion may cause overflow, which is not reported.
+** MEMORY:      N/A
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks);
+NSPR_API(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks);
+NSPR_API(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks);
+
+PR_END_EXTERN_C
+
+
+#endif /* !defined(prinrval_h) */
+
+/* prinrval.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prio.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prio.h
new file mode 100644
index 0000000..7ec3045
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prio.h
@@ -0,0 +1,2034 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:     prio.h
+ *
+ * Description:    PR i/o related stuff, such as file system access, file
+ *         i/o, socket i/o, etc.
+ */
+
+#ifndef prio_h___
+#define prio_h___
+
+#include "prlong.h"
+#include "prtime.h"
+#include "prinrval.h"
+#include "prinet.h"
+
+PR_BEGIN_EXTERN_C
+
+/* Typedefs */
+typedef struct PRDir            PRDir;
+typedef struct PRDirEntry       PRDirEntry;
+#ifdef MOZ_UNICODE
+typedef struct PRDirUTF16       PRDirUTF16;
+typedef struct PRDirEntryUTF16  PRDirEntryUTF16;
+#endif /* MOZ_UNICODE */
+typedef struct PRFileDesc       PRFileDesc;
+typedef struct PRFileInfo       PRFileInfo;
+typedef struct PRFileInfo64     PRFileInfo64;
+typedef union  PRNetAddr        PRNetAddr;
+typedef struct PRIOMethods      PRIOMethods;
+typedef struct PRPollDesc       PRPollDesc;
+typedef struct PRFilePrivate    PRFilePrivate;
+typedef struct PRSendFileData   PRSendFileData;
+
+/*
+***************************************************************************
+** The file descriptor.
+** This is the primary structure to represent any active open socket,
+** whether it be a normal file or a network connection. Such objects
+** are stackable (or layerable). Each layer may have its own set of
+** method pointers and context private to that layer. All each layer
+** knows about its neighbors is how to get to their method table.
+***************************************************************************
+*/
+
+typedef PRIntn PRDescIdentity;          /* see: Layering file descriptors */
+
+struct PRFileDesc {
+    const PRIOMethods *methods;         /* the I/O methods table */
+    PRFilePrivate *secret;              /* layer dependent data */
+    PRFileDesc *lower, *higher;         /* pointers to adjacent layers */
+    void (PR_CALLBACK *dtor)(PRFileDesc *fd);
+                                        /* A destructor function for layer */
+    PRDescIdentity identity;            /* Identity of this particular layer  */
+};
+
+/*
+***************************************************************************
+** PRTransmitFileFlags
+**
+** Flags for PR_TransmitFile.  Pass PR_TRANSMITFILE_CLOSE_SOCKET to
+** PR_TransmitFile if the connection should be closed after the file
+** is transmitted.
+***************************************************************************
+*/
+typedef enum PRTransmitFileFlags {
+    PR_TRANSMITFILE_KEEP_OPEN = 0,    /* socket is left open after file
+                                       * is transmitted. */
+    PR_TRANSMITFILE_CLOSE_SOCKET = 1  /* socket is closed after file
+                                       * is transmitted. */
+} PRTransmitFileFlags;
+
+/*
+**************************************************************************
+** Macros for PRNetAddr
+**
+** Address families: PR_AF_INET, PR_AF_INET6, PR_AF_LOCAL
+** IP addresses: PR_INADDR_ANY, PR_INADDR_LOOPBACK, PR_INADDR_BROADCAST
+**************************************************************************
+*/
+
+#ifdef WIN32
+
+#define PR_AF_INET 2
+#define PR_AF_LOCAL 1
+#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
+#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
+
+#ifndef PR_AF_UNSPEC
+#define PR_AF_UNSPEC 0
+#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).
+**************************************************************************
+*************************************************************************/
+
+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_u64
+
+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 */
+#endif
+    } raw;
+    struct {
+        PRUint16 family;                /* address family (AF_INET) */
+        PRUint16 port;                  /* port number */
+        PRUint32 ip;                    /* The actual 32 bits of address */
+#ifdef XP_BEOS
+        char pad[4];                    /* Be has a smaller structure */
+#else
+        char pad[8];
+#endif
+    } inet;
+    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;
+#if defined(XP_UNIX) || defined(XP_OS2)
+    struct {                            /* Unix domain socket address */
+        PRUint16 family;                /* address family (AF_UNIX) */
+#ifdef XP_OS2
+        char path[108];                 /* null-terminated pathname */
+                                        /* bind fails if size is not 108. */
+#else
+        char path[104];                 /* null-terminated pathname */
+#endif
+    } local;
+#endif
+};
+
+/*
+***************************************************************************
+** PRSockOption
+**
+** The file descriptors can have predefined options set after they file
+** descriptor is created to change their behavior. Only the options in
+** the following enumeration are supported.
+***************************************************************************
+*/
+typedef enum PRSockOption
+{
+    PR_SockOpt_Nonblocking,     /* nonblocking io */
+    PR_SockOpt_Linger,          /* linger on close if data present */
+    PR_SockOpt_Reuseaddr,       /* allow local address reuse */
+    PR_SockOpt_Keepalive,       /* keep connections alive */
+    PR_SockOpt_RecvBufferSize,  /* send buffer size */
+    PR_SockOpt_SendBufferSize,  /* receive buffer size */
+
+    PR_SockOpt_IpTimeToLive,    /* time to live */
+    PR_SockOpt_IpTypeOfService, /* type of service and precedence */
+
+    PR_SockOpt_AddMember,       /* add an IP group membership */
+    PR_SockOpt_DropMember,      /* drop an IP group membership */
+    PR_SockOpt_McastInterface,  /* multicast interface address */
+    PR_SockOpt_McastTimeToLive, /* multicast timetolive */
+    PR_SockOpt_McastLoopback,   /* multicast loopback */
+
+    PR_SockOpt_NoDelay,         /* don't delay send to coalesce packets */
+    PR_SockOpt_MaxSegment,      /* maximum segment size */
+    PR_SockOpt_Broadcast,       /* enable broadcast */
+    PR_SockOpt_Last
+} PRSockOption;
+
+typedef struct PRLinger {
+	PRBool polarity;		    /* Polarity of the option's setting */
+	PRIntervalTime linger;	    /* Time to linger before closing */
+} PRLinger;
+
+typedef struct PRMcastRequest {
+	PRNetAddr mcaddr;			/* IP multicast address of group */
+	PRNetAddr ifaddr;			/* local IP address of interface */
+} PRMcastRequest;
+
+typedef struct PRSocketOptionData
+{
+    PRSockOption option;
+    union
+    {
+        PRUintn ip_ttl;             /* IP time to live */
+        PRUintn mcast_ttl;          /* IP multicast time to live */
+        PRUintn tos;                /* IP type of service and precedence */
+        PRBool non_blocking;        /* Non-blocking (network) I/O */
+        PRBool reuse_addr;          /* Allow local address reuse */
+        PRBool keep_alive;          /* Keep connections alive */
+        PRBool mcast_loopback;      /* IP multicast loopback */
+        PRBool no_delay;            /* Don't delay send to coalesce packets */
+        PRBool broadcast;           /* Enable broadcast */
+        PRSize max_segment;         /* Maximum segment size */
+        PRSize recv_buffer_size;    /* Receive buffer size */
+        PRSize send_buffer_size;    /* Send buffer size */
+        PRLinger linger;            /* Time to linger on close if data present */
+        PRMcastRequest add_member;  /* add an IP group membership */
+        PRMcastRequest drop_member; /* Drop an IP group membership */
+        PRNetAddr mcast_if;         /* multicast interface address */
+    } value;
+} PRSocketOptionData;
+
+/*
+***************************************************************************
+** PRIOVec
+**
+** The I/O vector is used by the write vector method to describe the areas
+** that are affected by the ouput operation.
+***************************************************************************
+*/
+typedef struct PRIOVec {
+    char *iov_base;
+    int iov_len;
+} PRIOVec;
+
+/*
+***************************************************************************
+** Discover what type of socket is being described by the file descriptor.
+***************************************************************************
+*/
+typedef enum PRDescType
+{
+    PR_DESC_FILE = 1,
+    PR_DESC_SOCKET_TCP = 2,
+    PR_DESC_SOCKET_UDP = 3,
+    PR_DESC_LAYERED = 4,
+    PR_DESC_PIPE = 5
+} PRDescType;
+
+typedef enum PRSeekWhence {
+    PR_SEEK_SET = 0,
+    PR_SEEK_CUR = 1,
+    PR_SEEK_END = 2
+} PRSeekWhence;
+
+NSPR_API(PRDescType) PR_GetDescType(PRFileDesc *file);
+
+/*
+***************************************************************************
+** PRIOMethods
+**
+** The I/O methods table provides procedural access to the functions of
+** the file descriptor. It is the responsibility of a layer implementor
+** to provide suitable functions at every entry point. If a layer provides
+** no functionality, it should call the next lower(higher) function of the
+** same name (e.g., return fd->lower->method->close(fd->lower));
+**
+** Not all functions are implemented for all types of files. In cases where
+** that is true, the function will return a error indication with an error
+** code of PR_INVALID_METHOD_ERROR.
+***************************************************************************
+*/
+
+typedef PRStatus (PR_CALLBACK *PRCloseFN)(PRFileDesc *fd);
+typedef PRInt32 (PR_CALLBACK *PRReadFN)(PRFileDesc *fd, void *buf, PRInt32 amount);
+typedef PRInt32 (PR_CALLBACK *PRWriteFN)(PRFileDesc *fd, const void *buf, PRInt32 amount);
+typedef PRInt32 (PR_CALLBACK *PRAvailableFN)(PRFileDesc *fd);
+typedef PRInt64 (PR_CALLBACK *PRAvailable64FN)(PRFileDesc *fd);
+typedef PRStatus (PR_CALLBACK *PRFsyncFN)(PRFileDesc *fd);
+typedef PROffset32 (PR_CALLBACK *PRSeekFN)(PRFileDesc *fd, PROffset32 offset, PRSeekWhence how);
+typedef PROffset64 (PR_CALLBACK *PRSeek64FN)(PRFileDesc *fd, PROffset64 offset, PRSeekWhence how);
+typedef PRStatus (PR_CALLBACK *PRFileInfoFN)(PRFileDesc *fd, PRFileInfo *info);
+typedef PRStatus (PR_CALLBACK *PRFileInfo64FN)(PRFileDesc *fd, PRFileInfo64 *info);
+typedef PRInt32 (PR_CALLBACK *PRWritevFN)(
+    PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
+    PRIntervalTime timeout);
+typedef PRStatus (PR_CALLBACK *PRConnectFN)(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout);
+typedef PRFileDesc* (PR_CALLBACK *PRAcceptFN) (
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout);
+typedef PRStatus (PR_CALLBACK *PRBindFN)(PRFileDesc *fd, const PRNetAddr *addr);
+typedef PRStatus (PR_CALLBACK *PRListenFN)(PRFileDesc *fd, PRIntn backlog);
+typedef PRStatus (PR_CALLBACK *PRShutdownFN)(PRFileDesc *fd, PRIntn how);
+typedef PRInt32 (PR_CALLBACK *PRRecvFN)(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout);
+typedef PRInt32 (PR_CALLBACK *PRSendFN) (
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout);
+typedef PRInt32 (PR_CALLBACK *PRRecvfromFN)(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout);
+typedef PRInt32 (PR_CALLBACK *PRSendtoFN)(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout);
+typedef PRInt16 (PR_CALLBACK *PRPollFN)(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
+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 *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 PRStatus (PR_CALLBACK *PRConnectcontinueFN)(
+    PRFileDesc *fd, PRInt16 out_flags);
+typedef PRIntn (PR_CALLBACK *PRReservedFN)(PRFileDesc *fd);
+
+struct PRIOMethods {
+    PRDescType file_type;           /* Type of file represented (tos)           */
+    PRCloseFN close;                /* close file and destroy descriptor        */
+    PRReadFN read;                  /* read up to specified bytes into buffer   */
+    PRWriteFN write;                /* write specified bytes from buffer        */
+    PRAvailableFN available;        /* determine number of bytes available      */
+    PRAvailable64FN available64;    /*          ditto, 64 bit                   */
+    PRFsyncFN fsync;                /* flush all buffers to permanent store     */
+    PRSeekFN seek;                  /* position the file to the desired place   */
+    PRSeek64FN seek64;              /*           ditto, 64 bit                  */
+    PRFileInfoFN fileInfo;          /* Get information about an open file       */
+    PRFileInfo64FN fileInfo64;      /*           ditto, 64 bit                  */
+    PRWritevFN writev;              /* Write segments as described by iovector  */
+    PRConnectFN connect;            /* Connect to the specified (net) address   */
+    PRAcceptFN accept;              /* Accept a connection for a (net) peer     */
+    PRBindFN bind;                  /* Associate a (net) address with the fd    */
+    PRListenFN listen;              /* Prepare to listen for (net) connections  */
+    PRShutdownFN shutdown;          /* Shutdown a (net) connection              */
+    PRRecvFN recv;                  /* Solicit up the the specified bytes       */
+    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                 */
+    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*/
+    PRConnectcontinueFN connectcontinue;
+                                    /* Continue a nonblocking connect */
+    PRReservedFN reserved_fn_3;		/* reserved for future use */
+    PRReservedFN reserved_fn_2;		/* reserved for future use */
+    PRReservedFN reserved_fn_1;		/* reserved for future use */
+    PRReservedFN reserved_fn_0;		/* reserved for future use */
+};
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_GetSpecialFD
+ * DESCRIPTION: Get the file descriptor that represents the standard input,
+ *              output, or error stream.
+ * INPUTS:
+ *     PRSpecialFD id
+ *         A value indicating the type of stream desired:
+ *             PR_StandardInput: standard input
+ *             PR_StandardOuput: standard output
+ *             PR_StandardError: standard error
+ * OUTPUTS: none
+ * RETURNS: PRFileDesc *
+ *     If the argument is valid, PR_GetSpecialFD returns a file descriptor
+ *     that represents the corresponding standard I/O stream.  Otherwise,
+ *     PR_GetSpecialFD returns NULL and sets error PR_INVALID_ARGUMENT_ERROR.
+ **************************************************************************
+ */
+
+typedef enum PRSpecialFD
+{
+    PR_StandardInput,          /* standard input */
+    PR_StandardOutput,         /* standard output */
+    PR_StandardError           /* standard error */
+} PRSpecialFD;
+
+NSPR_API(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD id);
+
+#define PR_STDIN	PR_GetSpecialFD(PR_StandardInput)
+#define PR_STDOUT	PR_GetSpecialFD(PR_StandardOutput)
+#define PR_STDERR	PR_GetSpecialFD(PR_StandardError)
+
+/*
+ **************************************************************************
+ * Layering file descriptors
+ *
+ * File descriptors may be layered. Each layer has it's own identity.
+ * Identities are allocated by the runtime and are to be associated
+ * (by the layer implementor) with all layers that are of that type.
+ * It is then possible to scan the chain of layers and find a layer
+ * that one recongizes and therefore predict that it will implement
+ * a desired protocol.
+ *
+ * There are three well-known identities:
+ *      PR_INVALID_IO_LAYER => an invalid layer identity, for error return
+ *      PR_TOP_IO_LAYER     => the identity of the top of the stack
+ *      PR_NSPR_IO_LAYER    => the identity used by NSPR proper
+ * PR_TOP_IO_LAYER may be used as a shorthand for identifying the topmost
+ * layer of an existing stack. Ie., the following two constructs are
+ * equivalent.
+ *
+ *      rv = PR_PushIOLayer(stack, PR_TOP_IO_LAYER, my_layer);
+ *      rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), my_layer)
+ *
+ * A string may be associated with the creation of the identity. It
+ * will be copied by the runtime. If queried the runtime will return
+ * a reference to that copied string (not yet another copy). There
+ * is no facility for deleting an identity.
+ **************************************************************************
+ */
+
+#define PR_IO_LAYER_HEAD (PRDescIdentity)-3
+#define PR_INVALID_IO_LAYER (PRDescIdentity)-1
+#define PR_TOP_IO_LAYER (PRDescIdentity)-2
+#define PR_NSPR_IO_LAYER (PRDescIdentity)0
+
+NSPR_API(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name);
+NSPR_API(const char*) PR_GetNameForIdentity(PRDescIdentity ident);
+NSPR_API(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd);
+NSPR_API(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd_stack, PRDescIdentity id);
+
+/*
+ **************************************************************************
+ * PR_GetDefaultIOMethods: Accessing the default methods table.
+ * You may get a pointer to the default methods table by calling this function.
+ * You may then select any elements from that table with which to build your
+ * layer's methods table. You may NOT modify the table directly.
+ **************************************************************************
+ */
+NSPR_API(const PRIOMethods *) PR_GetDefaultIOMethods(void);
+
+/*
+ **************************************************************************
+ * Creating a layer
+ *
+ * A new layer may be allocated by calling PR_CreateIOLayerStub(). The
+ * file descriptor returned will contain the pointer to the methods table
+ * provided. The runtime will not modify the table nor test its correctness.
+ **************************************************************************
+ */
+NSPR_API(PRFileDesc*) PR_CreateIOLayerStub(
+    PRDescIdentity ident, const PRIOMethods *methods);
+
+/*
+ **************************************************************************
+ * Creating a layer
+ *
+ * A new stack may be created by calling PR_CreateIOLayer(). The
+ * file descriptor returned will point to the top of the stack, which has
+ * the layer 'fd' as the topmost layer.
+ * 
+ * NOTE: This function creates a new style stack, which has a fixed, dummy
+ * header. The old style stack, created by a call to PR_PushIOLayer,
+ * results in modifying contents of the top layer of the stack, when
+ * pushing and popping layers of the stack.
+ **************************************************************************
+ */
+NSPR_API(PRFileDesc*) PR_CreateIOLayer(PRFileDesc* fd);
+
+/*
+ **************************************************************************
+ * Pushing a layer
+ *
+ * A file descriptor (perhaps allocated using PR_CreateIOLayerStub()) may
+ * be pushed into an existing stack of file descriptors at any point the
+ * caller deems appropriate. The new layer will be inserted into the stack
+ * just above the layer with the indicated identity.
+ *
+ * Note: Even if the identity parameter indicates the top-most layer of
+ * the stack, the value of the file descriptor describing the original
+ * stack will not change.
+ **************************************************************************
+ */
+NSPR_API(PRStatus) PR_PushIOLayer(
+    PRFileDesc *fd_stack, PRDescIdentity id, PRFileDesc *layer);
+
+/*
+ **************************************************************************
+ * Popping a layer
+ *
+ * A layer may be popped from a stack by indicating the identity of the
+ * layer to be removed. If found, a pointer to the removed object will
+ * be returned to the caller. The object then becomes the responsibility
+ * of the caller.
+ *
+ * Note: Even if the identity indicates the top layer of the stack, the
+ * reference returned will not be the file descriptor for the stack and
+ * that file descriptor will remain valid.
+ **************************************************************************
+ */
+NSPR_API(PRFileDesc*) PR_PopIOLayer(PRFileDesc *fd_stack, PRDescIdentity id);
+
+/*
+ **************************************************************************
+ * FUNCTION:    PR_Open
+ * DESCRIPTION:    Open a file for reading, writing, or both.
+ * INPUTS:
+ *     const char *name
+ *         The path name of the file to be opened
+ *     PRIntn flags
+ *         The file status flags.
+ *         It is a bitwise OR of the following bit flags (only one of
+ *         the first three flags below may be used):
+ *		PR_RDONLY        Open for reading only.
+ *		PR_WRONLY        Open for writing only.
+ *		PR_RDWR          Open for reading and writing.
+ *		PR_CREATE_FILE   If the file does not exist, the file is created
+ *                              If the file exists, this flag has no effect.
+ *      PR_SYNC          If set, each write will wait for both the file data
+ *                              and file status to be physically updated.
+ *		PR_APPEND        The file pointer is set to the end of
+ *                              the file prior to each write.
+ *		PR_TRUNCATE      If the file exists, its length is truncated to 0.
+ *      PR_EXCL          With PR_CREATE_FILE, if the file does not exist,
+ *                              the file is created. If the file already 
+ *                              exists, no action and NULL is returned
+ *
+ *     PRIntn mode
+ *         The access permission bits of the file mode, if the file is
+ *         created when PR_CREATE_FILE is on.
+ * OUTPUTS:    None
+ * RETURNS:    PRFileDesc *
+ *     If the file is successfully opened,
+ *     returns a pointer to the PRFileDesc
+ *     created for the newly opened file.
+ *     Returns a NULL pointer if the open
+ *     failed.
+ * SIDE EFFECTS:
+ * RESTRICTIONS:
+ * MEMORY:
+ *     The return value, if not NULL, points to a dynamically allocated
+ *     PRFileDesc object.
+ * ALGORITHM:
+ **************************************************************************
+ */
+
+/* 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.
+** 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);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRFileDesc*) PR_OpenFileUTF16(
+    const PRUnichar *name, PRIntn flags, PRIntn mode);
+#endif /* MOZ_UNICODE */
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_Close
+ * DESCRIPTION:
+ *     Close a file or socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         a pointer to a PRFileDesc.
+ * OUTPUTS:
+ *     None.
+ * RETURN:
+ *     PRStatus
+ * SIDE EFFECTS:
+ * RESTRICTIONS:
+ *     None.
+ * MEMORY:
+ *     The dynamic memory pointed to by the argument fd is freed.
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus)    PR_Close(PRFileDesc *fd);
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_Read
+ * DESCRIPTION:
+ *     Read bytes from a file or socket.
+ *     The operation will block until either an end of stream indication is
+ *     encountered, some positive number of bytes are transferred, or there
+ *     is an error. No more than 'amount' bytes will be transferred.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         pointer to the PRFileDesc object for the file or socket
+ *     void *buf
+ *         pointer to a buffer to hold the data read in.
+ *     PRInt32 amount
+ *         the size of 'buf' (in bytes)
+ * OUTPUTS:
+ * RETURN:
+ *     PRInt32
+ *         a positive number indicates the number of bytes actually read in.
+ *         0 means end of file is reached or the network connection is closed.
+ *         -1 indicates a failure. The reason for the failure is obtained
+ *         by calling PR_GetError().
+ * SIDE EFFECTS:
+ *     data is written into the buffer pointed to by 'buf'.
+ * RESTRICTIONS:
+ *     None.
+ * MEMORY:
+ *     N/A
+ * ALGORITHM:
+ *     N/A
+ **************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount);
+
+/*
+ ***************************************************************************
+ * FUNCTION: PR_Write
+ * DESCRIPTION:
+ *     Write a specified number of bytes to a file or socket.  The thread
+ *     invoking this function blocks until all the data is written.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         pointer to a PRFileDesc object that refers to a file or socket
+ *     const void *buf
+ *         pointer to the buffer holding the data
+ *     PRInt32 amount
+ *         amount of data in bytes to be written from the buffer
+ * OUTPUTS:
+ *     None.
+ * RETURN: PRInt32
+ *     A positive number indicates the number of bytes successfully written.
+ *     A -1 is an indication that the operation failed. The reason
+ *     for the failure is obtained by calling PR_GetError().
+ ***************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_Write(PRFileDesc *fd,const void *buf,PRInt32 amount);
+
+/*
+ ***************************************************************************
+ * FUNCTION: PR_Writev
+ * DESCRIPTION:
+ *     Write data to a socket.  The data is organized in a PRIOVec array. The
+ *     operation will block until all the data is written or the operation
+ *     fails.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         Pointer that points to a PRFileDesc object for a socket.
+ *     const PRIOVec *iov
+ *         An array of PRIOVec.  PRIOVec is a struct with the following
+ *         two fields:
+ *             char *iov_base;
+ *             int iov_len;
+ *     PRInt32 iov_size
+ *         Number of elements in the iov array. The value of this
+ *         argument must not be greater than PR_MAX_IOVECTOR_SIZE.
+ *         If it is, the method will fail (PR_BUFFER_OVERFLOW_ERROR).
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the entire write operation.
+ * OUTPUTS:
+ *     None
+ * RETURN:
+ *     A positive number indicates the number of bytes successfully written.
+ *     A -1 is an indication that the operation failed. The reason
+ *     for the failure is obtained by calling PR_GetError().
+ ***************************************************************************
+ */
+
+#define PR_MAX_IOVECTOR_SIZE 16   /* 'iov_size' must be <= */
+
+NSPR_API(PRInt32) PR_Writev(
+    PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
+    PRIntervalTime timeout);
+
+/*
+ ***************************************************************************
+ * FUNCTION: PR_Delete
+ * DESCRIPTION:
+ *     Delete a file from the filesystem. The operation may fail if the
+ *     file is open.
+ * INPUTS:
+ *     const char *name
+ *         Path name of the file to be deleted.
+ * OUTPUTS:
+ *     None.
+ * RETURN: PRStatus
+ *     The function returns PR_SUCCESS if the file is successfully
+ *     deleted, otherwise it returns PR_FAILURE.
+ ***************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_Delete(const char *name);
+
+/**************************************************************************/
+
+typedef enum PRFileType
+{
+    PR_FILE_FILE = 1,
+    PR_FILE_DIRECTORY = 2,
+    PR_FILE_OTHER = 3
+} PRFileType;
+
+struct PRFileInfo {
+    PRFileType type;        /* Type of file */
+    PROffset32 size;        /* Size, in bytes, of file's contents */
+    PRTime creationTime;    /* Creation time per definition of PRTime */
+    PRTime modifyTime;      /* Last modification time per definition of PRTime */
+};
+
+struct PRFileInfo64 {
+    PRFileType type;        /* Type of file */
+    PROffset64 size;        /* Size, in bytes, of file's contents */
+    PRTime creationTime;    /* Creation time per definition of PRTime */
+    PRTime modifyTime;      /* Last modification time per definition of PRTime */
+};
+
+/****************************************************************************
+ * FUNCTION: PR_GetFileInfo, PR_GetFileInfo64
+ * DESCRIPTION:
+ *     Get the information about the file with the given path name. This is
+ *     applicable only to NSFileDesc describing 'file' types (see
+ * INPUTS:
+ *     const char *fn
+ *         path name of the file
+ * OUTPUTS:
+ *     PRFileInfo *info
+ *         Information about the given file is written into the file
+ *         information object pointer to by 'info'.
+ * RETURN: PRStatus
+ *     PR_GetFileInfo returns PR_SUCCESS if file information is successfully
+ *     obtained, otherwise it returns PR_FAILURE.
+ ***************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info);
+NSPR_API(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info);
+#endif /* MOZ_UNICODE */
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_GetOpenFileInfo, PR_GetOpenFileInfo64
+ * DESCRIPTION:
+ *     Get information about an open file referred to by the
+ *     given PRFileDesc object.
+ * INPUTS:
+ *     const PRFileDesc *fd
+ *          A reference to a valid, open file.
+ * OUTPUTS:
+ *     Same as PR_GetFileInfo, PR_GetFileInfo64
+ * RETURN: PRStatus
+ *     PR_GetFileInfo returns PR_SUCCESS if file information is successfully
+ *     obtained, otherwise it returns PR_FAILURE.
+ ***************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info);
+NSPR_API(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info);
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_Rename
+ * DESCRIPTION:
+ *     Rename a file from the old name 'from' to the new name 'to'.
+ * INPUTS:
+ *     const char *from
+ *         The old name of the file to be renamed.
+ *     const char *to
+ *         The new name of the file.
+ * OUTPUTS:
+ *     None.
+ * RETURN: PRStatus
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus)    PR_Rename(const char *from, const char *to);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Access
+ * DESCRIPTION:
+ *     Determine accessibility of a file.
+ * INPUTS:
+ *     const char *name
+ *         path name of the file
+ *     PRAccessHow how
+ *         specifies which access permission to check for.
+ *         It can be one of the following values:
+ *             PR_ACCESS_READ_OK       Test for read permission
+ *             PR_ACCESS_WRITE_OK      Test for write permission
+ *             PR_ACCESS_EXISTS        Check existence of file
+ * OUTPUTS:
+ *     None.
+ * RETURN: PRStatus
+ *     PR_SUCCESS is returned if the requested access is permitted.
+ *     Otherwise, PR_FAILURE is returned. Additional information
+ *     regarding the reason for the failure may be retrieved from
+ *     PR_GetError().
+ *************************************************************************
+ */
+
+typedef enum PRAccessHow {
+    PR_ACCESS_EXISTS = 1,
+    PR_ACCESS_WRITE_OK = 2,
+    PR_ACCESS_READ_OK = 3
+} PRAccessHow;
+
+NSPR_API(PRStatus) PR_Access(const char *name, PRAccessHow how);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Seek, PR_Seek64
+ * DESCRIPTION:
+ *     Moves read-write file offset
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         Pointer to a PRFileDesc object.
+ *     PROffset32, PROffset64 offset
+ *         Specifies a value, in bytes, that is used in conjunction
+ *         with the 'whence' parameter to set the file pointer.  A
+ *         negative value causes seeking in the reverse direction.
+ *     PRSeekWhence whence
+ *         Specifies how to interpret the 'offset' parameter in setting
+ *         the file pointer associated with the 'fd' parameter.
+ *         Values for the 'whence' parameter are:
+ *             PR_SEEK_SET  Sets the file pointer to the value of the
+ *                          'offset' parameter
+ *             PR_SEEK_CUR  Sets the file pointer to its current location
+ *                          plus the value of the offset parameter.
+ *             PR_SEEK_END  Sets the file pointer to the size of the
+ *                          file plus the value of the offset parameter.
+ * OUTPUTS:
+ *     None.
+ * RETURN: PROffset32, PROffset64
+ *     Upon successful completion, the resulting pointer location,
+ *     measured in bytes from the beginning of the file, is returned.
+ *     If the PR_Seek() function fails, the file offset remains
+ *     unchanged, and the returned value is -1. The error code can
+ *     then be retrieved via PR_GetError().
+ *************************************************************************
+ */
+
+NSPR_API(PROffset32) PR_Seek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence);
+NSPR_API(PROffset64) PR_Seek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence);
+
+/*
+ ************************************************************************
+ * FUNCTION: PR_Available
+ * DESCRIPTION:
+ *     Determine the amount of data in bytes available for reading
+ *     in the given file or socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         Pointer to a PRFileDesc object that refers to a file or
+ *         socket.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32, PRInt64
+ *     Upon successful completion, PR_Available returns the number of
+ *     bytes beyond the current read pointer that is available for
+ *     reading.  Otherwise, it returns a -1 and the reason for the
+ *     failure can be retrieved via PR_GetError().
+ ************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_Available(PRFileDesc *fd);
+NSPR_API(PRInt64) PR_Available64(PRFileDesc *fd);
+
+/*
+ ************************************************************************
+ * FUNCTION: PR_Sync
+ * DESCRIPTION:
+ *     Sync any buffered data for a fd to its backing device (disk).
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         Pointer to a PRFileDesc object that refers to a file or
+ *         socket
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     PR_SUCCESS is returned if the requested access is permitted.
+ *     Otherwise, PR_FAILURE is returned.
+ ************************************************************************
+ */
+
+NSPR_API(PRStatus)	PR_Sync(PRFileDesc *fd);
+
+/************************************************************************/
+
+struct PRDirEntry {
+    const char *name;        /* name of entry, relative to directory name */
+};
+
+#ifdef MOZ_UNICODE
+struct PRDirEntryUTF16 {
+    const PRUnichar *name;   /* name of entry in UTF16, relative to
+                              * directory name */
+};
+#endif /* MOZ_UNICODE */
+
+#if !defined(NO_NSPR_10_SUPPORT)
+#define PR_DirName(dirEntry)	(dirEntry->name)
+#endif
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_OpenDir
+ * DESCRIPTION:
+ *     Open the directory by the given name
+ * INPUTS:
+ *     const char *name
+ *         path name of the directory to be opened
+ * OUTPUTS:
+ *     None
+ * RETURN: PRDir *
+ *     If the directory is sucessfully opened, a PRDir object is
+ *     dynamically allocated and a pointer to it is returned.
+ *     If the directory cannot be opened, a NULL pointer is returned.
+ * MEMORY:
+ *     Upon successful completion, the return value points to
+ *     dynamically allocated memory.
+ *************************************************************************
+ */
+
+NSPR_API(PRDir*) PR_OpenDir(const char *name);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name);
+#endif /* MOZ_UNICODE */
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_ReadDir
+ * DESCRIPTION:
+ * INPUTS:
+ *     PRDir *dir
+ *         pointer to a PRDir object that designates an open directory
+ *     PRDirFlags flags
+ *           PR_SKIP_NONE     Do not skip any files
+ *           PR_SKIP_DOT      Skip the directory entry "." that
+ *                            represents the current directory
+ *           PR_SKIP_DOT_DOT  Skip the directory entry ".." that
+ *                            represents the parent directory.
+ *           PR_SKIP_BOTH     Skip both '.' and '..'
+ *           PR_SKIP_HIDDEN   Skip hidden files
+ * OUTPUTS:
+ * RETURN: PRDirEntry*
+ *     Returns a pointer to the next entry in the directory.  Returns
+ *     a NULL pointer upon reaching the end of the directory or when an
+ *     error occurs. The actual reason can be retrieved via PR_GetError().
+ *************************************************************************
+ */
+
+typedef enum PRDirFlags {
+    PR_SKIP_NONE = 0x0,
+    PR_SKIP_DOT = 0x1,
+    PR_SKIP_DOT_DOT = 0x2,
+    PR_SKIP_BOTH = 0x3,
+    PR_SKIP_HIDDEN = 0x4
+} PRDirFlags;
+
+NSPR_API(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags);
+#endif /* MOZ_UNICODE */
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_CloseDir
+ * DESCRIPTION:
+ *     Close the specified directory.
+ * INPUTS:
+ *     PRDir *dir
+ *        The directory to be closed.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *        If successful, will return a status of PR_SUCCESS. Otherwise
+ *        a value of PR_FAILURE. The reason for the failure may be re-
+ *        trieved using PR_GetError().
+ *************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_CloseDir(PRDir *dir);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir);
+#endif /* MOZ_UNICODE */
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_MkDir
+ * DESCRIPTION:
+ *     Create a new directory with the given name and access mode.
+ * INPUTS:
+ *     const char *name
+ *        The name of the directory to be created. All the path components
+ *        up to but not including the leaf component must already exist.
+ *     PRIntn mode
+ *        See 'mode' definiton in PR_Open().
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *        If successful, will return a status of PR_SUCCESS. Otherwise
+ *        a value of PR_FAILURE. The reason for the failure may be re-
+ *        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:
+ *     None
+ * RETURN: PRStatus
+ *        If successful, will return a status of PR_SUCCESS. Otherwise
+ *        a value of PR_FAILURE. The reason for the failure may be re-
+ *        trieved using PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_RmDir(const char *name);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_NewUDPSocket
+ * DESCRIPTION:
+ *     Create a new UDP socket.
+ * INPUTS:
+ *     None
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_NewUDPSocket returns a pointer
+ *     to the PRFileDesc created for the newly opened UDP socket.
+ *     Returns a NULL pointer if the creation of a new UDP socket failed.
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)    PR_NewUDPSocket(void);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_NewTCPSocket
+ * DESCRIPTION:
+ *     Create a new TCP socket.
+ * INPUTS:
+ *     None
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_NewTCPSocket returns a pointer
+ *     to the PRFileDesc created for the newly opened TCP socket.
+ *     Returns a NULL pointer if the creation of a new TCP socket failed.
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)    PR_NewTCPSocket(void);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_OpenUDPSocket
+ * DESCRIPTION:
+ *     Create a new UDP socket of the specified address family.
+ * INPUTS:
+ *     PRIntn af
+ *       Address family
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_OpenUDPSocket returns a pointer
+ *     to the PRFileDesc created for the newly opened UDP socket.
+ *     Returns a NULL pointer if the creation of a new UDP socket failed.
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)    PR_OpenUDPSocket(PRIntn af);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_OpenTCPSocket
+ * DESCRIPTION:
+ *     Create a new TCP socket of the specified address family.
+ * INPUTS:
+ *     PRIntn af
+ *       Address family
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_NewTCPSocket returns a pointer
+ *     to the PRFileDesc created for the newly opened TCP socket.
+ *     Returns a NULL pointer if the creation of a new TCP socket failed.
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)    PR_OpenTCPSocket(PRIntn af);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Connect
+ * DESCRIPTION:
+ *     Initiate a connection on a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a socket
+ *     PRNetAddr *addr
+ *       Specifies the address of the socket in its own communication
+ *       space.
+ *     PRIntervalTime timeout
+ *       The function uses the lesser of the provided timeout and
+ *       the OS's connect timeout.  In particular, if you specify
+ *       PR_INTERVAL_NO_TIMEOUT as the timeout, the OS's connection
+ *       time limit will be used.
+ *
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     Upon successful completion of connection initiation, PR_Connect
+ *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+ *     failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_Connect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_ConnectContinue
+ * DESCRIPTION:
+ *     Continue a nonblocking connect.  After a nonblocking connect
+ *     is initiated with PR_Connect() (which fails with
+ *     PR_IN_PROGRESS_ERROR), one should call PR_Poll() on the socket,
+ *     with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT.  When
+ *     PR_Poll() returns, one calls PR_ConnectContinue() on the
+ *     socket to determine whether the nonblocking connect has
+ *     completed or is still in progress.  Repeat the PR_Poll(),
+ *     PR_ConnectContinue() sequence until the nonblocking connect
+ *     has completed.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         the file descriptor representing a socket
+ *     PRInt16 out_flags
+ *         the out_flags field of the poll descriptor returned by
+ *         PR_Poll()
+ * RETURN: PRStatus
+ *     If the nonblocking connect has successfully completed,
+ *     PR_ConnectContinue returns PR_SUCCESS.  If PR_ConnectContinue()
+ *     returns PR_FAILURE, call PR_GetError():
+ *     - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in
+ *       progress and has not completed yet.  The caller should poll
+ *       on the file descriptor for the in_flags
+ *       PR_POLL_WRITE|PR_POLL_EXCEPT and retry PR_ConnectContinue
+ *       later when PR_Poll() returns.
+ *     - Other errors: the nonblocking connect has failed with this
+ *       error code.
+ */
+
+NSPR_API(PRStatus)    PR_ConnectContinue(PRFileDesc *fd, PRInt16 out_flags);
+
+/*
+ *************************************************************************
+ * THIS FUNCTION IS DEPRECATED.  USE PR_ConnectContinue INSTEAD.
+ *
+ * FUNCTION: PR_GetConnectStatus
+ * DESCRIPTION:
+ *     Get the completion status of a nonblocking connect.  After
+ *     a nonblocking connect is initiated with PR_Connect() (which
+ *     fails with PR_IN_PROGRESS_ERROR), one should call PR_Poll()
+ *     on the socket, with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT.
+ *     When PR_Poll() returns, one calls PR_GetConnectStatus on the
+ *     PRPollDesc structure to determine whether the nonblocking
+ *     connect has succeeded or failed.
+ * INPUTS:
+ *     const PRPollDesc *pd
+ *         Pointer to a PRPollDesc whose fd member is the socket,
+ *         and in_flags must contain PR_POLL_WRITE and PR_POLL_EXCEPT.
+ *         PR_Poll() should have been called and set the out_flags.
+ * RETURN: PRStatus
+ *     If the nonblocking connect has successfully completed,
+ *     PR_GetConnectStatus returns PR_SUCCESS.  If PR_GetConnectStatus()
+ *     returns PR_FAILURE, call PR_GetError():
+ *     - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in
+ *       progress and has not completed yet.
+ *     - Other errors: the nonblocking connect has failed with this
+ *       error code.
+ */
+
+NSPR_API(PRStatus)    PR_GetConnectStatus(const PRPollDesc *pd);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Accept
+ * DESCRIPTION:
+ *     Accept a connection on a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing the rendezvous socket
+ *       on which the caller is willing to accept new connections.
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the accept operation.
+ * OUTPUTS:
+ *     PRNetAddr *addr
+ *       Returns the address of the connecting entity in its own
+ *       communication space. It may be NULL.
+ * RETURN: PRFileDesc*
+ *     Upon successful acceptance of a connection, PR_Accept
+ *     returns a valid file descriptor. Otherwise, it returns NULL.
+ *     Further failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*) PR_Accept(
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Bind
+ * DESCRIPTION:
+ *    Bind an address to a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a socket.
+ *     PRNetAddr *addr
+ *       Specifies the address to which the socket will be bound.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     Upon successful binding of an address to a socket, PR_Bind
+ *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+ *     failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Listen
+ * DESCRIPTION:
+ *    Listen for connections on a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a socket that will be
+ *       used to listen for new connections.
+ *     PRIntn backlog
+ *       Specifies the maximum length of the queue of pending connections.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     Upon successful completion of listen request, PR_Listen
+ *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+ *     failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Shutdown
+ * DESCRIPTION:
+ *    Shut down part of a full-duplex connection on a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a connected socket.
+ *     PRIntn how
+ *       Specifies the kind of disallowed operations on the socket.
+ *           PR_SHUTDOWN_RCV - Further receives will be disallowed
+ *           PR_SHUTDOWN_SEND - Further sends will be disallowed
+ *           PR_SHUTDOWN_BOTH - Further sends and receives will be disallowed
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     Upon successful completion of shutdown request, PR_Shutdown
+ *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+ *     failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+typedef enum PRShutdownHow
+{
+    PR_SHUTDOWN_RCV = 0,      /* disallow further receives */
+    PR_SHUTDOWN_SEND = 1,     /* disallow further sends */
+    PR_SHUTDOWN_BOTH = 2      /* disallow further receives and sends */
+} PRShutdownHow;
+
+NSPR_API(PRStatus)    PR_Shutdown(PRFileDesc *fd, PRShutdownHow how);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Recv
+ * DESCRIPTION:
+ *    Receive a specified number of bytes from a connected socket.
+ *     The operation will block until some positive number of bytes are 
+ *     transferred, a time out has occurred, or there is an error. 
+ *     No more than 'amount' bytes will be transferred.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       points to a PRFileDesc object representing a socket.
+ *     void *buf
+ *       pointer to a buffer to hold the data received.
+ *     PRInt32 amount
+ *       the size of 'buf' (in bytes)
+ *     PRIntn flags
+ *       must be zero or PR_MSG_PEEK.
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the receive operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32
+ *         a positive number indicates the number of bytes actually received.
+ *         0 means the network connection is closed.
+ *         -1 indicates a failure. The reason for the failure is obtained
+ *         by calling PR_GetError().
+ **************************************************************************
+ */
+
+#define PR_MSG_PEEK 0x2
+
+NSPR_API(PRInt32)    PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+                PRIntn flags, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Send
+ * DESCRIPTION:
+ *    Send a specified number of bytes from a connected socket.
+ *     The operation will block until all bytes are 
+ *     processed, a time out has occurred, or there is an error. 
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       points to a PRFileDesc object representing a socket.
+ *     void *buf
+ *       pointer to a buffer from where the data is sent.
+ *     PRInt32 amount
+ *       the size of 'buf' (in bytes)
+ *     PRIntn flags
+ *        (OBSOLETE - must always be zero)
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the send operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32
+ *     A positive number indicates the number of bytes successfully processed.
+ *     This number must always equal 'amount'. A -1 is an indication that the
+ *     operation failed. The reason for the failure is obtained by calling
+ *     PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRInt32)    PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+                                PRIntn flags, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_RecvFrom
+ * DESCRIPTION:
+ *     Receive up to a specified number of bytes from socket which may
+ *     or may not be connected.
+ *     The operation will block until one or more bytes are 
+ *     transferred, a time out has occurred, or there is an error. 
+ *     No more than 'amount' bytes will be transferred.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       points to a PRFileDesc object representing a socket.
+ *     void *buf
+ *       pointer to a buffer to hold the data received.
+ *     PRInt32 amount
+ *       the size of 'buf' (in bytes)
+ *     PRIntn flags
+ *        (OBSOLETE - must always be zero)
+ *     PRNetAddr *addr
+ *       Specifies the address of the sending peer. It may be NULL.
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the receive operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32
+ *         a positive number indicates the number of bytes actually received.
+ *         0 means the network connection is closed.
+ *         -1 indicates a failure. The reason for the failure is obtained
+ *         by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_RecvFrom(
+    PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+    PRNetAddr *addr, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_SendTo
+ * DESCRIPTION:
+ *    Send a specified number of bytes from an unconnected socket.
+ *    The operation will block until all bytes are 
+ *    sent, a time out has occurred, or there is an error. 
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       points to a PRFileDesc object representing an unconnected socket.
+ *     void *buf
+ *       pointer to a buffer from where the data is sent.
+ *     PRInt32 amount
+ *       the size of 'buf' (in bytes)
+ *     PRIntn flags
+ *        (OBSOLETE - must always be zero)
+ *     PRNetAddr *addr
+ *       Specifies the address of the peer.
+.*     PRIntervalTime timeout
+ *       Time limit for completion of the send operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32
+ *     A positive number indicates the number of bytes successfully sent.
+ *     -1 indicates a failure. The reason for the failure is obtained
+ *     by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_SendTo(
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+    const PRNetAddr *addr, PRIntervalTime timeout);
+
+/*
+*************************************************************************
+** FUNCTION: PR_TransmitFile
+** DESCRIPTION:
+**    Transmitfile sends a complete file (sourceFile) across a socket 
+**    (networkSocket).  If headers is non-NULL, the headers will be sent across
+**    the socket prior to sending the file.
+** 
+**    Optionally, the PR_TRANSMITFILE_CLOSE_SOCKET flag may be passed to
+**    transmitfile.  This flag specifies that transmitfile should close the
+**    socket after sending the data.
+**
+** INPUTS:
+**    PRFileDesc *networkSocket
+**        The socket to send data over
+**    PRFileDesc *sourceFile
+**        The file to send
+**    const void *headers
+**        A pointer to headers to be sent before sending data
+**    PRInt32       hlen
+**        length of header buffers in bytes.
+**    PRTransmitFileFlags       flags
+**        If the flags indicate that the connection should be closed,
+**        it will be done immediately after transferring the file, unless
+**        the operation is unsuccessful. 
+.*     PRIntervalTime timeout
+ *        Time limit for completion of the transmit operation.
+**
+** RETURNS:
+**    Returns the number of bytes written or -1 if the operation failed.
+**    If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_
+**    SOCKET flag is ignored. The reason for the failure is obtained
+**    by calling PR_GetError().
+**************************************************************************
+*/
+
+NSPR_API(PRInt32) PR_TransmitFile(
+    PRFileDesc *networkSocket, PRFileDesc *sourceFile,
+    const void *headers, PRInt32 hlen, PRTransmitFileFlags flags,
+    PRIntervalTime timeout);
+
+/*
+*************************************************************************
+** FUNCTION: PR_SendFile
+** DESCRIPTION:
+**    PR_SendFile sends data from a file (sendData->fd) across a socket 
+**    (networkSocket).  If specified, a header and/or trailer buffer are sent
+**	  before and after the file, respectively. The file offset, number of bytes
+** 	  of file data to send, the header and trailer buffers are specified in the
+**	  sendData argument.
+** 
+**    Optionally, if the PR_TRANSMITFILE_CLOSE_SOCKET flag is passed, the
+**    socket is closed after successfully sending the data.
+**
+** INPUTS:
+**    PRFileDesc *networkSocket
+**        The socket to send data over
+**    PRSendFileData *sendData
+**        Contains the FD, file offset and length, header and trailer
+**		  buffer specifications.
+**    PRTransmitFileFlags       flags
+**        If the flags indicate that the connection should be closed,
+**        it will be done immediately after transferring the file, unless
+**        the operation is unsuccessful. 
+.*     PRIntervalTime timeout
+ *        Time limit for completion of the send operation.
+**
+** RETURNS:
+**    Returns the number of bytes written or -1 if the operation failed.
+**    If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_
+**    SOCKET flag is ignored. The reason for the failure is obtained
+**    by calling PR_GetError().
+**************************************************************************
+*/
+
+struct PRSendFileData {
+	PRFileDesc	*fd;			/* file to send							*/
+	PRUint32	file_offset;	/* file offset							*/
+	PRSize		file_nbytes;	/* number of bytes of file data to send	*/
+								/* if 0, send data from file_offset to	*/
+								/* end-of-file.							*/
+	const void	*header;		/* header buffer						*/
+	PRInt32		hlen;			/* header len							*/
+	const void	*trailer;		/* trailer buffer						*/
+	PRInt32		tlen;			/* trailer len							*/
+};
+
+
+NSPR_API(PRInt32) PR_SendFile(
+    PRFileDesc *networkSocket, PRSendFileData *sendData,
+	PRTransmitFileFlags flags, PRIntervalTime timeout);
+
+/*
+*************************************************************************
+** FUNCTION: PR_AcceptRead
+** DESCRIPTION:
+**    AcceptRead accepts a new connection, returns the newly created
+**    socket's descriptor and also returns the connecting peer's address.
+**    AcceptRead, as its name suggests, also receives the first block of data 
+**    sent by the peer.
+**
+** 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. 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 
+**        interval elapses.
+** OUTPUTS:
+**    PRFileDesc **acceptedSock
+**        The file descriptor for the newly connected socket.  This parameter
+**        will only be valid if the function return does not indicate failure.
+**    PRNetAddr  **peerAddr,
+**        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:
+**    Create a new TCP socket pair. The returned descriptors can be used
+**    interchangeably; they are interconnected full-duplex descriptors: data
+**    written to one can be read from the other and vice-versa.
+**
+** INPUTS:
+**    None
+** OUTPUTS:
+**    PRFileDesc *fds[2]
+**        The file descriptor pair for the newly created TCP sockets.
+** RETURN: PRStatus
+**     Upon successful completion of TCP socket pair, PR_NewTCPSocketPair 
+**     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+**     failure information can be obtained by calling PR_GetError().
+** XXX can we implement this on windoze and mac?
+**************************************************************************
+**/
+NSPR_API(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]);
+
+/*
+*************************************************************************
+** FUNCTION: PR_GetSockName
+** DESCRIPTION:
+**    Get socket name.  Return the network address for this socket.
+**
+** INPUTS:
+**     PRFileDesc *fd
+**       Points to a PRFileDesc object representing the socket.
+** OUTPUTS:
+**     PRNetAddr *addr
+**       Returns the address of the socket in its own communication space.
+** RETURN: PRStatus
+**     Upon successful completion, PR_GetSockName returns PR_SUCCESS.  
+**     Otherwise, it returns PR_FAILURE.  Further failure information can 
+**     be obtained by calling PR_GetError().
+**************************************************************************
+**/
+NSPR_API(PRStatus)	PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr);
+
+/*
+*************************************************************************
+** FUNCTION: PR_GetPeerName
+** DESCRIPTION:
+**    Get name of the connected peer.  Return the network address for the 
+**    connected peer socket.
+**
+** INPUTS:
+**     PRFileDesc *fd
+**       Points to a PRFileDesc object representing the connected peer.
+** OUTPUTS:
+**     PRNetAddr *addr
+**       Returns the address of the connected peer in its own communication
+**       space.
+** RETURN: PRStatus
+**     Upon successful completion, PR_GetPeerName returns PR_SUCCESS.  
+**     Otherwise, it returns PR_FAILURE.  Further failure information can 
+**     be obtained by calling PR_GetError().
+**************************************************************************
+**/
+NSPR_API(PRStatus)	PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr);
+
+NSPR_API(PRStatus)	PR_GetSocketOption(
+    PRFileDesc *fd, PRSocketOptionData *data);
+
+NSPR_API(PRStatus)	PR_SetSocketOption(
+    PRFileDesc *fd, const PRSocketOptionData *data);
+
+/*
+ *********************************************************************
+ *
+ * File descriptor inheritance
+ *
+ *********************************************************************
+ */
+
+/*
+ ************************************************************************
+ * FUNCTION: PR_SetFDInheritable
+ * DESCRIPTION:
+ *    Set the inheritance attribute of a file descriptor.
+ *
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object.
+ *     PRBool inheritable
+ *       If PR_TRUE, the file descriptor fd is set to be inheritable
+ *       by a child process.  If PR_FALSE, the file descriptor is set
+ *       to be not inheritable by a child process.
+ * RETURN: PRStatus
+ *     Upon successful completion, PR_SetFDInheritable returns PR_SUCCESS.  
+ *     Otherwise, it returns PR_FAILURE.  Further failure information can 
+ *     be obtained by calling PR_GetError().
+ *************************************************************************
+ */
+NSPR_API(PRStatus) PR_SetFDInheritable(
+    PRFileDesc *fd,
+    PRBool inheritable);
+
+/*
+ ************************************************************************
+ * FUNCTION: PR_GetInheritedFD
+ * DESCRIPTION:
+ *    Get an inherited file descriptor with the specified name.
+ *
+ * INPUTS:
+ *     const char *name
+ *       The name of the inherited file descriptor.
+ * RETURN: PRFileDesc *
+ *     Upon successful completion, PR_GetInheritedFD returns the
+ *     inherited file descriptor with the specified name.  Otherwise,  
+ *     it returns NULL.  Further failure information can be obtained
+ *     by calling PR_GetError().
+ *************************************************************************
+ */
+NSPR_API(PRFileDesc *) PR_GetInheritedFD(const char *name);
+
+/*
+ *********************************************************************
+ *
+ * Memory-mapped files
+ *
+ *********************************************************************
+ */
+
+typedef struct PRFileMap PRFileMap;
+
+/*
+ * protection options for read and write accesses of a file mapping
+ */
+typedef enum PRFileMapProtect {
+    PR_PROT_READONLY,     /* read only */
+    PR_PROT_READWRITE,    /* readable, and write is shared */
+    PR_PROT_WRITECOPY     /* readable, and write is private (copy-on-write) */
+} PRFileMapProtect;
+
+NSPR_API(PRFileMap *) PR_CreateFileMap(
+    PRFileDesc *fd,
+    PRInt64 size,
+    PRFileMapProtect prot);
+
+/*
+ * return the alignment (in bytes) of the offset argument to PR_MemMap
+ */
+NSPR_API(PRInt32) PR_GetMemMapAlignment(void);
+
+NSPR_API(void *) PR_MemMap(
+    PRFileMap *fmap,
+    PROffset64 offset,  /* must be aligned and sized according to the
+                         * return value of PR_GetMemMapAlignment() */
+    PRUint32 len);
+
+NSPR_API(PRStatus) PR_MemUnmap(void *addr, PRUint32 len);
+
+NSPR_API(PRStatus) PR_CloseFileMap(PRFileMap *fmap);
+
+/*
+ ******************************************************************
+ *
+ * Interprocess communication
+ *
+ ******************************************************************
+ */
+
+/*
+ * Creates an anonymous pipe and returns file descriptors for the
+ * read and write ends of the pipe.
+ */
+
+NSPR_API(PRStatus) PR_CreatePipe(
+    PRFileDesc **readPipe,
+    PRFileDesc **writePipe
+);
+
+/************************************************************************/
+/************** The following definitions are for poll ******************/
+/************************************************************************/
+
+struct PRPollDesc {
+    PRFileDesc* fd;
+    PRInt16 in_flags;
+    PRInt16 out_flags;
+};
+
+/*
+** Bit values for PRPollDesc.in_flags or PRPollDesc.out_flags. Binary-or
+** these together to produce the desired poll request.
+*/
+
+#if defined(_PR_POLL_BACKCOMPAT)
+
+#include <poll.h>
+#define PR_POLL_READ    POLLIN
+#define PR_POLL_WRITE   POLLOUT
+#define PR_POLL_EXCEPT  POLLPRI
+#define PR_POLL_ERR     POLLERR     /* only in out_flags */
+#define PR_POLL_NVAL    POLLNVAL    /* only in out_flags when fd is bad */
+#define PR_POLL_HUP     POLLHUP     /* only in out_flags */
+
+#else  /* _PR_POLL_BACKCOMPAT */
+
+#define PR_POLL_READ    0x1
+#define PR_POLL_WRITE   0x2
+#define PR_POLL_EXCEPT  0x4
+#define PR_POLL_ERR     0x8         /* only in out_flags */
+#define PR_POLL_NVAL    0x10        /* only in out_flags when fd is bad */
+#define PR_POLL_HUP     0x20        /* only in out_flags */
+
+#endif  /* _PR_POLL_BACKCOMPAT */
+
+/*
+*************************************************************************
+** FUNCTION:    PR_Poll
+** DESCRIPTION:
+**
+** The call returns as soon as I/O is ready on one or more of the underlying
+** socket objects. A count of the number of ready descriptors is
+** returned unless a timeout occurs in which case zero is returned.
+**
+** PRPollDesc.fd should be set to a pointer to a PRFileDesc object
+** representing a socket. This field can be set to NULL to indicate to
+** PR_Poll that this PRFileDesc object should be ignored.
+** PRPollDesc.in_flags should be set to the desired request
+** (read/write/except or some combination). Upon successful return from
+** this call PRPollDesc.out_flags will be set to indicate what kind of
+** i/o can be performed on the respective descriptor. PR_Poll() uses the
+** out_flags fields as scratch variables during the call. If PR_Poll()
+** returns 0 or -1, the out_flags fields do not contain meaningful values
+** and must not be used.
+**
+** INPUTS:
+**      PRPollDesc *pds         A pointer to an array of PRPollDesc
+**
+**      PRIntn npds             The number of elements in the array
+**                              If this argument is zero PR_Poll is
+**                              equivalent to a PR_Sleep(timeout).
+**
+**      PRIntervalTime timeout  Amount of time the call will block waiting
+**                              for I/O to become ready. If this time expires
+**                              w/o any I/O becoming ready, the result will
+**                              be zero.
+**
+** OUTPUTS:    None
+** RETURN:
+**      PRInt32                 Number of PRPollDesc's with events or zero
+**                              if the function timed out or -1 on failure.
+**                              The reason for the failure is obtained by
+**                              calling PR_GetError().
+**************************************************************************
+*/
+NSPR_API(PRInt32) PR_Poll(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout);
+
+/*
+**************************************************************************
+**
+** Pollable events
+**
+** A pollable event is a special kind of file descriptor.
+** The only I/O operation you can perform on a pollable event
+** is to poll it with the PR_POLL_READ flag.  You can't
+** read from or write to a pollable event.
+**
+** The purpose of a pollable event is to combine event waiting
+** with I/O waiting in a single PR_Poll call.  Pollable events
+** are implemented using a pipe or a pair of TCP sockets
+** connected via the loopback address, therefore setting and
+** waiting for pollable events are expensive operating system
+** calls.  Do not use pollable events for general thread
+** synchronization. Use condition variables instead.
+**
+** A pollable event has two states: set and unset.  Events
+** are not queued, so there is no notion of an event count.
+** A pollable event is either set or unset.
+**
+** A new pollable event is created by a PR_NewPollableEvent
+** call and is initially in the unset state.
+**
+** PR_WaitForPollableEvent blocks the calling thread until
+** the pollable event is set, and then it atomically unsets
+** the pollable event before it returns.
+**
+** To set a pollable event, call PR_SetPollableEvent.
+**
+** One can call PR_Poll with the PR_POLL_READ flag on a pollable
+** event.  When the pollable event is set, PR_Poll returns with
+** the PR_POLL_READ flag set in the out_flags.
+**
+** To close a pollable event, call PR_DestroyPollableEvent
+** (not PR_Close).
+**
+**************************************************************************
+*/
+
+NSPR_API(PRFileDesc *) PR_NewPollableEvent(void);
+
+NSPR_API(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event);
+
+NSPR_API(PRStatus) PR_SetPollableEvent(PRFileDesc *event);
+
+NSPR_API(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event);
+
+PR_END_EXTERN_C
+
+#endif /* prio_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/pripcsem.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/pripcsem.h
new file mode 100644
index 0000000..5a96be5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/pripcsem.h
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: pripcsem.h
+ *
+ * Description: named semaphores for interprocess
+ * synchronization
+ *
+ * Unrelated processes obtain access to a shared semaphore
+ * by specifying its name.
+ *
+ * Our goal is to support named semaphores on at least
+ * Unix and Win32 platforms.  The implementation will use
+ * one of the three native semaphore APIs: POSIX, System V,
+ * and Win32.
+ *
+ * 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;
+
+/*
+ * PR_OpenSemaphore --
+ *
+ * Create or open a named semaphore with the specified name.
+ * A handle to the semaphore is returned.
+ *
+ * If the named semaphore doesn't exist and the PR_SEM_CREATE
+ * flag is specified, the named semaphore is created.  The
+ * created semaphore needs to be removed from the system with
+ * a PR_DeleteSemaphore call.
+ *
+ * If PR_SEM_CREATE is specified, the third argument is the
+ * access permission bits of the new semaphore (same
+ * interpretation as the mode argument to PR_Open) and the
+ * fourth argument is the initial value of the new semaphore.
+ * If PR_SEM_CREATE is not specified, the third and fourth
+ * arguments are ignored.
+ */
+
+#define PR_SEM_CREATE 0x1  /* create if not exist */
+#define PR_SEM_EXCL   0x2  /* fail if already exists */
+
+NSPR_API(PRSem *) PR_OpenSemaphore(
+    const char *name, PRIntn flags, PRIntn mode, PRUintn value);
+
+/*
+ * PR_WaitSemaphore --
+ *
+ * If the value of the semaphore is > 0, decrement the value and return.
+ * If the value is 0, sleep until the value becomes > 0, then decrement
+ * the value and return.
+ *
+ * The "test and decrement" operation is performed atomically.
+ */
+
+NSPR_API(PRStatus) PR_WaitSemaphore(PRSem *sem);
+
+/*
+ * PR_PostSemaphore --
+ *
+ * Increment the value of the named semaphore by 1.
+ */
+
+NSPR_API(PRStatus) PR_PostSemaphore(PRSem *sem);
+
+/*
+ * PR_CloseSemaphore --
+ *
+ * Close a named semaphore handle.
+ */
+
+NSPR_API(PRStatus) PR_CloseSemaphore(PRSem *sem);
+
+/*
+ * PR_DeleteSemaphore --
+ *
+ * Remove a named semaphore from the system.
+ */
+
+NSPR_API(PRStatus) PR_DeleteSemaphore(const char *name);
+
+PR_END_EXTERN_C
+
+#endif /* pripcsem_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/private/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/Makefile.in
new file mode 100644
index 0000000..180393b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/Makefile.in
@@ -0,0 +1,61 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+RELEASE_HEADERS = pprio.h pprthred.h prpriv.h
+RELEASE_HEADERS := $(addprefix $(srcdir)/, $(RELEASE_HEADERS))
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)/private
+
+HEADERS = $(RELEASE_HEADERS) $(srcdir)/pprmwait.h $(srcdir)/primpl.h
+
+include_subdir = private
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(RELEASE_HEADERS)
+	$(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)/private
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprio.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprio.h
new file mode 100644
index 0000000..8f29657
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprio.h
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:	pprio.h
+**
+** Description:	Private definitions for I/O related structures
+*/
+
+#ifndef pprio_h___
+#define pprio_h___
+
+#include "prtypes.h"
+#include "prio.h"
+
+PR_BEGIN_EXTERN_C
+
+/************************************************************************/
+/************************************************************************/
+
+#ifdef _WIN64
+typedef __int64 PROsfd;
+#else
+typedef PRInt32 PROsfd;
+#endif
+
+/* Return the method tables for files, tcp sockets and udp sockets */
+NSPR_API(const PRIOMethods*)    PR_GetFileMethods(void);
+NSPR_API(const PRIOMethods*)    PR_GetTCPMethods(void);
+NSPR_API(const PRIOMethods*)    PR_GetUDPMethods(void);
+NSPR_API(const PRIOMethods*)    PR_GetPipeMethods(void);
+
+/*
+** Convert a NSPR socket handle to a native socket handle.
+**
+** Using this function makes your code depend on the properties of the
+** current NSPR implementation, which may change (although extremely
+** unlikely because of NSPR's backward compatibility requirement).  Avoid
+** using it if you can.
+**
+** If you use this function, you need to understand what NSPR does to
+** the native handle.  For example, NSPR puts native socket handles in
+** non-blocking mode or associates them with an I/O completion port (the
+** WINNT build configuration only).  Your use of the native handle should
+** not interfere with NSPR's use of the native handle.  If your code
+** changes the configuration of the native handle, (e.g., changes it to
+** blocking or closes it), NSPR will not work correctly.
+*/
+NSPR_API(PROsfd)       PR_FileDesc2NativeHandle(PRFileDesc *);
+NSPR_API(void)         PR_ChangeFileDescNativeHandle(PRFileDesc *, PROsfd);
+NSPR_API(PRFileDesc*)  PR_AllocFileDesc(PROsfd osfd,
+                                         const PRIOMethods *methods);
+NSPR_API(void)         PR_FreeFileDesc(PRFileDesc *fd);
+/*
+** Import an existing OS file to NSPR. 
+*/
+NSPR_API(PRFileDesc*)  PR_ImportFile(PROsfd osfd);
+NSPR_API(PRFileDesc*)  PR_ImportPipe(PROsfd osfd);
+NSPR_API(PRFileDesc*)  PR_ImportTCPSocket(PROsfd osfd);
+NSPR_API(PRFileDesc*)  PR_ImportUDPSocket(PROsfd osfd);
+
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_CreateSocketPollFd
+ * DESCRIPTION:
+ *     Create a PRFileDesc wrapper for a native socket handle, for use with
+ *	   PR_Poll only
+ * INPUTS:
+ *     None
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_CreateSocketPollFd returns a pointer
+ *     to the PRFileDesc created for the native socket handle
+ *     Returns a NULL pointer if the create of a new PRFileDesc failed
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)	PR_CreateSocketPollFd(PROsfd osfd);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_DestroySocketPollFd
+ * DESCRIPTION:
+ *     Destroy the PRFileDesc wrapper created by PR_CreateSocketPollFd
+ * INPUTS:
+ *     None
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_DestroySocketPollFd returns
+ *	   PR_SUCCESS, else PR_FAILURE
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd);
+
+
+/*
+** Macros for PR_Socket
+**
+** Socket types: PR_SOCK_STREAM, PR_SOCK_DGRAM
+*/
+
+#ifdef WIN32
+
+#define PR_SOCK_STREAM 1
+#define PR_SOCK_DGRAM 2
+
+#else /* WIN32 */
+
+#define PR_SOCK_STREAM SOCK_STREAM
+#define PR_SOCK_DGRAM SOCK_DGRAM
+
+#endif /* WIN32 */
+
+/*
+** Create a new Socket; this function is obsolete.
+*/
+NSPR_API(PRFileDesc*)	PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto);
+
+/* FUNCTION: PR_LockFile
+** DESCRIPTION:
+**    Lock a file for exclusive access.
+** RETURNS:
+**    PR_SUCCESS when the lock is held
+**    PR_FAILURE otherwise
+*/
+NSPR_API(PRStatus) PR_LockFile(PRFileDesc *fd);
+
+/* FUNCTION: PR_TLockFile
+** DESCRIPTION:
+**    Test and Lock a file for exclusive access.  Do not block if the
+**    file cannot be locked immediately.
+** RETURNS:
+**    PR_SUCCESS when the lock is held
+**    PR_FAILURE otherwise
+*/
+NSPR_API(PRStatus) PR_TLockFile(PRFileDesc *fd);
+
+/* FUNCTION: PR_UnlockFile
+** DESCRIPTION:
+**    Unlock a file which has been previously locked successfully by this
+**    process.
+** RETURNS:
+**    PR_SUCCESS when the lock is released
+**    PR_FAILURE otherwise
+*/
+NSPR_API(PRStatus) PR_UnlockFile(PRFileDesc *fd);
+
+/*
+** Emulate acceptread by accept and recv.
+*/
+NSPR_API(PRInt32) PR_EmulateAcceptRead(PRFileDesc *sd, PRFileDesc **nd,
+    PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout);
+
+/*
+** Emulate sendfile by reading from the file and writing to the socket.
+** The file is memory-mapped if memory-mapped files are supported.
+*/
+NSPR_API(PRInt32) PR_EmulateSendFile(
+    PRFileDesc *networkSocket, PRSendFileData *sendData,
+    PRTransmitFileFlags flags, PRIntervalTime timeout);
+
+#ifdef WIN32
+/* FUNCTION: PR_NTFast_AcceptRead
+** DESCRIPTION:
+**    NT has the notion of an "accept context", which is only needed in
+**    order to make certain calls.  By default, a socket connected via
+**    AcceptEx can only do a limited number of things without updating
+**    the acceptcontext.  The generic version of PR_AcceptRead always
+**    updates the accept context.  This version does not.
+**/
+NSPR_API(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd,
+              PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime t);
+
+typedef void (*_PR_AcceptTimeoutCallback)(void *);
+
+/* FUNCTION: PR_NTFast_AcceptRead_WithTimeoutCallback
+** DESCRIPTION:
+**    The AcceptEx call combines the accept with the read function.  However,
+**    our daemon threads need to be able to wakeup and reliably flush their
+**    log buffers if the Accept times out.  However, with the current blocking
+**    interface to AcceptRead, there is no way for us to timeout the Accept;
+**    this is because when we timeout the Read, we can close the newly 
+**    socket and continue; but when we timeout the accept itself, there is no
+**    new socket to timeout.  So instead, this version of the function is
+**    provided.  After the initial timeout period elapses on the accept()
+**    portion of the function, it will call the callback routine and then
+**    continue the accept.   If the timeout occurs on the read, it will 
+**    close the connection and return error.
+*/
+NSPR_API(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback(
+              PRFileDesc *sd, 
+              PRFileDesc **nd,
+              PRNetAddr **raddr, 
+              void *buf, 
+              PRInt32 amount, 
+              PRIntervalTime t,
+              _PR_AcceptTimeoutCallback callback, 
+              void *callback_arg);
+
+/* FUNCTION: PR_NTFast_Accept
+** DESCRIPTION:
+**    NT has the notion of an "accept context", which is only needed in
+**    order to make certain calls.  By default, a socket connected via
+**    AcceptEx can only do a limited number of things without updating
+**    the acceptcontext.  The generic version of PR_Accept always
+**    updates the accept context.  This version does not.
+**/
+NSPR_API(PRFileDesc*)	PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr,
+                                                PRIntervalTime timeout);
+
+/* FUNCTION: PR_NTFast_Update
+** DESCRIPTION:
+**    For sockets accepted with PR_NTFast_Accept or PR_NTFastAcceptRead,
+**    this function will update the accept context for those sockets,
+**    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_CancelIo
+** DESCRIPTION:
+**    Cancel IO operations on fd.
+*/
+NSPR_API(PRStatus) PR_NT_CancelIo(PRFileDesc *fd);
+
+
+#endif /* WIN32 */
+
+PR_END_EXTERN_C
+
+#endif /* pprio_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprmwait.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprmwait.h
new file mode 100644
index 0000000..d116a8b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprmwait.h
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#if defined(_PPRMWAIT_H)
+#else
+#define _PPRMWAIT_H
+
+#include "prlock.h"
+#include "prcvar.h"
+#include "prclist.h"
+#include "prthread.h"
+
+#define MAX_POLLING_INTERVAL 100
+#define _PR_POLL_COUNT_FUDGE 64
+#define _PR_DEFAULT_HASH_LENGTH 59
+
+/*
+ * Our hash table resolves collisions by open addressing with
+ * double hashing.  See Cormen, Leiserson, and Rivest,
+ * Introduction to Algorithms, p. 232, The MIT Press, 1990.
+ */
+
+#define _MW_HASH(a, m) ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m))
+#define _MW_HASH2(a, m) (1 + ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m - 2)))
+#define _MW_ABORTED(_rv) \
+    ((PR_FAILURE == (_rv)) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
+
+typedef enum {_prmw_success, _prmw_rehash, _prmw_error} _PR_HashStory;
+
+typedef struct _PRWaiterHash
+{
+    PRUint16 count;             /* current number in hash table */
+    PRUint16 length;            /* current size of the hash table */
+    PRRecvWait *recv_wait;      /* hash table of receive wait objects */
+} _PRWaiterHash;
+
+typedef enum {_prmw_running, _prmw_stopping, _prmw_stopped} PRMWGroupState;
+
+struct PRWaitGroup
+{
+    PRCList group_link;         /* all groups are linked to each other */
+    PRCList io_ready;           /* list of I/O requests that are ready */
+    PRMWGroupState state;       /* state of this group (so we can shut down) */
+
+    PRLock *ml;                 /* lock for synchronizing this wait group */
+    PRCondVar *io_taken;        /* calling threads notify when they take I/O */
+    PRCondVar *io_complete;     /* calling threads wait here for completions */
+    PRCondVar *new_business;    /* polling thread waits here more work */
+    PRCondVar *mw_manage;       /* used to manage group lists */
+    PRThread* poller;           /* thread that's actually doing the poll() */
+    PRUint16 waiting_threads;   /* number of threads waiting for recv */
+    PRUint16 polling_count;     /* number of elements in the polling list */
+    PRUint32 p_timestamp;       /* pseudo-time group had element removed */
+    PRPollDesc *polling_list;   /* list poller builds for polling */
+    PRIntervalTime last_poll;   /* last time we polled */
+    _PRWaiterHash *waiter;      /* pointer to hash table of wait receive objects */
+
+#ifdef WINNT
+    /*
+     * On NT, idle threads are responsible for getting completed i/o.
+     * They need to add completed i/o to the io_ready list.  Since
+     * idle threads cannot use nspr locks, we have to use an md lock
+     * to protect the io_ready list.
+     */
+    _MDLock mdlock;             /* protect io_ready, waiter, and wait_list */
+    PRCList wait_list;          /* used in place of io_complete.  reuse
+                                 * waitQLinks in the PRThread structure. */
+#endif /* WINNT */
+};
+
+/**********************************************************************
+***********************************************************************
+******************** Wait group enumerations **************************
+***********************************************************************
+**********************************************************************/
+typedef struct _PRGlobalState
+{
+    PRCList group_list;         /* master of the group list */
+    PRWaitGroup *group;         /* the default (NULL) group */
+} _PRGlobalState;
+
+#ifdef WINNT
+extern PRStatus NT_HashRemoveInternal(PRWaitGroup *group, PRFileDesc *fd);
+#endif
+
+typedef enum {_PR_ENUM_UNSEALED=0, _PR_ENUM_SEALED=0x0eadface} _PREnumSeal;
+
+struct PRMWaitEnumerator
+{
+    PRWaitGroup *group;       /* group this enumerator is bound to */
+    PRThread *thread;               /* thread in midst of an enumeration */
+    _PREnumSeal seal;               /* trying to detect deleted objects */
+    PRUint32 p_timestamp;           /* when enumeration was (re)started */
+    PRRecvWait **waiter;            /* pointer into hash table */
+    PRUintn index;                  /* position in hash table */
+    void *pad[4];                   /* some room to grow */
+};
+
+#endif /* defined(_PPRMWAIT_H) */
+
+/* pprmwait.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprthred.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprthred.h
new file mode 100644
index 0000000..fe8ae50
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/pprthred.h
@@ -0,0 +1,363 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef pprthred_h___
+#define pprthred_h___
+
+/*
+** API for PR private functions.  These calls are to be used by internal
+** developers only.
+*/
+#include "nspr.h"
+
+#if defined(XP_OS2)
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_WIN
+#include <os2.h>
+#endif
+
+PR_BEGIN_EXTERN_C
+
+/*---------------------------------------------------------------------------
+** THREAD PRIVATE FUNCTIONS
+---------------------------------------------------------------------------*/
+
+/*
+** Associate a thread object with an existing native thread.
+** 	"type" is the type of thread object to attach
+** 	"priority" is the priority to assign to the thread
+** 	"stack" defines the shape of the threads stack
+**
+** This can return NULL if some kind of error occurs, or if memory is
+** tight. This call invokes "start(obj,arg)" and returns when the
+** function returns. The thread object is automatically destroyed.
+**
+** This call is not normally needed unless you create your own native
+** thread. PR_Init does this automatically for the primordial thread.
+*/
+NSPR_API(PRThread*) PR_AttachThread(PRThreadType type,
+                                     PRThreadPriority priority,
+				     PRThreadStack *stack);
+
+/*
+** Detach the nspr thread from the currently executing native thread.
+** The thread object will be destroyed and all related data attached
+** to it. The exit procs will be invoked.
+**
+** This call is not normally needed unless you create your own native
+** thread. PR_Exit will automatially detach the nspr thread object
+** created by PR_Init for the primordial thread.
+**
+** This call returns after the nspr thread object is destroyed.
+*/
+NSPR_API(void) PR_DetachThread(void);
+
+/*
+** Get the id of the named thread. Each thread is assigned a unique id
+** when it is created or attached.
+*/
+NSPR_API(PRUint32) PR_GetThreadID(PRThread *thread);
+
+/*
+** Set the procedure that is called when a thread is dumped. The procedure
+** will be applied to the argument, arg, when called. Setting the procedure
+** to NULL effectively removes it.
+*/
+typedef void (*PRThreadDumpProc)(PRFileDesc *fd, PRThread *t, void *arg);
+NSPR_API(void) PR_SetThreadDumpProc(
+    PRThread* thread, PRThreadDumpProc dump, void *arg);
+
+/*
+** Get this thread's affinity mask.  The affinity mask is a 32 bit quantity
+** marking a bit for each processor this process is allowed to run on.
+** The processor mask is returned in the mask argument.
+** The least-significant-bit represents processor 0.
+**
+** Returns 0 on success, -1 on failure.
+*/
+NSPR_API(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask);
+
+/*
+** Set this thread's affinity mask.  
+**
+** Returns 0 on success, -1 on failure.
+*/
+NSPR_API(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask );
+
+/*
+** Set the default CPU Affinity mask.
+**
+*/
+NSPR_API(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask);
+
+/*
+** Show status of all threads to standard error output.
+*/
+NSPR_API(void) PR_ShowStatus(void);
+
+/*
+** Set thread recycle mode to on (1) or off (0)
+*/
+NSPR_API(void) PR_SetThreadRecycleMode(PRUint32 flag);
+
+
+/*---------------------------------------------------------------------------
+** THREAD PRIVATE FUNCTIONS FOR GARBAGE COLLECTIBLE THREADS           
+---------------------------------------------------------------------------*/
+
+/* 
+** Only Garbage collectible threads participate in resume all, suspend all and 
+** enumeration operations.  They are also different during creation when
+** platform specific action may be needed (For example, all Solaris GC able
+** threads are bound threads).
+*/
+
+/*
+** Same as PR_CreateThread except that the thread is marked as garbage
+** collectible.
+*/
+NSPR_API(PRThread*) PR_CreateThreadGCAble(PRThreadType type,
+				     void (*start)(void *arg),
+				     void *arg,
+				     PRThreadPriority priority,
+				     PRThreadScope scope,
+				     PRThreadState state,
+				     PRUint32 stackSize);
+
+/*
+** Same as PR_AttachThread except that the thread being attached is marked as 
+** garbage collectible.
+*/
+NSPR_API(PRThread*) PR_AttachThreadGCAble(PRThreadType type,
+					PRThreadPriority priority,
+					PRThreadStack *stack);
+
+/*
+** Mark the thread as garbage collectible.
+*/
+NSPR_API(void) PR_SetThreadGCAble(void);
+
+/*
+** Unmark the thread as garbage collectible.
+*/
+NSPR_API(void) PR_ClearThreadGCAble(void);
+
+/*
+** This routine prevents all other GC able threads from running. This call is needed by 
+** the garbage collector.
+*/
+NSPR_API(void) PR_SuspendAll(void);
+
+/*
+** This routine unblocks all other GC able threads that were suspended from running by 
+** PR_SuspendAll(). This call is needed by the garbage collector.
+*/
+NSPR_API(void) PR_ResumeAll(void);
+
+/*
+** Return the thread stack pointer of the given thread. 
+** Needed by the garbage collector.
+*/
+NSPR_API(void *) PR_GetSP(PRThread *thread);
+
+/*
+** Save the registers that the GC would find interesting into the thread
+** "t". isCurrent will be non-zero if the thread state that is being
+** saved is the currently executing thread. Return the address of the
+** first register to be scanned as well as the number of registers to
+** scan in "np".
+**
+** If "isCurrent" is non-zero then it is allowed for the thread context
+** area to be used as scratch storage to hold just the registers
+** necessary for scanning.
+**
+** This function simply calls the internal function _MD_HomeGCRegisters().
+*/
+NSPR_API(PRWord *) PR_GetGCRegisters(PRThread *t, int isCurrent, int *np);
+
+/*
+** (Get|Set)ExecutionEnvironent
+**
+** Used by Java to associate it's execution environment so garbage collector
+** can find it. If return is NULL, then it's probably not a collectable thread.
+**
+** There's no locking required around these calls.
+*/
+NSPR_API(void*) GetExecutionEnvironment(PRThread *thread);
+NSPR_API(void) SetExecutionEnvironment(PRThread* thread, void *environment);
+
+/*
+** Enumeration function that applies "func(thread,i,arg)" to each active
+** thread in the process. The enumerator returns PR_SUCCESS if the enumeration
+** should continue, any other value is considered failure, and enumeration
+** stops, returning the failure value from PR_EnumerateThreads.
+** Needed by the garbage collector.
+*/
+typedef PRStatus (PR_CALLBACK *PREnumerator)(PRThread *t, int i, void *arg);
+NSPR_API(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg);
+
+/* 
+** Signature of a thread stack scanning function. It is applied to every
+** contiguous group of potential pointers within a thread. Count denotes the
+** number of pointers. 
+*/
+typedef PRStatus 
+(PR_CALLBACK *PRScanStackFun)(PRThread* t,
+			      void** baseAddr, PRUword count, void* closure);
+
+/*
+** Applies scanFun to all contiguous groups of potential pointers 
+** within a thread. This includes the stack, registers, and thread-local
+** data. If scanFun returns a status value other than PR_SUCCESS the scan
+** is aborted, and the status value is returned. 
+*/
+NSPR_API(PRStatus)
+PR_ThreadScanStackPointers(PRThread* t,
+                           PRScanStackFun scanFun, void* scanClosure);
+
+/* 
+** Calls PR_ThreadScanStackPointers for every thread.
+*/
+NSPR_API(PRStatus)
+PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure);
+
+/*
+** Returns a conservative estimate on the amount of stack space left
+** on a thread in bytes, sufficient for making decisions about whether 
+** to continue recursing or not.
+*/
+NSPR_API(PRUword)
+PR_GetStackSpaceLeft(PRThread* t);
+
+/*---------------------------------------------------------------------------
+** THREAD CPU PRIVATE FUNCTIONS             
+---------------------------------------------------------------------------*/
+
+/*
+** Get a pointer to the primordial CPU.
+*/
+NSPR_API(struct _PRCPU *) _PR_GetPrimordialCPU(void);
+
+/*---------------------------------------------------------------------------
+** THREAD SYNCHRONIZATION PRIVATE FUNCTIONS
+---------------------------------------------------------------------------*/
+
+/*
+** Create a new named monitor (named for debugging purposes).
+**  Monitors are re-entrant locks with a built-in condition variable.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low.
+*/
+NSPR_API(PRMonitor*) PR_NewNamedMonitor(const char* name);
+
+/*
+** Test and then lock the lock if it's not already locked by some other
+** thread. Return PR_FALSE if some other thread owned the lock at the
+** time of the call.
+*/
+NSPR_API(PRBool) PR_TestAndLock(PRLock *lock);
+
+/*
+** Test and then enter the mutex associated with the monitor if it's not
+** already entered by some other thread. Return PR_FALSE if some other
+** thread owned the mutex at the time of the call.
+*/
+NSPR_API(PRBool) PR_TestAndEnterMonitor(PRMonitor *mon);
+
+/*
+** Return the number of times that the current thread has entered the
+** mutex. Returns zero if the current thread has not entered the mutex.
+*/
+NSPR_API(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon);
+
+/*
+** Just like PR_CEnterMonitor except that if the monitor is owned by
+** another thread NULL is returned.
+*/
+NSPR_API(PRMonitor*) PR_CTestAndEnterMonitor(void *address);
+
+/*---------------------------------------------------------------------------
+** PLATFORM-SPECIFIC INITIALIZATION FUNCTIONS
+---------------------------------------------------------------------------*/
+#if defined(IRIX)
+/*
+** Irix specific initialization funtion to be called before PR_Init
+** is called by the application. Sets the CONF_INITUSERS and CONF_INITSIZE
+** attributes of the shared arena set up by nspr.
+**
+** The environment variables _NSPR_IRIX_INITUSERS and _NSPR_IRIX_INITSIZE
+** can also be used to set these arena attributes. If _NSPR_IRIX_INITUSERS
+** is set, but not _NSPR_IRIX_INITSIZE, the value of the CONF_INITSIZE
+** attribute of the nspr arena is scaled as a function of the
+** _NSPR_IRIX_INITUSERS value.
+** 
+** If the _PR_Irix_Set_Arena_Params() is called in addition to setting the
+** environment variables, the values of the environment variables are used.
+** 
+*/
+NSPR_API(void) _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize);
+
+#endif /* IRIX */
+
+#if defined(XP_OS2)
+/*
+** These functions need to be called at the start and end of a thread.
+** An EXCEPTIONREGISTRATIONRECORD must be declared on the stack and its
+** address passed to the two functions.
+*/
+NSPR_API(void) PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* e);
+NSPR_API(void) PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* e);
+#endif /* XP_OS2 */
+
+/* I think PR_GetMonitorEntryCount is useless. All you really want is this... */
+#define PR_InMonitor(m)		(PR_GetMonitorEntryCount(m) > 0)
+
+/*---------------------------------------------------------------------------
+** Special X-Lock hack for client
+---------------------------------------------------------------------------*/
+
+#ifdef XP_UNIX
+extern void PR_XLock(void);
+extern void PR_XUnlock(void);
+extern PRBool PR_XIsLocked(void);
+#endif /* XP_UNIX */
+
+PR_END_EXTERN_C
+
+#endif /* pprthred_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/private/primpl.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/primpl.h
new file mode 100644
index 0000000..6675e40
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/primpl.h
@@ -0,0 +1,2141 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef primpl_h___
+#define primpl_h___
+
+/*
+ * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which
+ * has:
+ *     #define sigaction _sigaction_sys
+ * This macro causes chaos if signal.h gets included before pthread.h.
+ * To be safe, we include pthread.h first.
+ */
+
+#if defined(_PR_PTHREADS)
+#include <pthread.h>
+#endif
+
+#if defined(_PR_BTHREADS)
+#include <kernel/OS.h>
+#endif
+
+#ifdef WIN32
+/*
+ * Allow use of functions and symbols first defined in Win2k.
+ */
+#if !defined(WINVER) || (WINVER < 0x0500)
+#undef WINVER
+#define WINVER 0x0500
+#endif
+#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+#endif /* WIN32 */
+
+#include "nspr.h"
+#include "prpriv.h"
+
+typedef struct PRSegment PRSegment;
+
+#include "md/prosdep.h"
+#include "obsolete/probslet.h"
+
+#ifdef _PR_HAVE_POSIX_SEMAPHORES
+#include <semaphore.h>
+#elif defined(_PR_HAVE_SYSV_SEMAPHORES)
+#include <sys/sem.h>
+#endif
+
+/*************************************************************************
+*****  A Word about Model Dependent Function Naming Convention ***********
+*************************************************************************/
+
+/*
+NSPR 2.0 must implement its function across a range of platforms 
+including: MAC, Windows/16, Windows/95, Windows/NT, and several
+variants of Unix. Each implementation shares common code as well 
+as having platform dependent portions. This standard describes how
+the model dependent portions are to be implemented.
+
+In header file pr/include/primpl.h, each publicly declared 
+platform dependent function is declared as:
+
+NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 );
+#define _PR_MD_FUNCTION _MD_FUNCTION
+
+In header file pr/include/md/<platform>/_<platform>.h, 
+each #define'd macro is redefined as one of:
+
+#define _MD_FUNCTION <blanks>
+#define _MD_FUNCTION <expanded macro>
+#define _MD_FUNCTION <osFunction>
+#define _MD_FUNCTION <_MD_Function>
+
+Where:
+
+<blanks> is no definition at all. In this case, the function is not implemented 
+and is never called for this platform. 
+For example: 
+#define _MD_INIT_CPUS()
+
+<expanded macro> is a C language macro expansion. 
+For example: 
+#define        _MD_CLEAN_THREAD(_thread) \
+    PR_BEGIN_MACRO \
+        PR_DestroyCondVar(_thread->md.asyncIOCVar); \
+        PR_DestroyLock(_thread->md.asyncIOLock); \
+    PR_END_MACRO
+
+<osFunction> is some function implemented by the host operating system. 
+For example: 
+#define _MD_EXIT        exit
+
+<_MD_function> is the name of a function implemented for this platform in 
+pr/src/md/<platform>/<soruce>.c file. 
+For example: 
+#define        _MD_GETFILEINFO         _MD_GetFileInfo
+
+In <source>.c, the implementation is:
+PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info);
+*/
+
+PR_BEGIN_EXTERN_C
+
+typedef struct _MDLock _MDLock;
+typedef struct _MDCVar _MDCVar;
+typedef struct _MDSegment _MDSegment;
+typedef struct _MDThread _MDThread;
+typedef struct _MDThreadStack _MDThreadStack;
+typedef struct _MDSemaphore _MDSemaphore;
+typedef struct _MDDir _MDDir;
+#ifdef MOZ_UNICODE
+typedef struct _MDDirUTF16 _MDDirUTF16;
+#endif /* MOZ_UNICODE */
+typedef struct _MDFileDesc _MDFileDesc;
+typedef struct _MDProcess _MDProcess;
+typedef struct _MDFileMap _MDFileMap;
+
+#if defined(_PR_PTHREADS)
+
+/*
+** The following definitions are unique to implementing NSPR using pthreads.
+** Since pthreads defines most of the thread and thread synchronization
+** stuff, this is a pretty small set.
+*/
+
+#define PT_CV_NOTIFIED_LENGTH 6
+typedef struct _PT_Notified _PT_Notified;
+struct _PT_Notified
+{
+    PRIntn length;              /* # of used entries in this structure */
+    struct
+    {
+        PRCondVar *cv;          /* the condition variable notified */
+        PRIntn times;           /* and the number of times notified */
+    } cv[PT_CV_NOTIFIED_LENGTH];
+    _PT_Notified *link;         /* link to another of these | NULL */
+};
+
+/*
+ * bits defined for pthreads 'state' field 
+ */
+#define PT_THREAD_DETACHED  0x01    /* thread can't be joined */
+#define PT_THREAD_GLOBAL    0x02    /* a global thread (unlikely) */
+#define PT_THREAD_SYSTEM    0x04    /* system (not user) thread */
+#define PT_THREAD_PRIMORD   0x08    /* this is the primordial thread */
+#define PT_THREAD_ABORTED   0x10    /* thread has been interrupted */
+#define PT_THREAD_GCABLE    0x20    /* thread is garbage collectible */
+#define PT_THREAD_SUSPENDED 0x40    /* thread has been suspended */
+#define PT_THREAD_FOREIGN   0x80    /* thread is not one of ours */
+#define PT_THREAD_BOUND     0x100    /* a bound-global thread */
+
+#define _PT_THREAD_INTERRUPTED(thr)					\
+		(!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED))
+#define _PT_THREAD_BLOCK_INTERRUPT(thr)				\
+		(thr->interrupt_blocked = 1)
+#define _PT_THREAD_UNBLOCK_INTERRUPT(thr)			\
+		(thr->interrupt_blocked = 0)
+
+#ifdef GC_LEAK_DETECTOR
+/* All threads are GCable. */
+#define _PT_IS_GCABLE_THREAD(thr) 1
+#else
+#define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE)
+#endif /* GC_LEAK_DETECTOR */
+
+/* 
+** Possible values for thread's suspend field
+** Note that the first two can be the same as they are really mutually exclusive,
+** i.e. both cannot be happening at the same time. We have two symbolic names
+** just as a mnemonic.
+**/
+#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 locks_created, locks_destroyed;
+    PRUintn locks_acquired, locks_released;
+    PRUintn cvars_created, cvars_destroyed;
+    PRUintn cvars_notified, delayed_cv_deletes;
+} PTDebug;
+
+#endif /* defined(DEBUG) */
+
+NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
+
+#else /* defined(_PR_PTHREADS) */
+
+NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
+
+/*
+** This section is contains those parts needed to implement NSPR on
+** platforms in general. One would assume that the pthreads implementation
+** included lots of the same types, at least conceptually.
+*/
+
+/*
+ * Local threads only.  No multiple CPU support and hence all the
+ * following routines are no-op.
+ */
+#ifdef _PR_LOCAL_THREADS_ONLY
+
+#define        _PR_MD_SUSPEND_THREAD(thread)        
+#define        _PR_MD_RESUME_THREAD(thread)        
+#define        _PR_MD_SUSPEND_CPU(cpu)        
+#define        _PR_MD_RESUME_CPU(cpu)        
+#define        _PR_MD_BEGIN_SUSPEND_ALL()        
+#define        _PR_MD_END_SUSPEND_ALL()        
+#define        _PR_MD_BEGIN_RESUME_ALL()        
+#define        _PR_MD_END_RESUME_ALL()
+#define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE
+
+#endif
+
+typedef struct _PRCPUQueue _PRCPUQueue;
+typedef struct _PRCPU _PRCPU;
+typedef struct _MDCPU _MDCPU;
+
+struct _PRCPUQueue {
+    _MDLock  runQLock;          /* lock for the run + wait queues */
+    _MDLock  sleepQLock;        /* lock for the run + wait queues */
+    _MDLock  miscQLock;         /* lock for the run + wait queues */
+
+    PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */
+    PRUint32  runQReadyMask;
+    PRCList sleepQ;
+    PRIntervalTime sleepQmax;
+    PRCList pauseQ;
+    PRCList suspendQ;
+    PRCList waitingToJoinQ;
+
+    PRUintn   numCPUs;          /* number of CPUs using this Q */
+};
+
+struct _PRCPU {
+    PRCList links;              /* link list of CPUs */
+    PRUint32 id;                /* id for this CPU */
+
+    union {
+        PRInt32 bits;
+        PRUint8 missed[4];
+    } u;
+    PRIntn where;               /* index into u.missed */
+    PRPackedBool paused;        /* cpu is paused */
+    PRPackedBool exit;          /* cpu should exit */
+
+    PRThread *thread;           /* native thread for this CPUThread */
+    PRThread *idle_thread;      /* user-level idle thread for this CPUThread */
+
+    PRIntervalTime last_clock;  /* the last time we went into 
+                                 * _PR_ClockInterrupt() on this CPU
+                                 */
+
+    _PRCPUQueue *queue;
+
+    _MDCPU md;
+};
+
+typedef struct _PRInterruptTable {
+    const char *name;
+    PRUintn missed_bit;
+    void (*handler)(void);
+} _PRInterruptTable;
+
+#define _PR_CPU_PTR(_qp) \
+    ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links)))
+
+#if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \
+        && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
+#define _MD_GET_ATTACHED_THREAD()        (_PR_MD_CURRENT_THREAD())
+#endif
+
+#ifdef _PR_LOCAL_THREADS_ONLY 
+
+NSPR_API(struct _PRCPU *)              _pr_currentCPU;
+NSPR_API(PRThread *)                   _pr_currentThread;
+NSPR_API(PRThread *)                   _pr_lastThread;
+NSPR_API(PRInt32)                      _pr_intsOff;
+
+#define _MD_CURRENT_CPU()               (_pr_currentCPU)
+#define _MD_SET_CURRENT_CPU(_cpu)       (_pr_currentCPU = (_cpu))
+#define _MD_CURRENT_THREAD()            (_pr_currentThread)
+#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
+#define _MD_LAST_THREAD()               (_pr_lastThread)
+#define _MD_SET_LAST_THREAD(t)          (_pr_lastThread = t)
+
+#define _MD_GET_INTSOFF()               (_pr_intsOff)
+#define _MD_SET_INTSOFF(_val)           (_pr_intsOff = _val)
+
+
+/* The unbalanced curly braces in these two macros are intentional */
+#define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is);
+#define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); }
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+extern PRInt32                  _native_threads_only;
+
+#if defined(_PR_GLOBAL_THREADS_ONLY)
+
+#define _MD_GET_INTSOFF() 0
+#define _MD_SET_INTSOFF(_val)
+#define _PR_INTSOFF(_is)
+#define _PR_FAST_INTSON(_is)
+#define _PR_INTSON(_is)
+#define _PR_THREAD_LOCK(_thread)
+#define _PR_THREAD_UNLOCK(_thread)
+#define _PR_RUNQ_LOCK(cpu)
+#define _PR_RUNQ_UNLOCK(cpu)
+#define _PR_SLEEPQ_LOCK(thread)
+#define _PR_SLEEPQ_UNLOCK(thread)
+#define _PR_MISCQ_LOCK(thread)
+#define _PR_MISCQ_UNLOCK(thread)
+#define _PR_CPU_LIST_LOCK()
+#define _PR_CPU_LIST_UNLOCK()
+
+#define _PR_ADD_RUNQ(_thread, _cpu, _pri)
+#define _PR_DEL_RUNQ(_thread)
+#define _PR_ADD_SLEEPQ(_thread, _timeout)
+#define _PR_DEL_SLEEPQ(_thread, _propogate)
+#define _PR_ADD_JOINQ(_thread, _cpu)
+#define _PR_DEL_JOINQ(_thread)
+#define _PR_ADD_SUSPENDQ(_thread, _cpu)
+#define _PR_DEL_SUSPENDQ(_thread)
+
+#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
+
+#define _PR_IS_NATIVE_THREAD(thread) 1
+#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
+
+#else
+
+#define _PR_INTSOFF(_is) \
+    PR_BEGIN_MACRO \
+        (_is) = _PR_MD_GET_INTSOFF(); \
+        _PR_MD_SET_INTSOFF(1); \
+    PR_END_MACRO
+
+#define _PR_FAST_INTSON(_is) \
+    PR_BEGIN_MACRO \
+        _PR_MD_SET_INTSOFF(_is); \
+    PR_END_MACRO
+
+#define _PR_INTSON(_is) \
+    PR_BEGIN_MACRO \
+        if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \
+                _PR_IntsOn((_PR_MD_CURRENT_CPU())); \
+        _PR_MD_SET_INTSOFF(_is); \
+    PR_END_MACRO
+
+#ifdef _PR_LOCAL_THREADS_ONLY 
+
+#define _PR_IS_NATIVE_THREAD(thread) 0
+#define _PR_THREAD_LOCK(_thread)
+#define _PR_THREAD_UNLOCK(_thread)
+#define _PR_RUNQ_LOCK(cpu)
+#define _PR_RUNQ_UNLOCK(cpu)
+#define _PR_SLEEPQ_LOCK(thread)
+#define _PR_SLEEPQ_UNLOCK(thread)
+#define _PR_MISCQ_LOCK(thread)
+#define _PR_MISCQ_UNLOCK(thread)
+#define _PR_CPU_LIST_LOCK()
+#define _PR_CPU_LIST_UNLOCK()
+
+#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
+    PR_BEGIN_MACRO \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
+    _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
+    PR_END_MACRO
+
+#define _PR_DEL_RUNQ(_thread) \
+    PR_BEGIN_MACRO \
+    _PRCPU *_cpu = _thread->cpu; \
+    PRInt32 _pri = _thread->priority; \
+    PR_REMOVE_LINK(&(_thread)->links); \
+    if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
+        _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
+    PR_END_MACRO
+
+#define _PR_ADD_SLEEPQ(_thread, _timeout) \
+    _PR_AddSleepQ(_thread, _timeout);   
+
+#define _PR_DEL_SLEEPQ(_thread, _propogate) \
+    _PR_DelSleepQ(_thread, _propogate);  
+
+#define _PR_ADD_JOINQ(_thread, _cpu) \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
+
+#define _PR_DEL_JOINQ(_thread) \
+    PR_REMOVE_LINK(&(_thread)->links);
+
+#define _PR_ADD_SUSPENDQ(_thread, _cpu) \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
+
+#define _PR_DEL_SUSPENDQ(_thread) \
+    PR_REMOVE_LINK(&(_thread)->links);
+
+#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
+
+#define _PR_IS_NATIVE_THREAD_SUPPORTED() 0
+
+#else        /* _PR_LOCAL_THREADS_ONLY */
+
+/* These are for the "combined" thread model */
+
+#define _PR_THREAD_LOCK(_thread) \
+    _PR_MD_LOCK(&(_thread)->threadLock);
+
+#define _PR_THREAD_UNLOCK(_thread) \
+    _PR_MD_UNLOCK(&(_thread)->threadLock);
+
+#define _PR_RUNQ_LOCK(_cpu) \
+    PR_BEGIN_MACRO \
+    _PR_MD_LOCK(&(_cpu)->queue->runQLock );\
+    PR_END_MACRO
+    
+#define _PR_RUNQ_UNLOCK(_cpu) \
+    PR_BEGIN_MACRO \
+    _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\
+    PR_END_MACRO
+
+#define _PR_SLEEPQ_LOCK(_cpu) \
+    _PR_MD_LOCK(&(_cpu)->queue->sleepQLock );
+
+#define _PR_SLEEPQ_UNLOCK(_cpu) \
+    _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock );
+
+#define _PR_MISCQ_LOCK(_cpu) \
+    _PR_MD_LOCK(&(_cpu)->queue->miscQLock );
+
+#define _PR_MISCQ_UNLOCK(_cpu) \
+    _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock );
+
+#define _PR_CPU_LIST_LOCK()                 _PR_MD_LOCK(&_pr_cpuLock)
+#define _PR_CPU_LIST_UNLOCK()               _PR_MD_UNLOCK(&_pr_cpuLock)
+
+#define QUEUE_RUN           0x1
+#define QUEUE_SLEEP         0x2
+#define QUEUE_JOIN          0x4
+#define QUEUE_SUSPEND       0x8
+#define QUEUE_LOCK          0x10
+
+#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
+    PR_BEGIN_MACRO \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
+    _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
+    PR_ASSERT((_thread)->queueCount == 0); \
+    (_thread)->queueCount = QUEUE_RUN; \
+    PR_END_MACRO
+
+#define _PR_DEL_RUNQ(_thread) \
+    PR_BEGIN_MACRO \
+    _PRCPU *_cpu = _thread->cpu; \
+    PRInt32 _pri = _thread->priority; \
+    PR_REMOVE_LINK(&(_thread)->links); \
+    if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
+        _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
+    PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\
+    (_thread)->queueCount = 0; \
+    PR_END_MACRO
+
+#define _PR_ADD_SLEEPQ(_thread, _timeout) \
+    PR_ASSERT((_thread)->queueCount == 0); \
+    (_thread)->queueCount = QUEUE_SLEEP; \
+    _PR_AddSleepQ(_thread, _timeout);  
+
+#define _PR_DEL_SLEEPQ(_thread, _propogate) \
+    PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\
+    (_thread)->queueCount = 0; \
+    _PR_DelSleepQ(_thread, _propogate);  
+
+#define _PR_ADD_JOINQ(_thread, _cpu) \
+    PR_ASSERT((_thread)->queueCount == 0); \
+    (_thread)->queueCount = QUEUE_JOIN; \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
+
+#define _PR_DEL_JOINQ(_thread) \
+    PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\
+    (_thread)->queueCount = 0; \
+    PR_REMOVE_LINK(&(_thread)->links);
+
+#define _PR_ADD_SUSPENDQ(_thread, _cpu) \
+    PR_ASSERT((_thread)->queueCount == 0); \
+    (_thread)->queueCount = QUEUE_SUSPEND; \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
+
+#define _PR_DEL_SUSPENDQ(_thread) \
+    PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\
+    (_thread)->queueCount = 0; \
+    PR_REMOVE_LINK(&(_thread)->links);
+
+#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \
+    (_thread)->cpu = (_newCPU);
+
+#define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE)
+#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+#endif /* _PR_GLOBAL_THREADS_ONLY */
+
+#define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1
+#define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0
+
+extern _PRInterruptTable _pr_interruptTable[];
+
+/* Bits for _pr_interruptState.u.missed[0,1] */
+#define _PR_MISSED_CLOCK    0x1
+#define _PR_MISSED_IO        0x2
+#define _PR_MISSED_CHILD    0x4
+
+extern void _PR_IntsOn(_PRCPU *cpu);
+
+NSPR_API(void) _PR_WakeupCPU(void);
+NSPR_API(void) _PR_PauseCPU(void);
+
+/************************************************************************/
+
+#define _PR_LOCK_LOCK(_lock) \
+    _PR_MD_LOCK(&(_lock)->ilock);
+#define _PR_LOCK_UNLOCK(_lock) \
+    _PR_MD_UNLOCK(&(_lock)->ilock);
+    
+extern void _PR_UnblockLockWaiter(PRLock *lock);
+
+#define _PR_LOCK_PTR(_qp) \
+    ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
+
+/************************************************************************/
+
+#define _PR_CVAR_LOCK(_cvar) \
+    _PR_MD_LOCK(&(_cvar)->ilock); 
+#define _PR_CVAR_UNLOCK(_cvar) \
+    _PR_MD_UNLOCK(&(_cvar)->ilock);
+
+extern PRStatus _PR_WaitCondVar(
+    PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
+extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
+
+NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
+
+/* PRThread.flags */
+#define _PR_SYSTEM          0x01
+#define _PR_INTERRUPT       0x02
+#define _PR_ATTACHED        0x04        /* created via PR_AttachThread */
+#define _PR_PRIMORDIAL      0x08        /* the thread that called PR_Init */
+#define _PR_ON_SLEEPQ       0x10        /* thread is on the sleepQ */
+#define _PR_ON_PAUSEQ       0x20        /* thread is on the pauseQ */
+#define _PR_SUSPENDING      0x40        /* thread wants to suspend */
+#define _PR_GLOBAL_SCOPE    0x80        /* thread is global scope */
+#define _PR_IDLE_THREAD     0x200       /* this is an idle thread        */
+#define _PR_GCABLE_THREAD   0x400       /* this is a collectable thread */
+#define _PR_BOUND_THREAD    0x800       /* a bound thread */
+#define _PR_INTERRUPT_BLOCKED	0x1000	/* interrupts blocked */
+
+/* PRThread.state */
+#define _PR_UNBORN       0
+#define _PR_RUNNABLE     1
+#define _PR_RUNNING      2
+#define _PR_LOCK_WAIT    3
+#define _PR_COND_WAIT    4
+#define _PR_JOIN_WAIT    5
+#define _PR_IO_WAIT      6
+#define _PR_SUSPENDED    7
+#define _PR_DEAD_STATE   8  /* for debugging */
+
+/* PRThreadStack.flags */
+#define _PR_STACK_VM            0x1    /* using vm instead of malloc */
+#define _PR_STACK_MAPPED        0x2    /* vm is mapped */
+#define _PR_STACK_PRIMORDIAL    0x4    /* stack for primordial thread */
+
+/* 
+** If the default stcksize from the client is zero, we need to pick a machine
+** dependent value.  This is only for standard user threads.  For custom threads,
+** 0 has a special meaning.
+** Adjust stackSize. Round up to a page boundary.
+*/
+
+#ifndef _MD_MINIMUM_STACK_SIZE
+#define _MD_MINIMUM_STACK_SIZE	0
+#endif
+
+#if (!defined(HAVE_CUSTOM_USER_THREADS))
+#define        _PR_ADJUST_STACKSIZE(stackSize) \
+        PR_BEGIN_MACRO \
+    if (stackSize == 0) \
+                stackSize = _MD_DEFAULT_STACK_SIZE; \
+    if (stackSize < _MD_MINIMUM_STACK_SIZE) \
+                stackSize = _MD_MINIMUM_STACK_SIZE; \
+    stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \
+    stackSize <<= _pr_pageShift; \
+        PR_END_MACRO
+#else
+#define        _PR_ADJUST_STACKSIZE(stackSize)
+#endif
+
+#ifdef GC_LEAK_DETECTOR
+/* All threads are GCable. */
+#define _PR_IS_GCABLE_THREAD(thr) 1
+#else
+#define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD)
+#endif /* GC_LEAK_DETECTOR */
+
+#define _PR_PENDING_INTERRUPT(thr)					\
+		(!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT))
+#define _PR_THREAD_BLOCK_INTERRUPT(thr)			\
+		(thr->flags |= _PR_INTERRUPT_BLOCKED)
+#define _PR_THREAD_UNBLOCK_INTERRUPT(thr)			\
+		(thr->flags &= ~_PR_INTERRUPT_BLOCKED)
+
+#define _PR_THREAD_PTR(_qp) \
+    ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links)))
+
+#define _PR_ACTIVE_THREAD_PTR(_qp) \
+    ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active)))
+
+#define _PR_THREAD_CONDQ_PTR(_qp) \
+    ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks)))
+
+#define _PR_THREAD_MD_TO_PTR(_md) \
+    ((PRThread*) ((char*) (_md) - offsetof(PRThread,md)))
+
+#define _PR_THREAD_STACK_TO_PTR(_stack) \
+    ((PRThread*) (_stack->thr))
+
+extern PRCList _pr_active_local_threadQ;
+extern PRCList _pr_active_global_threadQ;
+extern PRCList _pr_cpuQ;
+extern _MDLock  _pr_cpuLock;
+extern PRInt32 _pr_md_idle_cpus;
+
+#define _PR_ACTIVE_LOCAL_THREADQ()          _pr_active_local_threadQ
+#define _PR_ACTIVE_GLOBAL_THREADQ()         _pr_active_global_threadQ
+#define _PR_CPUQ()                          _pr_cpuQ
+#define _PR_RUNQ(_cpu)                      ((_cpu)->queue->runQ)
+#define _PR_RUNQREADYMASK(_cpu)             ((_cpu)->queue->runQReadyMask)
+#define _PR_SLEEPQ(_cpu)                    ((_cpu)->queue->sleepQ)
+#define _PR_SLEEPQMAX(_cpu)                 ((_cpu)->queue->sleepQmax)
+#define _PR_PAUSEQ(_cpu)                    ((_cpu)->queue->pauseQ)
+#define _PR_SUSPENDQ(_cpu)                  ((_cpu)->queue->suspendQ)
+#define _PR_WAITINGTOJOINQ(_cpu)            ((_cpu)->queue->waitingToJoinQ)
+
+extern PRUint32 _pr_recycleThreads;   /* Flag for behavior on thread cleanup */
+extern PRLock *_pr_deadQLock;
+extern PRUint32 _pr_numNativeDead;
+extern PRUint32 _pr_numUserDead;
+extern PRCList _pr_deadNativeQ;
+extern PRCList _pr_deadUserQ;
+#define _PR_DEADNATIVEQ     _pr_deadNativeQ
+#define _PR_DEADUSERQ       _pr_deadUserQ
+#define _PR_DEADQ_LOCK      PR_Lock(_pr_deadQLock);
+#define _PR_DEADQ_UNLOCK    PR_Unlock(_pr_deadQLock);
+#define _PR_INC_DEADNATIVE  (_pr_numNativeDead++)
+#define _PR_DEC_DEADNATIVE  (_pr_numNativeDead--)
+#define _PR_NUM_DEADNATIVE  (_pr_numNativeDead)
+#define _PR_INC_DEADUSER    (_pr_numUserDead++)
+#define _PR_DEC_DEADUSER    (_pr_numUserDead--)
+#define _PR_NUM_DEADUSER    (_pr_numUserDead)
+
+extern PRUint32 _pr_utid;
+
+extern struct _PRCPU  *_pr_primordialCPU;
+
+extern PRLock *_pr_activeLock;          /* lock for userActive and systemActive */
+extern PRInt32 _pr_userActive;          /* number of active user threads */
+extern PRInt32 _pr_systemActive;        /* number of active system threads */
+extern PRInt32 _pr_primordialExitCount; /* number of user threads left
+                                         * before the primordial thread
+                                         * can exit.  */
+extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for
+                                           * notifying the primordial thread
+                                           * when all other user threads
+                                           * have terminated.  */
+
+extern PRUintn _pr_maxPTDs;
+
+extern PRLock *_pr_terminationCVLock;
+
+/*************************************************************************
+* Internal routines either called by PR itself or from machine-dependent *
+* code.                                                                  *
+*************************************************************************/
+
+extern void _PR_ClockInterrupt(void);
+
+extern void _PR_Schedule(void);
+extern void _PR_SetThreadPriority(
+    PRThread* thread, PRThreadPriority priority);
+
+/***********************************************************************
+** FUNCTION:	_PR_NewSegment()
+** DESCRIPTION:
+**   Allocate a memory segment. The "size" value is rounded up to the
+**   native system page size and a page aligned portion of memory is
+**   returned.  This memory is not part of the malloc heap. If "vaddr" is
+**   not NULL then PR tries to allocate the segment at the desired virtual
+**   address.
+** INPUTS:	size:  size of the desired memory segment
+**          vaddr:  address at which the newly aquired segment is to be
+**                  mapped into memory.
+** OUTPUTS:	a memory segment is allocated, a PRSegment is allocated
+** RETURN:	pointer to PRSegment
+***********************************************************************/
+extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr);
+
+/***********************************************************************
+** FUNCTION:	_PR_DestroySegment()
+** DESCRIPTION:
+**   The memory segment and the PRSegment are freed
+** INPUTS:	seg:  pointer to PRSegment to be freed
+** OUTPUTS:	the the PRSegment and its associated memory segment are freed
+** RETURN:	void
+***********************************************************************/
+extern void _PR_DestroySegment(PRSegment *seg);
+
+extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
+extern void _PR_FreeStack(PRThreadStack *stack);
+extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
+extern void _PR_NotifyLockedThread (PRThread *thread);
+
+NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
+NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
+
+extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread);
+
+NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type,
+                                     void (*start)(void *arg),
+                                     void *arg,
+                                     PRThreadPriority priority,
+                                     PRThreadScope scope,
+                                     PRThreadState state,
+                                     PRUint32 stackSize,
+                     PRUint32 flags);
+
+extern void _PR_NativeDestroyThread(PRThread *thread);
+extern void _PR_UserDestroyThread(PRThread *thread);
+
+extern PRThread* _PRI_AttachThread(
+    PRThreadType type, PRThreadPriority priority,
+    PRThreadStack *stack, PRUint32 flags);
+
+extern void _PRI_DetachThread(void);
+
+
+#define _PR_IO_PENDING(_thread) ((_thread)->io_pending)
+
+NSPR_API(void) _PR_MD_INIT_CPUS();
+#define    _PR_MD_INIT_CPUS _MD_INIT_CPUS
+
+NSPR_API(void) _PR_MD_WAKEUP_CPUS();
+#define    _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS
+
+/* Interrupts related */
+
+NSPR_API(void) _PR_MD_START_INTERRUPTS(void);
+#define    _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS
+
+NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void);
+#define    _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS
+
+NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void);
+#define    _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS
+
+NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
+#define    _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS
+
+NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
+#define    _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS
+
+NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
+#define    _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS
+
+/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
+ * awaken a thread which is waiting on a lock or cvar.
+ */
+extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
+#define    _PR_MD_WAIT _MD_WAIT
+
+extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *);
+#define    _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
+
+#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
+NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void);
+#define    _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT
+#endif
+
+/* Stack debugging */
+NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
+#define    _PR_MD_INIT_STACK _MD_INIT_STACK
+
+NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
+#define    _PR_MD_CLEAR_STACK _MD_CLEAR_STACK
+
+/* CPU related */
+NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void);
+#define    _PR_MD_GET_INTSOFF _MD_GET_INTSOFF
+
+NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
+#define    _PR_MD_SET_INTSOFF _MD_SET_INTSOFF
+
+NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void);
+#define    _PR_MD_CURRENT_CPU _MD_CURRENT_CPU
+
+NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
+#define    _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU
+
+NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
+#define    _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU
+
+/*
+ * Returns the number of threads awoken or 0 if a timeout occurred;
+ */
+extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
+#define    _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
+
+extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
+#define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT
+
+extern void _PR_MD_EXIT(PRIntn status);
+#define    _PR_MD_EXIT _MD_EXIT
+
+/* Locks related */
+
+NSPR_API(void) _PR_MD_INIT_LOCKS(void);
+#define    _PR_MD_INIT_LOCKS _MD_INIT_LOCKS
+
+NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md);
+#define    _PR_MD_NEW_LOCK _MD_NEW_LOCK
+
+NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md);
+#define    _PR_MD_FREE_LOCK _MD_FREE_LOCK
+
+NSPR_API(void) _PR_MD_LOCK(_MDLock *md);
+#define    _PR_MD_LOCK _MD_LOCK
+
+/* Return 0 on success, a nonzero value on failure. */
+NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md);
+#define    _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK
+
+NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md);
+#define    _PR_MD_UNLOCK _MD_UNLOCK
+
+NSPR_API(void) _PR_MD_IOQ_LOCK(void);
+#define    _PR_MD_IOQ_LOCK _MD_IOQ_LOCK
+
+NSPR_API(void) _PR_MD_IOQ_UNLOCK(void);
+#define    _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK
+
+#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
+/* Semaphore related -- only for native threads */
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value);
+#define _PR_MD_NEW_SEM _MD_NEW_SEM
+
+NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md);
+#define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM
+
+NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM(
+    _MDSemaphore *md, PRIntervalTime timeout);
+#define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM
+
+NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md);
+#define _PR_MD_WAIT_SEM _MD_WAIT_SEM
+
+NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md);
+#define _PR_MD_POST_SEM _MD_POST_SEM
+#endif /* HAVE_CVAR_BUILT_ON_SEM */
+
+#endif
+
+/* Condition Variables related -- only for native threads */
+
+#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
+NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md);
+#define    _PR_MD_NEW_CV _MD_NEW_CV
+
+NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md);
+#define    _PR_MD_FREE_CV _MD_FREE_CV
+
+NSPR_API(void) _PR_MD_WAIT_CV(
+    _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout);
+#define    _PR_MD_WAIT_CV _MD_WAIT_CV
+
+NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock);
+#define    _PR_MD_NOTIFY_CV _MD_NOTIFY_CV
+
+NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock);
+#define    _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+/* Threads related */
+NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void);
+#define    _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD
+
+NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void);
+#define    _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD
+
+NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void);
+#define    _PR_MD_LAST_THREAD _MD_LAST_THREAD
+
+NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread);
+#define    _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD
+
+NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
+#define    _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD
+
+extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread);
+#define    _PR_MD_INIT_THREAD _MD_INIT_THREAD
+
+extern void _PR_MD_EXIT_THREAD(PRThread *thread);
+#define    _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
+
+#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
+
+NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
+#define    _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD
+
+extern void _PR_MD_SUSPEND_THREAD(PRThread *thread);
+#define    _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD
+
+extern void _PR_MD_RESUME_THREAD(PRThread *thread);
+#define    _PR_MD_RESUME_THREAD _MD_RESUME_THREAD
+
+extern void _PR_MD_SUSPEND_CPU(_PRCPU  *cpu);
+#define    _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU
+
+extern void _PR_MD_RESUME_CPU(_PRCPU  *cpu);
+#define    _PR_MD_RESUME_CPU _MD_RESUME_CPU
+
+extern void _PR_MD_BEGIN_SUSPEND_ALL(void);
+#define    _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL
+
+extern void _PR_MD_END_SUSPEND_ALL(void);
+#define    _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL
+
+extern void _PR_MD_BEGIN_RESUME_ALL(void);
+#define    _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL
+
+extern void _PR_MD_END_RESUME_ALL(void);
+#define    _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL
+
+#if defined(IRIX) 
+NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void);
+#endif        /* IRIX */
+
+#endif        /* !_PR_LOCAL_THREADS_ONLY */
+
+extern void _PR_MD_CLEAN_THREAD(PRThread *thread);
+#define    _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
+#define    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD
+
+extern PRThread* _PR_MD_CREATE_USER_THREAD(
+                        PRUint32 stacksize,
+                        void (*start)(void *),
+                        void *arg);
+#define    _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
+#endif
+
+extern PRStatus _PR_MD_CREATE_THREAD(
+                        PRThread *thread, 
+                        void (*start) (void *), 
+                        PRThreadPriority priority,                      
+                        PRThreadScope scope,
+                        PRThreadState state,
+                        PRUint32 stackSize);
+#define    _PR_MD_CREATE_THREAD _MD_CREATE_THREAD
+
+extern void _PR_MD_JOIN_THREAD(_MDThread *md);
+#define    _PR_MD_JOIN_THREAD _MD_JOIN_THREAD
+
+extern void _PR_MD_END_THREAD(void);
+#define    _PR_MD_END_THREAD _MD_END_THREAD
+
+extern void _PR_MD_YIELD(void);
+#define    _PR_MD_YIELD _MD_YIELD
+
+extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
+#define    _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
+
+NSPR_API(void) _PR_MD_SUSPENDALL(void);
+#define    _PR_MD_SUSPENDALL _MD_SUSPENDALL
+
+NSPR_API(void) _PR_MD_RESUMEALL(void);
+#define    _PR_MD_RESUMEALL _MD_RESUMEALL
+
+extern void _PR_MD_INIT_CONTEXT(
+    PRThread *thread, char *top, void (*start) (void), PRBool *status);
+#define    _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT
+
+extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread);
+#define    _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT
+
+extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread);
+#define    _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
+
+/* Segment related */
+extern void _PR_MD_INIT_SEGS(void);
+#define    _PR_MD_INIT_SEGS _MD_INIT_SEGS
+
+extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
+#define    _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT
+
+extern void _PR_MD_FREE_SEGMENT(PRSegment *seg);
+#define    _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT
+
+/* Directory enumeration related */
+extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name);
+#define    _PR_MD_OPEN_DIR _MD_OPEN_DIR
+
+extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags);
+#define    _PR_MD_READ_DIR _MD_READ_DIR
+
+extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md);
+#define    _PR_MD_CLOSE_DIR _MD_CLOSE_DIR
+
+/* Named semaphores related */
+extern PRSem * _PR_MD_OPEN_SEMAPHORE(
+    const char *osname, PRIntn flags, PRIntn mode, PRUintn value);
+#define    _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE
+
+extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem);
+#define    _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE
+
+extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem);
+#define    _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE
+
+extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem);
+#define    _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE
+
+extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname);
+#define    _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE
+
+/* I/O related */
+extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd);
+#define    _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC
+
+extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
+#define    _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
+
+/* File I/O related */
+extern PROsfd _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
+#define    _PR_MD_OPEN _MD_OPEN
+
+extern PROsfd _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(PROsfd 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
+
+extern PRInt32 _PR_MD_WRITEV(
+    PRFileDesc *fd, const struct PRIOVec *iov,
+    PRInt32 iov_size, PRIntervalTime timeout);
+#define    _PR_MD_WRITEV _MD_WRITEV
+
+extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd);
+#define    _PR_MD_FSYNC _MD_FSYNC
+
+extern PRInt32 _PR_MD_DELETE(const char *name);
+#define        _PR_MD_DELETE _MD_DELETE
+
+extern PRInt32 _PR_MD_RENAME(const char *from, const char *to);
+#define _PR_MD_RENAME _MD_RENAME
+
+extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how);
+#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
+
+#ifdef MOZ_UNICODE
+/* UTF16 File I/O related */
+extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name);
+#define    _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16
+
+extern PROsfd _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode);
+#define    _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16
+
+extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags);
+#define    _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16
+
+extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md);
+#define    _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16
+
+extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info);
+#define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16
+#endif /* MOZ_UNICODE */
+
+/* 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(PROsfd osfd);
+#define    _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET
+
+extern PRInt32 _PR_MD_CONNECT(
+    PRFileDesc *fd, const PRNetAddr *addr,
+    PRUint32 addrlen, PRIntervalTime timeout);
+#define    _PR_MD_CONNECT _MD_CONNECT
+
+extern PROsfd _PR_MD_ACCEPT(
+    PRFileDesc *fd, PRNetAddr *addr,
+    PRUint32 *addrlen, PRIntervalTime timeout);
+#define    _PR_MD_ACCEPT _MD_ACCEPT
+
+extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
+#define    _PR_MD_BIND _MD_BIND
+
+extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog);
+#define    _PR_MD_LISTEN _MD_LISTEN
+
+extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how);
+#define    _PR_MD_SHUTDOWN _MD_SHUTDOWN
+
+extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, 
+                               PRIntn flags, PRIntervalTime timeout);
+#define    _PR_MD_RECV _MD_RECV
+
+extern PRInt32 _PR_MD_SEND(
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, 
+    PRIntervalTime timeout);
+#define    _PR_MD_SEND _MD_SEND
+
+extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, 
+                                PRNetAddr **raddr, void *buf, PRInt32 amount,
+                                PRIntervalTime timeout);
+#define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ
+
+#ifdef WIN32
+extern PROsfd _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, 
+                                PRUint32 *addrlen, PRIntervalTime timeout,
+                                PRBool fast,
+                                _PR_AcceptTimeoutCallback callback,
+                                void *callbackArg);
+
+extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, 
+                                PRNetAddr **raddr, void *buf, PRInt32 amount,
+                                PRIntervalTime timeout, PRBool fast,
+                                _PR_AcceptTimeoutCallback callback,
+                                void *callbackArg);
+
+extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls);
+#define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT
+/*
+ * 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().
+ * This is defined in ntmisc.c
+ */
+extern const PRTime _pr_filetime_offset;
+#endif /* WIN32 */
+
+extern PRInt32 _PR_MD_SENDFILE(
+    PRFileDesc *sock, PRSendFileData *sfd, 
+	PRInt32 flags, PRIntervalTime timeout);
+#define _PR_MD_SENDFILE _MD_SENDFILE
+
+extern PRStatus _PR_MD_GETSOCKNAME(
+    PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
+#define    _PR_MD_GETSOCKNAME _MD_GETSOCKNAME
+
+extern PRStatus _PR_MD_GETPEERNAME(
+    PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
+#define    _PR_MD_GETPEERNAME _MD_GETPEERNAME
+
+extern PRStatus _PR_MD_GETSOCKOPT(
+    PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
+#define    _PR_MD_GETSOCKOPT _MD_GETSOCKOPT
+
+extern PRStatus _PR_MD_SETSOCKOPT(
+    PRFileDesc *fd, PRInt32 level, PRInt32 optname,
+    const char* optval, PRInt32 optlen);
+#define    _PR_MD_SETSOCKOPT _MD_SETSOCKOPT
+
+extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption(
+    PRFileDesc *fd, PRSocketOptionData *data);
+
+extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption(
+    PRFileDesc *fd, const PRSocketOptionData *data);
+
+extern PRInt32 _PR_MD_RECVFROM(
+    PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+    PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
+#define    _PR_MD_RECVFROM _MD_RECVFROM
+
+extern PRInt32 _PR_MD_SENDTO(
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+    const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
+#define    _PR_MD_SENDTO _MD_SENDTO
+
+extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd);
+#define    _PR_MD_SOCKETPAIR _MD_SOCKETPAIR
+
+extern PROsfd _PR_MD_SOCKET(int af, int type, int flags);
+#define    _PR_MD_SOCKET _MD_SOCKET
+
+extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd);
+#define    _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE
+
+extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd);
+#define    _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE
+
+extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
+                                                                                        PRIntervalTime timeout);
+#define    _PR_MD_PR_POLL _MD_PR_POLL
+
+/*
+ * Initialize fd->secret->inheritable for a newly created fd.
+ * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd)
+ * was created by NSPR and hence has the OS-dependent default
+ * inheritable attribute.  If 'imported' is true, the osfd was
+ * not created by NSPR and hence a system call is required to
+ * query its inheritable attribute.  Since we may never need to
+ * know the inheritable attribute of a fd, a platform may choose
+ * to initialize fd->secret->inheritable of an imported fd to
+ * _PR_TRI_UNKNOWN and only pay the cost of the system call
+ * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary.
+ */
+extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported);
+#define    _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE
+
+extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable);
+#define    _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE
+
+
+#define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \
+        if (_PR_PENDING_INTERRUPT(me)) { \
+                me->flags &= ~_PR_INTERRUPT; \
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \
+        } else { \
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \
+        }                                                        
+                
+extern void *_PR_MD_GET_SP(PRThread *thread);
+#define    _PR_MD_GET_SP _MD_GET_SP
+
+#endif /* defined(_PR_PTHREADS) */
+
+/************************************************************************/
+/*************************************************************************
+** The remainder of the definitions are shared by pthreads and the classic
+** NSPR code. These too may be conditionalized.
+*************************************************************************/
+/************************************************************************/
+
+extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence);
+#define    _PR_MD_LSEEK _MD_LSEEK
+
+extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence);
+#define    _PR_MD_LSEEK64 _MD_LSEEK64
+
+extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info);
+#define _PR_MD_GETFILEINFO _MD_GETFILEINFO
+
+extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info);
+#define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64
+
+extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info);
+#define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO
+
+extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info);
+#define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64
+
+
+/*****************************************************************************/
+/************************** File descriptor caching **************************/
+/*****************************************************************************/
+extern void _PR_InitFdCache(void);
+extern void _PR_CleanupFdCache(void);
+extern PRFileDesc *_PR_Getfd(void);
+extern void _PR_Putfd(PRFileDesc *fd);
+
+/*
+ * These flags are used by NSPR temporarily in the poll
+ * descriptor's out_flags field to record the mapping of
+ * NSPR's poll flags to the system poll flags.
+ *
+ * If _PR_POLL_READ_SYS_WRITE bit is set, it means the
+ * PR_POLL_READ flag specified by the topmost layer is
+ * mapped to the WRITE flag at the system layer.  Similarly
+ * for the other three _PR_POLL_XXX_SYS_YYY flags.  It is
+ * assumed that the PR_POLL_EXCEPT flag doesn't get mapped
+ * to other flags.
+ */
+#define _PR_POLL_READ_SYS_READ     0x1
+#define _PR_POLL_READ_SYS_WRITE    0x2
+#define _PR_POLL_WRITE_SYS_READ    0x4
+#define _PR_POLL_WRITE_SYS_WRITE   0x8
+
+/*
+** These methods are coerced into file descriptor methods table
+** when the intended service is inappropriate for the particular
+** type of file descriptor.
+*/
+extern PRIntn _PR_InvalidInt(void);
+extern PRInt16 _PR_InvalidInt16(void);
+extern PRInt64 _PR_InvalidInt64(void);
+extern PRStatus _PR_InvalidStatus(void);
+extern PRFileDesc *_PR_InvalidDesc(void);
+
+extern PRIOMethods _pr_faulty_methods;
+
+/*
+** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union
+** whose 'family' field is set.  It returns the size of the union
+** member corresponding to the specified address family.
+*/
+
+extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr);
+
+#if defined(_PR_INET6)
+
+#define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr)
+
+#elif defined(_PR_HAVE_MD_SOCKADDR_IN6)
+
+/*
+** Under the following conditions:
+** 1. _PR_INET6 is not defined;
+** 2. _PR_INET6_PROBE is defined;
+** 3. struct sockaddr_in6 has nonstandard fields at the end
+**    (e.g., on Solaris 8),
+** (_addr)->ipv6 is smaller than struct sockaddr_in6, and
+** hence we can't pass sizeof((_addr)->ipv6) to socket
+** functions such as connect because they would fail with
+** EINVAL.
+**
+** To pass the correct socket address length to socket
+** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and
+** define struct _md_sockaddr_in6 to be isomorphic to
+** struct sockaddr_in6.
+*/
+
+#if defined(XP_UNIX) || defined(XP_OS2)
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : ((_addr)->raw.family == PR_AF_INET6	\
+        ? sizeof(struct _md_sockaddr_in6)		\
+        : sizeof((_addr)->local)))
+#else
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : sizeof(struct _md_sockaddr_in6))
+#endif /* defined(XP_UNIX) */
+
+#else
+
+#if defined(XP_UNIX) || defined(XP_OS2)
+#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) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : sizeof((_addr)->ipv6))
+#endif /* defined(XP_UNIX) */
+
+#endif /* defined(_PR_INET6) */
+
+extern PRStatus _PR_MapOptionName(
+    PRSockOption optname, PRInt32 *level, PRInt32 *name);
+extern void _PR_InitThreads(
+    PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs);
+
+struct PRLock {
+#if defined(_PR_PTHREADS)
+    pthread_mutex_t mutex;          /* the underlying lock */
+    _PT_Notified notified;          /* array of conditions notified */
+    PRBool locked;                  /* whether the mutex is locked */
+    pthread_t owner;                /* if locked, current lock owner */
+#elif defined(_PR_BTHREADS)
+    sem_id	semaphoreID;	    /* the underlying lock */
+    int32	benaphoreCount;	    /* number of people in lock */
+    thread_id	owner;		    /* current lock owner */
+#else /* not pthreads or Be threads */
+    PRCList links;                  /* linkage for PRThread.lockList */
+    struct PRThread *owner;         /* current lock owner */
+    PRCList waitQ;                  /* list of threads waiting for lock */
+    PRThreadPriority priority;      /* priority of lock */ 
+    PRThreadPriority boostPriority; /* boosted priority of lock owner */
+    _MDLock ilock;                  /* Internal Lock to protect user-level fields */
+#endif
+};
+
+extern void _PR_InitLocks(void);
+
+struct PRCondVar {
+    PRLock *lock;               /* associated lock that protects the condition */
+#if defined(_PR_PTHREADS)
+    pthread_cond_t cv;          /* underlying pthreads condition */
+    PRInt32 notify_pending;     /* CV has destroy pending notification */
+#elif defined(_PR_BTHREADS)
+    sem_id    sem;              /* the underlying lock */
+    sem_id    handshakeSem;     /* the lock for 'notify'-threads waiting for confirmation */
+    sem_id    signalSem;        /* the lock for threads waiting for someone to notify */
+    volatile int32    nw;       /* the number waiting */
+    volatile int32    ns;       /* the number signalling */
+    long signalBenCount;        /* the number waiting on the underlying sem */
+#else /* not pthreads or Be threads */
+    PRCList condQ;              /* Condition variable wait Q */
+    _MDLock ilock;              /* Internal Lock to protect condQ */
+    _MDCVar md;
+#endif
+};
+
+/************************************************************************/
+
+struct PRMonitor {
+    const char* name;           /* monitor name for debugging */
+#if defined(_PR_PTHREADS)
+    PRLock lock;                /* the lock structure */
+    pthread_t owner;            /* the owner of the lock or invalid */
+    PRCondVar *cvar;            /* condition variable queue */
+#else  /* defined(_PR_PTHREADS) */
+    PRCondVar *cvar;            /* associated lock and condition variable queue */
+#endif /* defined(_PR_PTHREADS) */
+    PRUint32 entryCount;        /* # of times re-entered */
+};
+
+/************************************************************************/
+
+struct PRSemaphore {
+#if defined(_PR_BTHREADS)
+    sem_id  sem;
+    int32   benaphoreCount;
+#else
+    PRCondVar *cvar;        /* associated lock and condition variable queue */
+    PRUintn count;            /* the value of the counting semaphore */
+    PRUint32 waiters;            /* threads waiting on the semaphore */
+#if defined(_PR_PTHREADS)
+#else  /* defined(_PR_PTHREADS) */
+    _MDSemaphore md;
+#endif /* defined(_PR_PTHREADS) */
+#endif /* defined(_PR_BTHREADS) */
+};
+
+NSPR_API(void) _PR_InitSem(void);
+
+/*************************************************************************/
+
+struct PRSem {
+#ifdef _PR_HAVE_POSIX_SEMAPHORES
+    sem_t *sem;
+#elif defined(_PR_HAVE_SYSV_SEMAPHORES)
+    int semid;
+#elif defined(WIN32)
+    HANDLE sem;
+#else
+    PRInt8 notused;
+#endif
+};
+
+/*************************************************************************/
+
+struct PRStackStr {
+    /* head MUST be at offset 0; assembly language code relies on this */
+#if defined(AIX)
+    volatile PRStackElem prstk_head;
+#else
+    PRStackElem prstk_head;
+#endif
+
+    PRLock *prstk_lock;
+    char *prstk_name;
+};
+
+/************************************************************************/
+
+/* XXX this needs to be exported (sigh) */
+struct PRThreadStack {
+    PRCList links;
+    PRUintn flags;
+
+    char *allocBase;            /* base of stack's allocated memory */
+    PRUint32 allocSize;         /* size of stack's allocated memory */
+    char *stackBottom;          /* bottom of stack from C's point of view */
+    char *stackTop;             /* top of stack from C's point of view */
+    PRUint32 stackSize;         /* size of usable portion of the stack */
+
+    PRSegment *seg;
+        PRThread* thr;          /* back pointer to thread owning this stack */
+
+#if defined(_PR_PTHREADS)
+#else /* defined(_PR_PTHREADS) */
+    _MDThreadStack md;
+#endif /* defined(_PR_PTHREADS) */
+};
+
+extern void _PR_DestroyThreadPrivate(PRThread*);
+
+typedef void (PR_CALLBACK *_PRStartFn)(void *);
+
+struct PRThread {
+    PRUint32 state;                 /* thread's creation state */
+    PRThreadPriority priority;      /* apparent priority, loosly defined */
+
+    void *arg;                      /* argument to the client's entry point */
+    _PRStartFn startFunc;           /* the root of the client's thread */
+
+    PRThreadStack *stack;           /* info about thread's stack (for GC) */
+    void *environment;              /* pointer to execution environment */
+
+    PRThreadDumpProc dump;          /* dump thread info out */
+    void *dumpArg;                  /* argument for the dump function */
+
+    /*
+    ** Per thread private data
+    */
+    PRUint32 tpdLength;             /* thread's current vector length */
+    void **privateData;             /* private data vector or NULL */
+    PRErrorCode errorCode;          /* current NSPR error code | zero */
+    PRInt32 osErrorCode;            /* mapping of errorCode | zero */
+    PRIntn  errorStringLength;      /* textLength from last call to PR_SetErrorText() */
+    PRInt32 errorStringSize;        /* malloc()'d size of buffer | 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 *waiting;             /* where the thread is waiting | NULL */
+    void *sp;                       /* recorded sp for garbage collection */
+    PRThread *next, *prev;          /* simple linked list of all threads */
+    PRUint32 suspend;               /* used to store suspend and resume flags */
+#ifdef PT_NO_SIGTIMEDWAIT
+    pthread_mutex_t suspendResumeMutex;
+    pthread_cond_t suspendResumeCV;
+#endif
+    PRUint32 interrupt_blocked;     /* interrupt blocked */
+    struct pollfd *syspoll_list;    /* Unix polling list used by PR_Poll */
+    PRUint32 syspoll_count;         /* number of elements in syspoll_list */
+#if defined(_PR_POLL_WITH_SELECT)
+    int *selectfd_list;             /* Unix fd's that PR_Poll selects on */
+    PRUint32 selectfd_count;        /* number of elements in selectfd_list */
+#endif
+#elif defined(_PR_BTHREADS)
+    PRUint32 flags;
+    _MDThread md;
+    PRBool io_pending;
+    PRInt32 io_fd;
+    PRBool io_suspended;
+#else /* not pthreads or Be threads */
+    _MDLock threadLock;             /* Lock to protect thread state variables.
+                                     * Protects the following fields:
+                                     *     state
+                                     *     priority
+                                     *     links
+                                     *     wait
+                                     *     cpu
+                                     */
+    PRUint32 queueCount;
+    PRUint32 waitCount;
+
+    PRCList active;                 /* on list of all active threads        */
+    PRCList links;
+    PRCList waitQLinks;             /* when thread is PR_Wait'ing */
+    PRCList lockList;               /* list of locks currently holding */
+    PRIntervalTime sleep;           /* sleep time when thread is sleeping */
+    struct _wait {
+        struct PRLock *lock;
+        struct PRCondVar *cvar;
+    } wait;
+
+    PRUint32 id;
+    PRUint32 flags;
+    PRUint32 no_sched;              /* Don't schedule the thread to run.
+                                     * This flag has relevance only when
+                                     * multiple NSPR CPUs are created.
+                                     * When a thread is de-scheduled, there
+                                     * is a narrow window of time in which
+                                     * the thread is put on the run queue
+                                     * but the scheduler is actually using
+                                     * the stack of this thread.  It is safe
+                                     * to run this thread on a different CPU
+                                     * only when its stack is not in use on
+                                     * any other CPU.  The no_sched flag is
+                                     * set during this interval to prevent
+                                     * the thread from being scheduled on a
+                                     * different CPU.
+                                     */
+
+    /* thread termination condition variable for join */
+    PRCondVar *term;
+
+    _PRCPU *cpu;                    /* cpu to which this thread is bound    */
+    PRUint32 threadAllocatedOnStack;/* boolean */
+
+    /* When an async IO is in progress and a second async IO cannot be 
+     * initiated, the io_pending flag is set to true.  Some platforms will
+     * not use the io_pending flag.  If the io_pending flag is true, then
+     * io_fd is the OS-file descriptor on which IO is pending.
+     */
+    PRBool io_pending;
+    PRInt32 io_fd;
+ 
+    /* If a timeout occurs or if an outstanding IO is interrupted and the
+     * OS doesn't support a real cancellation (NT or MAC), then the 
+     * io_suspended flag will be set to true.  The thread will be resumed
+     * but may run into trouble issuing additional IOs until the io_pending
+     * flag can be cleared 
+     */
+    PRBool io_suspended;
+
+    _MDThread md;
+#endif
+};
+
+struct PRProcessAttr {
+    PRFileDesc *stdinFd;
+    PRFileDesc *stdoutFd;
+    PRFileDesc *stderrFd;
+    char *currentDirectory;
+    char *fdInheritBuffer;
+    PRSize fdInheritBufferSize;
+    PRSize fdInheritBufferUsed;
+};
+
+struct PRProcess {
+    _MDProcess md;
+};
+
+struct PRFileMap {
+    PRFileDesc *fd;
+    PRFileMapProtect prot;
+    _MDFileMap md;
+};
+
+/************************************************************************/
+
+/*
+** File descriptors of the NSPR layer can be in one of the
+** following states (stored in the 'state' field of struct
+** PRFilePrivate):
+** - _PR_FILEDESC_OPEN: The OS fd is open.
+** - _PR_FILEDESC_CLOSED: The OS fd is closed.  The PRFileDesc
+**   is still open but is unusable.  The only operation allowed
+**   on the PRFileDesc is PR_Close().
+** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc
+**   structure is freed.
+*/
+
+#define _PR_FILEDESC_OPEN       0xaaaaaaaa    /* 1010101... */
+#define _PR_FILEDESC_CLOSED     0x55555555    /* 0101010... */
+#define _PR_FILEDESC_FREED      0x11111111
+
+/*
+** A boolean type with an additional "unknown" state
+*/
+
+typedef enum {
+    _PR_TRI_TRUE = 1,
+    _PR_TRI_FALSE = 0,
+    _PR_TRI_UNKNOWN = -1
+} _PRTriStateBool;
+
+struct PRFilePrivate {
+    PRInt32 state;
+    PRBool nonblocking;
+    _PRTriStateBool inheritable;
+    PRFileDesc *next;
+    PRIntn lockCount;   /*   0: not locked
+                         *  -1: a native lockfile call is in progress
+                         * > 0: # times the file is locked */
+#ifdef _PR_HAVE_PEEK_BUFFER
+    char *peekBuffer;
+    PRInt32 peekBufSize;
+    PRInt32 peekBytes;
+#endif
+#if !defined(_PR_HAVE_O_APPEND)
+    PRBool  appendMode; /* Some platforms don't have O_APPEND or its
+                         * equivalent, so they have to seek to end of
+                         * file on write if the file was opened in
+                         * append mode.  See Bugzilla 4090, 276330. */
+#endif
+    _MDFileDesc md;
+#ifdef _PR_NEED_SECRET_AF
+    PRUint16 af;        /* If the platform's implementation of accept()
+                         * requires knowing the address family of the 
+			 * socket, we save the address family here. */
+#endif
+};
+
+#ifdef _WIN64
+#define PR_PRIdOSFD "lld"       /* for printing PROsfd */
+#define PR_PRIxOSFD "llx"
+#define PR_SCNdOSFD "lld"       /* for scanning PROsfd */
+#define PR_SCNxOSFD "llx"
+#else
+#define PR_PRIdOSFD "ld"        /* for printing PROsfd */
+#define PR_PRIxOSFD "lx"
+#define PR_SCNdOSFD "ld"        /* for scanning PROsfd */
+#define PR_SCNxOSFD "lx"
+#endif
+
+struct PRDir {
+    PRDirEntry d;
+    _MDDir md;
+};
+
+#ifdef MOZ_UNICODE
+struct PRDirUTF16 { 
+    PRDirEntry d; 
+    _MDDirUTF16 md; 
+}; 
+#endif /* MOZ_UNICODE */
+
+extern void _PR_InitSegs(void);
+extern void _PR_InitStacks(void);
+extern void _PR_InitTPD(void);
+extern void _PR_InitMem(void);
+extern void _PR_InitEnv(void);
+extern void _PR_InitCMon(void);
+extern void _PR_InitIO(void);
+extern void _PR_InitLog(void);
+extern void _PR_InitNet(void);
+extern void _PR_InitClock(void);
+extern void _PR_InitLinker(void);
+extern void _PR_InitAtomic(void);
+extern void _PR_InitCPUs(void);
+extern void _PR_InitDtoa(void);
+extern void _PR_InitTime(void);
+extern void _PR_InitMW(void);
+extern void _PR_InitRWLocks(void);
+extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me);
+extern void _PR_CleanupThread(PRThread *thread);
+extern void _PR_CleanupCallOnce(void);
+extern void _PR_CleanupMW(void);
+extern void _PR_CleanupTime(void);
+extern void _PR_CleanupDtoa(void);
+extern void _PR_ShutdownLinker(void);
+extern void _PR_CleanupEnv(void);
+extern void _PR_CleanupIO(void);
+extern void _PR_CleanupCMon(void);
+extern void _PR_CleanupNet(void);
+extern void _PR_CleanupLayerCache(void);
+extern void _PR_CleanupStacks(void);
+#ifdef WINNT
+extern void _PR_CleanupCPUs(void);
+#endif
+extern void _PR_CleanupThreads(void);
+extern void _PR_CleanupTPD(void);
+extern void _PR_Cleanup(void);
+extern void _PR_LogCleanup(void);
+extern void _PR_InitLayerCache(void);
+#ifdef GC_LEAK_DETECTOR
+extern void _PR_InitGarbageCollector(void);
+#endif
+
+extern PRBool _pr_initialized;
+extern void _PR_ImplicitInitialization(void);
+extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred);
+
+/************************************************************************/
+
+struct PRSegment {
+    void *vaddr;
+    PRUint32 size;
+    PRUintn flags;
+#if defined(_PR_PTHREADS)
+#else  /* defined(_PR_PTHREADS) */
+    _MDSegment md;
+#endif /* defined(_PR_PTHREADS) */
+};
+
+/* PRSegment.flags */
+#define _PR_SEG_VM    0x1
+
+/************************************************************************/
+
+extern PRInt32 _pr_pageSize;
+extern PRInt32 _pr_pageShift;
+
+extern PRLogModuleInfo *_pr_clock_lm;
+extern PRLogModuleInfo *_pr_cmon_lm;
+extern PRLogModuleInfo *_pr_io_lm;
+extern PRLogModuleInfo *_pr_cvar_lm;
+extern PRLogModuleInfo *_pr_mon_lm;
+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;
+
+/* Zone allocator */
+/*
+** The zone allocator code has hardcoded pthread types and
+** functions, so it can only be used in the pthreads version.
+** This can be fixed by replacing the hardcoded pthread types
+** and functions with macros that expand to the native thread
+** types and functions on each platform.
+*/
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#define _PR_ZONE_ALLOCATOR
+#endif
+
+#ifdef _PR_ZONE_ALLOCATOR
+extern void _PR_InitZones(void);
+extern void _PR_DestroyZones(void);
+#endif
+
+/* Overriding malloc, free, etc. */
+#if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
+        && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \
+        && !defined(PURIFY) \
+        && !defined(DARWIN) \
+        && !defined(NEXTSTEP) \
+        && !defined(QNX) \
+        && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS))
+#define _PR_OVERRIDE_MALLOC
+#endif
+
+/*************************************************************************
+* External machine-dependent code provided by each OS.                     *                                                                     *
+*************************************************************************/
+
+/* Initialization related */
+extern void _PR_MD_EARLY_INIT(void);
+#define    _PR_MD_EARLY_INIT _MD_EARLY_INIT
+
+extern void _PR_MD_INTERVAL_INIT(void);
+#define    _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT
+
+NSPR_API(void) _PR_MD_FINAL_INIT(void);
+#define    _PR_MD_FINAL_INIT _MD_FINAL_INIT
+
+extern void _PR_MD_EARLY_CLEANUP(void);
+#define    _PR_MD_EARLY_CLEANUP _MD_EARLY_CLEANUP
+
+/* Process control */
+
+extern PRProcess * _PR_MD_CREATE_PROCESS(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr);
+#define    _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS
+
+extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process);
+#define    _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS
+
+extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode);
+#define    _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS
+
+extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process);
+#define    _PR_MD_KILL_PROCESS _MD_KILL_PROCESS        
+
+/* Current Time */
+NSPR_API(PRTime) _PR_MD_NOW(void);
+#define    _PR_MD_NOW _MD_NOW
+
+/* Environment related */
+extern char* _PR_MD_GET_ENV(const char *name);
+#define    _PR_MD_GET_ENV _MD_GET_ENV
+
+extern PRIntn _PR_MD_PUT_ENV(const char *name);
+#define    _PR_MD_PUT_ENV _MD_PUT_ENV
+
+/* Atomic operations */
+
+extern void _PR_MD_INIT_ATOMIC(void);
+#define    _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC
+
+extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
+#define    _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT
+
+extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32);
+#define    _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD
+
+extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
+#define    _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT
+
+extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
+#define    _PR_MD_ATOMIC_SET _MD_ATOMIC_SET
+
+/* Garbage collection */
+
+/*
+** Save the registers that the GC would find interesting into the thread
+** "t". isCurrent will be non-zero if the thread state that is being
+** saved is the currently executing thread. Return the address of the
+** first register to be scanned as well as the number of registers to
+** scan in "np".
+**
+** If "isCurrent" is non-zero then it is allowed for the thread context
+** area to be used as scratch storage to hold just the registers
+** necessary for scanning.
+*/
+extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np);
+
+/* Time intervals */
+
+extern PRIntervalTime _PR_MD_GET_INTERVAL(void);
+#define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL
+
+extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void);
+#define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC
+
+/* Affinity masks */
+
+extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
+#define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK
+
+extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
+#define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK
+
+/* File locking */
+
+extern PRStatus _PR_MD_LOCKFILE(PROsfd osfd);
+#define    _PR_MD_LOCKFILE _MD_LOCKFILE
+
+extern PRStatus _PR_MD_TLOCKFILE(PROsfd osfd);
+#define    _PR_MD_TLOCKFILE _MD_TLOCKFILE
+
+extern PRStatus _PR_MD_UNLOCKFILE(PROsfd osfd);
+#define    _PR_MD_UNLOCKFILE _MD_UNLOCKFILE
+
+/* Memory-mapped files */
+
+extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size);
+#define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP
+
+extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void);
+#define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT
+
+extern void * _PR_MD_MEM_MAP(
+    PRFileMap *fmap,
+    PROffset64 offset,
+    PRUint32 len);
+#define _PR_MD_MEM_MAP _MD_MEM_MAP
+
+extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size);
+#define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP
+
+extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap);
+#define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP
+
+/* Named Shared Memory */
+
+/*
+** Declare PRSharedMemory.
+*/
+struct PRSharedMemory 
+{
+    char        *ipcname; /* after conversion to native */
+    PRSize      size;  /* from open */
+    PRIntn      mode;  /* from open */
+    PRIntn      flags; /* from open */
+#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY)
+    int         id;
+#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY)
+    int         id;
+#elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
+    HANDLE      handle;
+#else
+    PRUint32    nothing; /* placeholder, nothing behind here */
+#endif
+    PRUint32    ident; /* guard word at end of struct */
+#define _PR_SHM_IDENT 0xdeadbad
+};
+                                                      
+extern PRSharedMemory * _MD_OpenSharedMemory( 
+    const char *name,
+    PRSize      size,
+    PRIntn      flags,
+    PRIntn      mode
+);
+#define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags );
+#define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr );
+#define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm );
+#define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name );
+#define _PR_MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
+
+extern PRFileMap* _md_OpenAnonFileMap( 
+    const char *dirName,
+    PRSize      size,
+    PRFileMapProtect prot
+);
+#define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap
+
+extern PRStatus _md_ExportFileMapAsString(
+    PRFileMap *fm,
+    PRSize    bufSize,
+    char      *buf
+);
+#define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString
+
+extern PRFileMap * _md_ImportFileMapFromString(
+    const char *fmstring
+);
+#define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString
+
+
+
+/* Interprocess communications (IPC) */
+
+/*
+ * The maximum length of an NSPR IPC name, including the
+ * terminating null byte.
+ */
+#define PR_IPC_NAME_SIZE 1024
+
+/*
+ * Types of NSPR IPC objects
+ */
+typedef enum {
+    _PRIPCSem,  /* semaphores */
+    _PRIPCShm   /* shared memory segments */
+} _PRIPCType;
+
+/*
+ * Make a native IPC name from an NSPR IPC name.
+ */
+extern PRStatus _PR_MakeNativeIPCName(
+    const char *name,  /* NSPR IPC name */
+    char *result,      /* result buffer */
+    PRIntn size,       /* size of result buffer */
+    _PRIPCType type    /* type of IPC object */
+);
+
+/* Socket call error code */
+
+NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void);
+#define    _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
+
+/* Get name of current host */
+extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
+#define    _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
+
+extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen);
+#define    _PR_MD_GETSYSINFO _MD_GETSYSINFO
+
+/* File descriptor inheritance */
+
+/*
+ * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to
+ * know the inheritable attribute of the fd, call this function
+ * to find that out.  This typically requires a system call.
+ */
+extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd);
+#define    _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE
+
+/* --- PR_GetRandomNoise() related things --- */
+
+extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size );
+#define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size))
+extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srclen );
+
+/* end PR_GetRandomNoise() related */
+
+#ifdef XP_BEOS
+
+extern PRLock *_connectLock;
+
+typedef struct _ConnectListNode {
+	PRInt32		osfd;
+	PRNetAddr	addr;
+	PRUint32	addrlen;
+	PRIntervalTime	timeout;
+} ConnectListNode;
+
+extern ConnectListNode connectList[64];
+
+extern PRUint32 connectCount;
+
+#endif /* XP_BEOS */
+
+PR_END_EXTERN_C
+
+#endif /* primpl_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/private/prpriv.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/prpriv.h
new file mode 100644
index 0000000..12a2cd6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/private/prpriv.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prpriv_h___
+#define prpriv_h___
+
+/*
+ * NSPR 2.0 Private API
+ */
+
+#include "private/pprio.h"
+#include "private/pprthred.h"
+
+#endif /* prpriv_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prlink.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prlink.h
new file mode 100644
index 0000000..45f4581
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prlink.h
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prlink_h___
+#define prlink_h___
+
+/*
+** API to static and dynamic linking.
+*/
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRLibrary PRLibrary;
+
+typedef struct PRStaticLinkTable {
+    const char *name;
+    void (*fp)(void);
+} PRStaticLinkTable;
+
+/*
+** Change the default library path to the given string. The string is
+** copied. This call will fail if it runs out of memory.
+**
+** The string provided as 'path' is copied. The caller can do whatever is
+** convenient with the argument when the function is complete.
+*/
+NSPR_API(PRStatus) PR_SetLibraryPath(const char *path);
+
+/*
+** Return a character string which contains the path used to search for
+** dynamically loadable libraries.
+**
+** The returned value is basically a copy of a PR_SetLibraryPath().
+** The storage is allocated by the runtime and becomes the responsibilty
+** of the caller.
+*/
+NSPR_API(char*) PR_GetLibraryPath(void);
+
+/*
+** Given a directory name "dir" and a library name "lib" construct a full
+** path name that will refer to the actual dynamically loaded
+** library. This does not test for existance of said file, it just
+** constructs the full filename. The name constructed is system dependent
+** and prepared for PR_LoadLibrary. The result must be free'd when the
+** caller is done with it.
+**
+** The storage for the result is allocated by the runtime and becomes the
+** responsibility of the caller.
+*/
+NSPR_API(char*) PR_GetLibraryName(const char *dir, const char *lib);
+
+/*
+**
+** Free the memory allocated, for the caller, by PR_GetLibraryName
+*/
+NSPR_API(void) PR_FreeLibraryName(char *mem);
+
+/*
+** Given a library "name" try to load the library. The argument "name"
+** is a machine-dependent name for the library, such as the full pathname
+** returned by PR_GetLibraryName.  If the library is already loaded,
+** this function will avoid loading the library twice.
+**
+** If the library is loaded successfully, then a pointer to the PRLibrary
+** structure representing the library is returned.  Otherwise, NULL is
+** returned.
+**
+** This increments the reference count of the library.
+*/
+NSPR_API(PRLibrary*) PR_LoadLibrary(const char *name);
+
+/*
+** Each operating system has its preferred way of specifying
+** a file in the file system.  Most operating systems use
+** a pathname.  Mac OS Classic, on the other hand, uses the FSSpec
+** structure to specify a file. PRLibSpec allows NSPR clients
+** to use the type of file specification that is most efficient
+** for a particular platform.
+**
+** On some operating systems such as Mac OS Classic, a shared library
+** may contain code fragments that can be individually loaded.
+** PRLibSpec also allows NSPR clients to identify a code fragment
+** in a library, if code fragments are supported by the OS.
+** A code fragment can be specified by name or by an integer index.
+**
+** Right now PRLibSpec supports four types of library specification:
+** a pathname in the native character encoding, a Mac code fragment
+** by name, a Mac code fragment by index, and a UTF-16 pathname.
+*/
+
+typedef enum PRLibSpecType {
+    PR_LibSpec_Pathname,
+    PR_LibSpec_MacNamedFragment,   /* obsolete (for Mac OS Classic) */
+    PR_LibSpec_MacIndexedFragment, /* obsolete (for Mac OS Classic) */
+    PR_LibSpec_PathnameU           /* supported only on Win32 */ 
+} PRLibSpecType;
+
+struct FSSpec; /* Mac OS Classic FSSpec */
+
+typedef struct PRLibSpec {
+    PRLibSpecType type;
+    union {
+        /* if type is PR_LibSpec_Pathname */
+        const char *pathname;
+
+        /* if type is PR_LibSpec_MacNamedFragment */
+        struct {
+            const struct FSSpec *fsspec;
+            const char *name;
+        } mac_named_fragment;      /* obsolete (for Mac OS Classic) */
+
+        /* if type is PR_LibSpec_MacIndexedFragment */
+        struct {
+            const struct FSSpec *fsspec;
+            PRUint32 index;
+        } mac_indexed_fragment;    /* obsolete (for Mac OS Classic) */
+
+        /* if type is PR_LibSpec_PathnameU */
+        const PRUnichar *pathname_u; /* supported only on Win32 */
+    } value;
+} PRLibSpec;
+
+/*
+** The following bit flags may be or'd together and passed
+** as the 'flags' argument to PR_LoadLibraryWithFlags.
+** Flags not supported by the underlying OS are ignored.
+*/
+
+#define PR_LD_LAZY   0x1  /* equivalent to RTLD_LAZY on Unix */
+#define PR_LD_NOW    0x2  /* equivalent to RTLD_NOW on Unix */
+#define PR_LD_GLOBAL 0x4  /* equivalent to RTLD_GLOBAL on Unix */
+#define PR_LD_LOCAL  0x8  /* equivalent to RTLD_LOCAL on Unix */
+/* The following is equivalent to LOAD_WITH_ALTERED_SEARCH_PATH on Windows */
+#define PR_LD_ALT_SEARCH_PATH  0x10  
+/*                0x8000     reserved for NSPR internal use */
+
+/*
+** Load the specified library, in the manner specified by 'flags'.
+*/
+
+NSPR_API(PRLibrary *)
+PR_LoadLibraryWithFlags(
+    PRLibSpec libSpec,    /* the shared library */
+    PRIntn flags          /* flags that affect the loading */
+);
+
+/*
+** Unload a previously loaded library. If the library was a static
+** library then the static link table will no longer be referenced. The
+** associated PRLibrary object is freed.
+**
+** PR_FAILURE is returned if the library cannot be unloaded.
+**
+** This function decrements the reference count of the library.
+*/
+NSPR_API(PRStatus) PR_UnloadLibrary(PRLibrary *lib);
+
+/*
+** Given the name of a procedure, return the address of the function that
+** implements the procedure, or NULL if no such function can be
+** found. This does not find symbols in the main program (the ".exe");
+** use PR_LoadStaticLibrary to register symbols in the main program.
+**
+** This function does not modify the reference count of the library.
+*/
+NSPR_API(void*) PR_FindSymbol(PRLibrary *lib, const char *name);
+
+/*
+** Similar to PR_FindSymbol, except that the return value is a pointer to
+** a function, and not a pointer to void. Casting between a data pointer
+** and a function pointer is not portable according to the C standard.
+** Any function pointer can be cast to any other function pointer.
+**
+** This function does not modify the reference count of the library.
+*/
+typedef void (*PRFuncPtr)(void);
+NSPR_API(PRFuncPtr) PR_FindFunctionSymbol(PRLibrary *lib, const char *name);
+
+/*
+** Finds a symbol in one of the currently loaded libraries. Given the
+** name of a procedure, return the address of the function that
+** implements the procedure, and return the library that contains that
+** symbol, or NULL if no such function can be found. This does not find
+** symbols in the main program (the ".exe"); use PR_AddStaticLibrary to
+** register symbols in the main program.  
+**
+** This increments the reference count of the library.
+*/
+NSPR_API(void*) PR_FindSymbolAndLibrary(const char *name,
+						      PRLibrary* *lib);
+
+/*
+** Similar to PR_FindSymbolAndLibrary, except that the return value is
+** a pointer to a function, and not a pointer to void. Casting between a
+** data pointer and a function pointer is not portable according to the C
+** standard. Any function pointer can be cast to any other function pointer.
+**
+** This increments the reference count of the library.
+*/
+NSPR_API(PRFuncPtr) PR_FindFunctionSymbolAndLibrary(const char *name,
+						      PRLibrary* *lib);
+
+/*
+** Register a static link table with the runtime under the name
+** "name". The symbols present in the static link table will be made
+** available to PR_FindSymbol. If "name" is null then the symbols will be
+** made available to the library which represents the executable. The
+** tables are not copied.
+**
+** Returns the library object if successful, null otherwise.
+**
+** This increments the reference count of the library.
+*/
+NSPR_API(PRLibrary*) PR_LoadStaticLibrary(
+    const char *name, const PRStaticLinkTable *table);
+
+/*
+** Return the pathname of the file that the library "name" was loaded
+** from. "addr" is the address of a function defined in the library.
+**
+** The caller is responsible for freeing the result with PR_Free.
+*/
+NSPR_API(char *) PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr);
+
+PR_END_EXTERN_C
+
+#endif /* prlink_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prlock.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prlock.h
new file mode 100644
index 0000000..b270aac
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prlock.h
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:		prlock.h
+** Description:	API to basic locking functions of NSPR.
+**
+**
+** NSPR provides basic locking mechanisms for thread synchronization.  Locks 
+** are lightweight resource contention controls that prevent multiple threads 
+** from accessing something (code/data) simultaneously.
+**/
+
+#ifndef prlock_h___
+#define prlock_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+/*
+ * PRLock --
+ *
+ *     NSPR represents the lock as an opaque entity to the client of the
+ *	   API.  All routines operate on a pointer to this opaque entity.
+ */
+
+typedef struct PRLock PRLock;
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/***********************************************************************
+** FUNCTION:    PR_NewLock
+** DESCRIPTION:
+**  Returns a pointer to a newly created opaque lock object.
+** INPUTS:      void
+** OUTPUTS:     void
+** RETURN:      PRLock*
+**   If the lock can not be created because of resource constraints, NULL
+**   is returned.
+**  
+***********************************************************************/
+NSPR_API(PRLock*) PR_NewLock(void);
+
+/***********************************************************************
+** FUNCTION:    PR_DestroyLock
+** DESCRIPTION:
+**  Destroys a given opaque lock object.
+** INPUTS:      PRLock *lock
+**              Lock to be freed.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_DestroyLock(PRLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_Lock
+** DESCRIPTION:
+**  Lock a lock.
+** INPUTS:      PRLock *lock
+**              Lock to locked.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_Lock(PRLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_Unlock
+** DESCRIPTION:
+**  Unlock a lock.  Unlocking an unlocked lock has undefined results.
+** INPUTS:      PRLock *lock
+**              Lock to unlocked.
+** OUTPUTS:     void
+** RETURN:      PR_STATUS
+**              Returns PR_FAILURE if the caller does not own the lock.
+***********************************************************************/
+NSPR_API(PRStatus) PR_Unlock(PRLock *lock);
+
+/***********************************************************************
+** MACRO:    PR_ASSERT_CURRENT_THREAD_OWNS_LOCK
+** DESCRIPTION:
+**  If the current thread owns |lock|, this assertion is guaranteed to
+**  succeed.  Otherwise, the behavior of this function is undefined.
+** INPUTS:      PRLock *lock
+**              Lock to assert ownership of.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
+#define PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(/* PrLock* */ lock) \
+    PR_AssertCurrentThreadOwnsLock(lock)
+#else
+#define PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(/* PrLock* */ lock)
+#endif
+
+/* Don't call this function directly. */
+NSPR_API(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock);
+
+PR_END_EXTERN_C
+
+#endif /* prlock_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prlog.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prlog.h
new file mode 100644
index 0000000..d2ca5d7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prlog.h
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prlog_h___
+#define prlog_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** prlog.h -- Declare interfaces to NSPR's Logging service
+**
+** NSPR provides a logging service that is used by NSPR itself and is
+** available to client programs.
+**
+** To use the service from a client program, you should create a
+** PRLogModuleInfo structure by calling PR_NewLogModule(). After
+** creating the LogModule, you can write to the log using the PR_LOG()
+** macro.
+**
+** Initialization of the log service is handled by NSPR initialization.
+**
+** At execution time, you must enable the log service. To enable the
+** log service, set the environment variable: NSPR_LOG_MODULES
+** variable.
+**
+** NSPR_LOG_MODULES variable has the form:
+**
+**     <moduleName>:<value>[, <moduleName>:<value>]*
+**
+** Where:
+**  <moduleName> is the name passed to PR_NewLogModule().
+**  <value> is a numeric constant, e.g. 5. This value is the maximum
+** value of a log event, enumerated by PRLogModuleLevel, that you want
+** written to the log.
+** 
+** For example: to record all events of greater value than or equal to
+** PR_LOG_ERROR for a LogModule names "gizmo", say:
+** 
+** set NSPR_LOG_MODULES=gizmo:2
+** 
+** Note that you must specify the numeric value of PR_LOG_ERROR.
+** 
+** Special LogModule names are provided for controlling NSPR's log
+** service at execution time. These controls should be set in the
+** NSPR_LOG_MODULES environment variable at execution time to affect
+** NSPR's log service for your application.
+** 
+** The special LogModule "all" enables all LogModules. To enable all
+** LogModule calls to PR_LOG(), say:
+** 
+** set NSPR_LOG_MODULES=all:5
+** 
+** The special LogModule name "sync" tells the NSPR log service to do
+** unbuffered logging.
+** 
+** The special LogModule name "bufsize:<size>" tells NSPR to set the
+** log buffer to <size>.
+**
+** The environment variable NSPR_LOG_FILE specifies the log file to use
+** unless the default of "stderr" is acceptable. For MS Windows
+** systems, NSPR_LOG_FILE can be set to a special value: "WinDebug"
+** (case sensitive). This value causes PR_LOG() output to be written
+** using the Windows API OutputDebugString(). OutputDebugString()
+** writes to the debugger window; some people find this helpful.
+** 
+**
+** To put log messages in your programs, use the PR_LOG macro:
+**
+**     PR_LOG(<module>, <level>, (<printfString>, <args>*));
+**
+** Where <module> is the address of a PRLogModuleInfo structure, and
+** <level> is one of the levels defined by the enumeration:
+** PRLogModuleLevel. <args> is a printf() style of argument list. That
+** is: (fmtstring, ...).
+**
+** Example:
+** 
+** main() {
+**    PRIntn one = 1;
+**    PRLogModuleInfo * myLm = PR_NewLogModule("gizmo");
+**    PR_LOG( myLm, PR_LOG_ALWAYS, ("Log this! %d\n", one)); 
+**    return; 
+** }
+** 
+** Note the use of printf() style arguments as the third agrument(s) to
+** PR_LOG().
+** 
+** After compiling and linking you application, set the environment:
+** 
+** set NSPR_LOG_MODULES=gizmo:5
+** set NSPR_LOG_FILE=logfile.txt
+** 
+** When you execute your application, the string "Log this! 1" will be
+** written to the file "logfile.txt".
+** 
+** Note to NSPR engineers: a number of PRLogModuleInfo structures are
+** defined and initialized in prinit.c. See this module for ideas on
+** what to log where.
+** 
+*/
+
+typedef enum PRLogModuleLevel {
+    PR_LOG_NONE = 0,                /* nothing */
+    PR_LOG_ALWAYS = 1,              /* always printed */
+    PR_LOG_ERROR = 2,               /* error messages */
+    PR_LOG_WARNING = 3,             /* warning messages */
+    PR_LOG_DEBUG = 4,               /* debug messages */
+
+    PR_LOG_NOTICE = PR_LOG_DEBUG,   /* notice messages */
+    PR_LOG_WARN = PR_LOG_WARNING,   /* warning messages */
+    PR_LOG_MIN = PR_LOG_DEBUG,      /* minimal debugging messages */
+    PR_LOG_MAX = PR_LOG_DEBUG       /* maximal debugging messages */
+} PRLogModuleLevel;
+
+/*
+** One of these structures is created for each module that uses logging.
+**    "name" is the name of the module
+**    "level" is the debugging level selected for that module
+*/
+typedef struct PRLogModuleInfo {
+    const char *name;
+    PRLogModuleLevel level;
+    struct PRLogModuleInfo *next;
+} PRLogModuleInfo;
+
+/*
+** Create a new log module.
+*/
+NSPR_API(PRLogModuleInfo*) PR_NewLogModule(const char *name);
+
+/*
+** Set the file to use for logging. Returns PR_FALSE if the file cannot
+** be created
+*/
+NSPR_API(PRBool) PR_SetLogFile(const char *name);
+
+/*
+** Set the size of the logging buffer. If "buffer_size" is zero then the
+** logging becomes "synchronous" (or unbuffered).
+*/
+NSPR_API(void) PR_SetLogBuffering(PRIntn buffer_size);
+
+/*
+** Print a string to the log. "fmt" is a PR_snprintf format type. All
+** messages printed to the log are preceeded by the name of the thread
+** and a time stamp. Also, the routine provides a missing newline if one
+** is not provided.
+*/
+NSPR_API(void) PR_LogPrint(const char *fmt, ...);
+
+/*
+** Flush the log to its file.
+*/
+NSPR_API(void) PR_LogFlush(void);
+
+NSPR_API(void) PR_Assert(const char *s, const char *file, PRIntn ln);
+
+#if defined(DEBUG) || defined(FORCE_PR_LOG)
+#define PR_LOGGING 1
+
+#define PR_LOG_TEST(_module,_level) \
+    ((_module)->level >= (_level))
+
+/*
+** Log something.
+**    "module" is the address of a PRLogModuleInfo structure
+**    "level" is the desired logging level
+**    "args" is a variable length list of arguments to print, in the following
+**       format:  ("printf style format string", ...)
+*/
+#define PR_LOG(_module,_level,_args)     \
+    PR_BEGIN_MACRO             \
+      if (PR_LOG_TEST(_module,_level)) { \
+      PR_LogPrint _args;         \
+      }                     \
+    PR_END_MACRO
+
+#else /* defined(DEBUG) || defined(FORCE_PR_LOG) */
+
+#undef PR_LOGGING
+#define PR_LOG_TEST(module,level) 0
+#define PR_LOG(module,level,args)
+
+#endif /* defined(DEBUG) || defined(FORCE_PR_LOG) */
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#ifdef PR_LOGGING
+#define PR_LOG_BEGIN    PR_LOG
+#define PR_LOG_END      PR_LOG
+#define PR_LOG_DEFINE   PR_NewLogModule
+#else
+#define PR_LOG_BEGIN(module,level,args)
+#define PR_LOG_END(module,level,args)
+#define PR_LOG_DEFINE(_name)    NULL
+#endif /* PR_LOGGING */
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
+
+#define PR_ASSERT(_expr) \
+    ((_expr)?((void)0):PR_Assert(# _expr,__FILE__,__LINE__))
+
+#define PR_NOT_REACHED(_reasonStr) \
+    PR_Assert(_reasonStr,__FILE__,__LINE__)
+
+#else
+
+#define PR_ASSERT(expr) ((void) 0)
+#define PR_NOT_REACHED(reasonStr)
+
+#endif /* defined(DEBUG) || defined(FORCE_PR_ASSERT) */
+
+PR_END_EXTERN_C
+
+#endif /* prlog_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prlong.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prlong.h
new file mode 100644
index 0000000..9523d30
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prlong.h
@@ -0,0 +1,435 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:                prlong.h
+** Description: Portable access to 64 bit numerics
+**
+** Long-long (64-bit signed integer type) support. Some C compilers
+** don't support 64 bit integers yet, so we use these macros to
+** support both machines that do and don't.
+**/
+#ifndef prlong_h___
+#define prlong_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/***********************************************************************
+** DEFINES:     LL_MaxInt
+**              LL_MinInt
+**              LL_Zero
+**              LL_MaxUint
+** DESCRIPTION:
+**      Various interesting constants and static variable
+**      initializer
+***********************************************************************/
+NSPR_API(PRInt64) LL_MaxInt(void);
+NSPR_API(PRInt64) LL_MinInt(void);
+NSPR_API(PRInt64) LL_Zero(void);
+NSPR_API(PRUint64) LL_MaxUint(void);
+
+#if defined(HAVE_LONG_LONG)
+
+/* Keep this in sync with prtypes.h. */
+#if PR_BYTES_PER_LONG == 8 && !defined(__APPLE__)
+#define LL_MAXINT   9223372036854775807L
+#define LL_MININT   (-LL_MAXINT - 1L)
+#define LL_ZERO     0L
+#define LL_MAXUINT  18446744073709551615UL
+#define LL_INIT(hi, lo)  ((hi ## L << 32) + lo ## L)
+#elif defined(WIN32) && !defined(__GNUC__)
+#define LL_MAXINT   9223372036854775807i64
+#define LL_MININT   (-LL_MAXINT - 1i64)
+#define LL_ZERO     0i64
+#define LL_MAXUINT  18446744073709551615ui64
+#define LL_INIT(hi, lo)  ((hi ## i64 << 32) + lo ## i64)
+#else
+#define LL_MAXINT   9223372036854775807LL
+#define LL_MININT   (-LL_MAXINT - 1LL)
+#define LL_ZERO     0LL
+#define LL_MAXUINT  18446744073709551615ULL
+#define LL_INIT(hi, lo)  ((hi ## LL << 32) + lo ## LL)
+#endif
+
+/***********************************************************************
+** MACROS:      LL_*
+** DESCRIPTION:
+**      The following macros define portable access to the 64 bit
+**      math facilities.
+**
+***********************************************************************/
+
+/***********************************************************************
+** MACROS:      LL_<relational operators>
+**
+**  LL_IS_ZERO        Test for zero
+**  LL_EQ             Test for equality
+**  LL_NE             Test for inequality
+**  LL_GE_ZERO        Test for zero or positive
+**  LL_CMP            Compare two values
+***********************************************************************/
+#define LL_IS_ZERO(a)       ((a) == 0)
+#define LL_EQ(a, b)         ((a) == (b))
+#define LL_NE(a, b)         ((a) != (b))
+#define LL_GE_ZERO(a)       ((a) >= 0)
+#define LL_CMP(a, op, b)    ((PRInt64)(a) op (PRInt64)(b))
+#define LL_UCMP(a, op, b)   ((PRUint64)(a) op (PRUint64)(b))
+
+/***********************************************************************
+** MACROS:      LL_<logical operators>
+**
+**  LL_AND            Logical and
+**  LL_OR             Logical or
+**  LL_XOR            Logical exclusion
+**  LL_OR2            A disgusting deviation
+**  LL_NOT            Negation (one's complement)
+***********************************************************************/
+#define LL_AND(r, a, b)        ((r) = (a) & (b))
+#define LL_OR(r, a, b)        ((r) = (a) | (b))
+#define LL_XOR(r, a, b)        ((r) = (a) ^ (b))
+#define LL_OR2(r, a)        ((r) = (r) | (a))
+#define LL_NOT(r, a)        ((r) = ~(a))
+
+/***********************************************************************
+** MACROS:      LL_<mathematical operators>
+**
+**  LL_NEG            Negation (two's complement)
+**  LL_ADD            Summation (two's complement)
+**  LL_SUB            Difference (two's complement)
+***********************************************************************/
+#define LL_NEG(r, a)        ((r) = -(a))
+#define LL_ADD(r, a, b)     ((r) = (a) + (b))
+#define LL_SUB(r, a, b)     ((r) = (a) - (b))
+
+/***********************************************************************
+** MACROS:      LL_<mathematical operators>
+**
+**  LL_MUL            Product (two's complement)
+**  LL_DIV            Quotient (two's complement)
+**  LL_MOD            Modulus (two's complement)
+***********************************************************************/
+#define LL_MUL(r, a, b)        ((r) = (a) * (b))
+#define LL_DIV(r, a, b)        ((r) = (a) / (b))
+#define LL_MOD(r, a, b)        ((r) = (a) % (b))
+
+/***********************************************************************
+** MACROS:      LL_<shifting operators>
+**
+**  LL_SHL            Shift left [0..64] bits
+**  LL_SHR            Shift right [0..64] bits with sign extension
+**  LL_USHR           Unsigned shift right [0..64] bits
+**  LL_ISHL           Signed shift left [0..64] bits
+***********************************************************************/
+#define LL_SHL(r, a, b)     ((r) = (PRInt64)(a) << (b))
+#define LL_SHR(r, a, b)     ((r) = (PRInt64)(a) >> (b))
+#define LL_USHR(r, a, b)    ((r) = (PRUint64)(a) >> (b))
+#define LL_ISHL(r, a, b)    ((r) = (PRInt64)(a) << (b))
+
+/***********************************************************************
+** MACROS:      LL_<conversion operators>
+**
+**  LL_L2I            Convert to signed 32 bit
+**  LL_L2UI           Convert to unsigned 32 bit
+**  LL_L2F            Convert to floating point
+**  LL_L2D            Convert to floating point
+**  LL_I2L            Convert signed to 64 bit
+**  LL_UI2L           Convert unsigned to 64 bit
+**  LL_F2L            Convert float to 64 bit
+**  LL_D2L            Convert float to 64 bit
+***********************************************************************/
+#define LL_L2I(i, l)        ((i) = (PRInt32)(l))
+#define LL_L2UI(ui, l)        ((ui) = (PRUint32)(l))
+#define LL_L2F(f, l)        ((f) = (PRFloat64)(l))
+#define LL_L2D(d, l)        ((d) = (PRFloat64)(l))
+
+#define LL_I2L(l, i)        ((l) = (PRInt64)(i))
+#define LL_UI2L(l, ui)        ((l) = (PRInt64)(ui))
+#define LL_F2L(l, f)        ((l) = (PRInt64)(f))
+#define LL_D2L(l, d)        ((l) = (PRInt64)(d))
+
+/***********************************************************************
+** MACROS:      LL_UDIVMOD
+** DESCRIPTION:
+**  Produce both a quotient and a remainder given an unsigned 
+** INPUTS:      PRUint64 a: The dividend of the operation
+**              PRUint64 b: The quotient of the operation
+** OUTPUTS:     PRUint64 *qp: pointer to quotient
+**              PRUint64 *rp: pointer to remainder
+***********************************************************************/
+#define LL_UDIVMOD(qp, rp, a, b) \
+    (*(qp) = ((PRUint64)(a) / (b)), \
+     *(rp) = ((PRUint64)(a) % (b)))
+
+#else  /* !HAVE_LONG_LONG */
+
+#define LL_MAXINT   LL_MaxInt()
+#define LL_MININT   LL_MinInt()
+#define LL_ZERO     LL_Zero()
+#define LL_MAXUINT  LL_MaxUint()
+
+#ifdef IS_LITTLE_ENDIAN
+#define LL_INIT(hi, lo) {PR_UINT32(lo), PR_UINT32(hi)}
+#else
+#define LL_INIT(hi, lo) {PR_UINT32(hi), PR_UINT32(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)    (((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, \
+                 (r).hi = (r).hi | (a).hi)
+#define LL_NOT(r, a)        ((r).lo = ~(a).lo, \
+                 (r).hi = ~(a).hi)
+
+#define LL_NEG(r, a)        ((r).lo = -(PRInt32)(a).lo, \
+                 (r).hi = -(PRInt32)(a).hi - ((r).lo != 0))
+#define LL_ADD(r, a, b) { \
+    PRInt64 _a, _b; \
+    _a = a; _b = b; \
+    (r).lo = _a.lo + _b.lo; \
+    (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \
+}
+
+#define LL_SUB(r, a, b) { \
+    PRInt64 _a, _b; \
+    _a = a; _b = b; \
+    (r).lo = _a.lo - _b.lo; \
+    (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \
+}
+
+#define LL_MUL(r, a, b) { \
+    PRInt64 _a, _b; \
+    _a = a; _b = b; \
+    LL_MUL32(r, _a.lo, _b.lo); \
+    (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
+}
+
+#define _lo16(a)        ((a) & PR_BITMASK(16))
+#define _hi16(a)        ((a) >> 16)
+
+#define LL_MUL32(r, a, b) { \
+     PRUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
+     _a1 = _hi16(a), _a0 = _lo16(a); \
+     _b1 = _hi16(b), _b0 = _lo16(b); \
+     _y0 = _a0 * _b0; \
+     _y1 = _a0 * _b1; \
+     _y2 = _a1 * _b0; \
+     _y3 = _a1 * _b1; \
+     _y1 += _hi16(_y0);                         /* can't carry */ \
+     _y1 += _y2;                                /* might carry */ \
+     if (_y1 < _y2)    \
+        _y3 += (PRUint32)(PR_BIT(16));  /* propagate */ \
+     (r).lo = (_lo16(_y1) << 16) + _lo16(_y0); \
+     (r).hi = _y3 + _hi16(_y1); \
+}
+
+#define LL_UDIVMOD(qp, rp, a, b)    ll_udivmod(qp, rp, a, b)
+
+NSPR_API(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b);
+
+#define LL_DIV(r, a, b) { \
+    PRInt64 _a, _b; \
+    PRUint32 _negative = (PRInt32)(a).hi < 0; \
+    if (_negative) { \
+    LL_NEG(_a, a); \
+    } else { \
+    _a = a; \
+    } \
+    if ((PRInt32)(b).hi < 0) { \
+    _negative ^= 1; \
+    LL_NEG(_b, b); \
+    } else { \
+    _b = b; \
+    } \
+    LL_UDIVMOD(&(r), 0, _a, _b); \
+    if (_negative) \
+    LL_NEG(r, r); \
+}
+
+#define LL_MOD(r, a, b) { \
+    PRInt64 _a, _b; \
+    PRUint32 _negative = (PRInt32)(a).hi < 0; \
+    if (_negative) { \
+    LL_NEG(_a, a); \
+    } else { \
+    _a = a; \
+    } \
+    if ((PRInt32)(b).hi < 0) { \
+    LL_NEG(_b, b); \
+    } else { \
+    _b = b; \
+    } \
+    LL_UDIVMOD(0, &(r), _a, _b); \
+    if (_negative) \
+    LL_NEG(r, r); \
+}
+
+#define LL_SHL(r, a, b) { \
+    if (b) { \
+    PRInt64 _a; \
+        _a = a; \
+        if ((b) < 32) { \
+        (r).lo = _a.lo << ((b) & 31); \
+        (r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \
+    } else { \
+        (r).lo = 0; \
+        (r).hi = _a.lo << ((b) & 31); \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+/* a is an PRInt32, b is PRInt32, r is PRInt64 */
+#define LL_ISHL(r, a, b) { \
+    if (b) { \
+    PRInt64 _a; \
+    _a.lo = (a); \
+    _a.hi = 0; \
+        if ((b) < 32) { \
+        (r).lo = (a) << ((b) & 31); \
+        (r).hi = ((a) >> (32 - (b))); \
+    } else { \
+        (r).lo = 0; \
+        (r).hi = (a) << ((b) & 31); \
+    } \
+    } else { \
+    (r).lo = (a); \
+    (r).hi = 0; \
+    } \
+}
+
+#define LL_SHR(r, a, b) { \
+    if (b) { \
+    PRInt64 _a; \
+        _a = a; \
+    if ((b) < 32) { \
+        (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
+        (r).hi = (PRInt32)_a.hi >> ((b) & 31); \
+    } else { \
+        (r).lo = (PRInt32)_a.hi >> ((b) & 31); \
+        (r).hi = (PRInt32)_a.hi >> 31; \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+#define LL_USHR(r, a, b) { \
+    if (b) { \
+    PRInt64 _a; \
+        _a = a; \
+    if ((b) < 32) { \
+        (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
+        (r).hi = _a.hi >> ((b) & 31); \
+    } else { \
+        (r).lo = _a.hi >> ((b) & 31); \
+        (r).hi = 0; \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+#define LL_L2I(i, l)        ((i) = (l).lo)
+#define LL_L2UI(ui, l)        ((ui) = (l).lo)
+#define LL_L2F(f, l)        { double _d; LL_L2D(_d, l); (f) = (PRFloat64)_d; }
+
+#define LL_L2D(d, l) { \
+    int _negative; \
+    PRInt64 _absval; \
+ \
+    _negative = (l).hi >> 31; \
+    if (_negative) { \
+    LL_NEG(_absval, l); \
+    } else { \
+    _absval = l; \
+    } \
+    (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \
+    if (_negative) \
+    (d) = -(d); \
+}
+
+#define LL_I2L(l, i)        { PRInt32 _i = ((PRInt32)(i)) >> 31; (l).lo = (i); (l).hi = _i; }
+#define LL_UI2L(l, ui)      ((l).lo = (ui), (l).hi = 0)
+#define LL_F2L(l, f)        { double _d = (double)f; LL_D2L(l, _d); }
+
+#define LL_D2L(l, d) { \
+    int _negative; \
+    double _absval, _d_hi; \
+    PRInt64 _lo_d; \
+ \
+    _negative = ((d) < 0); \
+    _absval = _negative ? -(d) : (d); \
+ \
+    (l).hi = _absval / 4.294967296e9; \
+    (l).lo = 0; \
+    LL_L2D(_d_hi, l); \
+    _absval -= _d_hi; \
+    _lo_d.hi = 0; \
+    if (_absval < 0) { \
+    _lo_d.lo = -_absval; \
+    LL_SUB(l, l, _lo_d); \
+    } else { \
+    _lo_d.lo = _absval; \
+    LL_ADD(l, l, _lo_d); \
+    } \
+ \
+    if (_negative) \
+    LL_NEG(l, l); \
+}
+
+#endif /* !HAVE_LONG_LONG */
+
+PR_END_EXTERN_C
+
+#endif /* prlong_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prmem.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prmem.h
new file mode 100644
index 0000000..1cf0949
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prmem.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: prmem.h
+** Description: API to NSPR memory management functions
+**
+*/
+#ifndef prmem_h___
+#define prmem_h___
+
+#include "prtypes.h"
+#include <stdlib.h>
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Thread safe memory allocation.
+**
+** NOTE: pr wraps up malloc, free, calloc, realloc so they are already
+** thread safe (and are not declared here - look in stdlib.h).
+*/
+
+/*
+** PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free have the same signatures
+** as their libc equivalent malloc, calloc, realloc, and free, and have
+** the same semantics.  (Note that the argument type size_t is replaced
+** by PRUint32.)  Memory allocated by PR_Malloc, PR_Calloc, or PR_Realloc
+** must be freed by PR_Free.
+*/
+
+NSPR_API(void *) PR_Malloc(PRUint32 size);
+
+NSPR_API(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize);
+
+NSPR_API(void *) PR_Realloc(void *ptr, PRUint32 size);
+
+NSPR_API(void) PR_Free(void *ptr);
+
+/*
+** The following are some convenience macros defined in terms of
+** PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free.
+*/
+
+/***********************************************************************
+** FUNCTION:	PR_MALLOC()
+** DESCRIPTION:
+**   PR_NEW() allocates an untyped item of size _size from the heap.
+** INPUTS:  _size: size in bytes of item to be allocated
+** OUTPUTS:	untyped pointer to the node allocated
+** RETURN:	pointer to node or error returned from malloc().
+***********************************************************************/
+#define PR_MALLOC(_bytes) (PR_Malloc((_bytes)))
+
+/***********************************************************************
+** FUNCTION:	PR_NEW()
+** DESCRIPTION:
+**   PR_NEW() allocates an item of type _struct from the heap.
+** INPUTS:  _struct: a data type
+** OUTPUTS:	pointer to _struct
+** RETURN:	pointer to _struct or error returns from malloc().
+***********************************************************************/
+#define PR_NEW(_struct) ((_struct *) PR_MALLOC(sizeof(_struct)))
+
+/***********************************************************************
+** FUNCTION:	PR_REALLOC()
+** DESCRIPTION:
+**   PR_REALLOC() re-allocates _ptr bytes from the heap as a _size
+**   untyped item.
+** INPUTS:	_ptr: pointer to node to reallocate
+**          _size: size of node to allocate
+** OUTPUTS:	pointer to node allocated
+** RETURN:	pointer to node allocated
+***********************************************************************/
+#define PR_REALLOC(_ptr, _size) (PR_Realloc((_ptr), (_size)))
+
+/***********************************************************************
+** FUNCTION:	PR_CALLOC()
+** DESCRIPTION:
+**   PR_CALLOC() allocates a _size bytes untyped item from the heap
+**   and sets the allocated memory to all 0x00.
+** INPUTS:	_size: size of node to allocate
+** OUTPUTS:	pointer to node allocated
+** RETURN:	pointer to node allocated
+***********************************************************************/
+#define PR_CALLOC(_size) (PR_Calloc(1, (_size)))
+
+/***********************************************************************
+** FUNCTION:	PR_NEWZAP()
+** DESCRIPTION:
+**   PR_NEWZAP() allocates an item of type _struct from the heap
+**   and sets the allocated memory to all 0x00.
+** INPUTS:	_struct: a data type
+** OUTPUTS:	pointer to _struct
+** RETURN:	pointer to _struct
+***********************************************************************/
+#define PR_NEWZAP(_struct) ((_struct*)PR_Calloc(1, sizeof(_struct)))
+
+/***********************************************************************
+** FUNCTION:	PR_DELETE()
+** DESCRIPTION:
+**   PR_DELETE() unallocates an object previosly allocated via PR_NEW()
+**   or PR_NEWZAP() to the heap.
+** INPUTS:	pointer to previously allocated object
+** OUTPUTS:	the referenced object is returned to the heap
+** RETURN:	void
+***********************************************************************/
+#define PR_DELETE(_ptr) { PR_Free(_ptr); (_ptr) = NULL; }
+
+/***********************************************************************
+** FUNCTION:	PR_FREEIF()
+** DESCRIPTION:
+**   PR_FREEIF() conditionally unallocates an object previously allocated
+**   vial PR_NEW() or PR_NEWZAP(). If the pointer to the object is
+**   equal to zero (0), the object is not released.
+** INPUTS:	pointer to previously allocated object
+** OUTPUTS:	the referenced object is conditionally returned to the heap
+** RETURN:	void
+***********************************************************************/
+#define PR_FREEIF(_ptr)	if (_ptr) PR_DELETE(_ptr)
+
+PR_END_EXTERN_C
+
+#endif /* prmem_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prmon.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prmon.h
new file mode 100644
index 0000000..0fe18dc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prmon.h
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prmon_h___
+#define prmon_h___
+
+#include "prtypes.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRMonitor PRMonitor;
+
+/*
+** Create a new monitor. Monitors are re-entrant locks with a single built-in
+** condition variable.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low.
+*/
+NSPR_API(PRMonitor*) PR_NewMonitor(void);
+
+/*
+** Destroy a monitor. The caller is responsible for guaranteeing that the
+** monitor is no longer in use. There must be no thread waiting on the monitor's
+** condition variable and that the lock is not held.
+**
+*/
+NSPR_API(void) PR_DestroyMonitor(PRMonitor *mon);
+
+/*
+** Enter the lock associated with the monitor. If the calling thread currently
+** is in the monitor, the call to enter will silently succeed. In either case,
+** it will increment the entry count by one.
+*/
+NSPR_API(void) PR_EnterMonitor(PRMonitor *mon);
+
+/*
+** Decrement the entry count associated with the monitor. If the decremented
+** entry count is zero, the monitor is exited. Returns PR_FAILURE if the
+** calling thread has not entered the monitor.
+*/
+NSPR_API(PRStatus) PR_ExitMonitor(PRMonitor *mon);
+
+/*
+** Wait for a notify on the monitor's condition variable. Sleep for "ticks"
+** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is
+** indefinite).
+**
+** While the thread is waiting it exits the monitor (as if it called
+** PR_ExitMonitor as many times as it had called PR_EnterMonitor).  When
+** the wait has finished the thread regains control of the monitors lock
+** with the same entry count as before the wait began.
+**
+** The thread waiting on the monitor will be resumed when the monitor is
+** notified (assuming the thread is the next in line to receive the
+** notify) or when the "ticks" timeout elapses.
+**
+** Returns PR_FAILURE if the caller has not entered the monitor.
+*/
+NSPR_API(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks);
+
+/*
+** Notify a thread waiting on the monitor's condition variable. If a thread
+** is waiting on the condition variable (using PR_Wait) then it is awakened
+** and attempts to reenter the monitor.
+*/
+NSPR_API(PRStatus) PR_Notify(PRMonitor *mon);
+
+/*
+** Notify all of the threads waiting on the monitor's condition variable.
+** All of threads waiting on the condition are scheduled to reenter the
+** monitor.
+*/
+NSPR_API(PRStatus) PR_NotifyAll(PRMonitor *mon);
+
+/*
+** PR_ASSERT_CURRENT_THREAD_IN_MONITOR
+** If the current thread is in |mon|, this assertion is guaranteed to
+** succeed.  Otherwise, the behavior of this function is undefined.
+*/
+#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
+#define PR_ASSERT_CURRENT_THREAD_IN_MONITOR(/* PRMonitor* */ mon) \
+    PR_AssertCurrentThreadInMonitor(mon)
+#else
+#define PR_ASSERT_CURRENT_THREAD_IN_MONITOR(/* PRMonitor* */ mon)
+#endif
+
+/* Don't call this function directly. */
+NSPR_API(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon);
+
+PR_END_EXTERN_C
+
+#endif /* prmon_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prmwait.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prmwait.h
new file mode 100644
index 0000000..e4cabda
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prmwait.h
@@ -0,0 +1,412 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#if defined(_PRMWAIT_H)
+#else
+#define _PRMWAIT_H
+
+#include "prio.h"
+#include "prtypes.h"
+#include "prclist.h"
+
+PR_BEGIN_EXTERN_C
+
+/********************************************************************************/
+/********************************************************************************/
+/********************************************************************************/
+/******************************       WARNING        ****************************/
+/********************************************************************************/
+/**************************** This is work in progress. *************************/
+/************************** Do not make any assumptions *************************/
+/************************** about the stability of this *************************/
+/************************** API or the underlying imple- ************************/
+/************************** mentation.                   ************************/
+/********************************************************************************/
+/********************************************************************************/
+
+/*
+** STRUCTURE:   PRWaitGroup
+** DESCRIPTION:
+**      The client may define several wait groups in order to semantically
+**      tie a collection of file descriptors for a single purpose. This allows
+**      easier dispatching of threads that returned with active file descriptors
+**      from the wait function.
+*/
+typedef struct PRWaitGroup PRWaitGroup;
+
+/*
+** ENUMERATION: PRMWStatus
+** DESCRIPTION:
+**      This enumeration is used to indicate the completion status of
+**      a receive wait object. Generally stated, a positive value indicates
+**      that the operation is not yet complete. A zero value indicates
+**      success (similar to PR_SUCCESS) and any negative value is an
+**      indication of failure. The reason for the failure can be retrieved
+**      by calling PR_GetError().
+**
+**  PR_MW_PENDING       The operation is still pending. None of the other
+**                      fields of the object are currently valid.
+**  PR_MW_SUCCESS       The operation is complete and it was successful.
+**  PR_MW_FAILURE       The operation failed. The reason for the failure
+**                      can be retrieved by calling PR_GetError().
+**  PR_MW_TIMEOUT       The amount of time allowed for by the object's
+**                      'timeout' field has expired w/o the operation
+**                      otherwise coming to closure.
+**  PR_MW_INTERRUPT     The operation was cancelled, either by the client
+**                      calling PR_CancelWaitFileDesc() or destroying the
+**                      entire wait group (PR_DestroyWaitGroup()).
+*/
+typedef enum PRMWStatus
+{
+    PR_MW_PENDING = 1,
+    PR_MW_SUCCESS = 0,
+    PR_MW_FAILURE = -1,
+    PR_MW_TIMEOUT = -2,
+    PR_MW_INTERRUPT = -3
+} PRMWStatus;
+
+/*
+** STRUCTURE:   PRMemoryDescriptor
+** DESCRIPTION:
+**      THis is a descriptor for an interval of memory. It contains a
+**      pointer to the first byte of that memory and the length (in
+**      bytes) of the interval.
+*/
+typedef struct PRMemoryDescriptor
+{
+    void *start;                /* pointer to first byte of memory */
+    PRSize length;              /* length (in bytes) of memory interval */
+} PRMemoryDescriptor;
+
+/*
+** STRUCTURE:   PRMWaitClientData
+** DESCRIPTION:
+**      An opague stucture for which a client MAY give provide a concrete
+**      definition and associate with a receive descriptor. The NSPR runtime
+**      does not manage this field. It is completely up to the client.
+*/
+typedef struct PRMWaitClientData PRMWaitClientData;
+
+/*
+** STRUCTURE:   PRRecvWait
+** DESCRIPTION:
+**      A receive wait object contains the file descriptor that is subject
+**      to the wait and the amount of time (beginning epoch established
+**      when the object is presented to the runtime) the the channel should
+**      block before abandoning the process.
+**
+**      The success of the wait operation will be noted in the object's
+**      'outcome' field. The fields are not valid when the NSPR runtime
+**      is in possession of the object.
+**
+**      The memory descriptor describes an interval of writable memory
+**      in the caller's address space where data from an initial read
+**      can be placed. The description may indicate a null interval.
+*/
+typedef struct PRRecvWait 
+{
+    PRCList internal;           /* internal runtime linkages */
+
+    PRFileDesc *fd;             /* file descriptor associated w/ object */
+    PRMWStatus outcome;         /* outcome of the current/last operation */
+    PRIntervalTime timeout;     /* time allowed for entire operation */
+
+    PRInt32 bytesRecv;          /* number of bytes transferred into buffer */
+    PRMemoryDescriptor buffer;  /* where to store first segment of input data */
+    PRMWaitClientData *client;  /* pointer to arbitrary client defined data */
+} PRRecvWait;
+
+/*
+** STRUCTURE:   PRMWaitEnumerator
+** DESCRIPTION:
+**      An enumeration object is used to store the state of an existing
+**      enumeration over a wait group. The opaque object must be allocated
+**      by the client and the reference presented on each call to the
+**      pseudo-stateless enumerator. The enumeration objects are sharable
+**      only in serial fashion.
+*/
+typedef struct PRMWaitEnumerator PRMWaitEnumerator;
+
+
+/*
+** FUNCTION:    PR_AddWaitFileDesc
+** DESCRIPTION:
+**      This function will effectively add a file descriptor to the
+**      list of those waiting for network receive. The new descriptor
+**      will be semantically tied to the wait group specified.
+**
+**      The ownership for the storage pointed to by 'desc' is temporarily
+**      passed over the the NSPR runtime. It will be handed back by the
+**      function PR_WaitRecvReady().
+**
+**  INPUTS
+**      group       A reference to a PRWaitGroup or NULL. Wait groups are
+**                  created by calling PR_CreateWaitGroup() and are used
+**                  to semantically group various file descriptors by the
+**                  client's application.
+**      desc        A reference to a valid PRRecvWait. The object of the
+**                  reference must be preserved and not be modified
+**                  until its ownership is returned to the client.
+**  RETURN
+**      PRStatus    An indication of success. If equal to PR_FAILUE details
+**                  of the failure are avaiable via PR_GetError().
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  Invalid 'group' identifier or duplicate 'desc' object.
+**      PR_OUT_OF_MEMORY_ERROR
+**                  Insuffient memory for internal data structures.
+**      PR_INVALID_STATE_ERROR
+**                  The group is being destroyed.
+*/
+NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);
+
+/*
+** FUNCTION:    PR_WaitRecvReady
+** DESCRIPTION:
+**      PR_WaitRecvReady will block the calling thread until one of the
+**      file descriptors that have been added via PR_AddWaitFileDesc is
+**      available for input I/O.
+**  INPUT
+**      group       A pointer to a valid PRWaitGroup or NULL (the null
+**                  group. The function will block the caller until a
+**                  channel from the wait group becomes ready for receive
+**                  or there is some sort of error.
+**  RETURN
+**      PRReciveWait
+**                  When the caller is resumed it is either returned a
+**                  valid pointer to a previously added receive wait or
+**                  a NULL. If the latter, the function has terminated
+**                  for a reason that can be determined by calling
+**                  PR_GetError().
+**                  If a valid pointer is returned, the reference is to the
+**                  file descriptor contained in the receive wait object.
+**                  The outcome of the wait operation may still fail, and
+**                  if it has, that fact will be noted in the object's
+**                  outcome field. Details can be retrieved from PR_GetError().
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The 'group' is not known by the runtime.
+**      PR_PENDING_INTERRUPT_ERROR
+                    The thread was interrupted.
+**      PR_INVALID_STATE_ERROR
+**                  The group is being destroyed.
+*/
+NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group);
+
+/*
+** FUNCTION:    PR_CancelWaitFileDesc
+** DESCRIPTION:
+**      PR_CancelWaitFileDesc is provided as a means for cancelling operations
+**      on objects previously submitted by use of PR_AddWaitFileDesc(). If
+**      the runtime knows of the object, it will be marked as having failed
+**      because it was interrupted (similar to PR_Interrupt()). The first
+**      available thread waiting on the group will be made to return the
+**      PRRecvWait object with the outcome noted.
+**
+**  INPUTS
+**      group       The wait group under which the wait receive object was
+**                  added.
+**      desc        A pointer to the wait receive object that is to be
+**                  cancelled.
+**  RETURN
+**      PRStatus    If the wait receive object was located and associated
+**                  with the specified wait group, the status returned will
+**                  be PR_SUCCESS. There is still a race condition that would
+**                  permit the offected object to complete normally, but it
+**                  is assured that it will complete in the near future.
+**                  If the receive object or wait group are invalid, the
+**                  function will return with a status of PR_FAILURE.
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The 'group' argument is not recognized as a valid group.
+**      PR_COLLECTION_EMPTY_ERROR
+**                  There are no more receive wait objects in the group's
+**                  collection.
+**      PR_INVALID_STATE_ERROR
+**                  The group is being destroyed.
+*/
+NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);
+
+/*
+** FUNCTION:    PR_CancelWaitGroup
+** DESCRIPTION:
+**      PR_CancelWaitGroup is provided as a means for cancelling operations
+**      on objects previously submitted by use of PR_AddWaitFileDesc(). Each
+**      successive call will return a pointer to a PRRecvWait object that
+**      was previously registered via PR_AddWaitFileDesc(). If no wait
+**      objects are associated with the wait group, a NULL will be returned.
+**      This function should be called in a loop until a NULL is returned
+**      to reclaim all the wait objects prior to calling PR_DestroyWaitGroup().
+**
+**  INPUTS
+**      group       The wait group under which the wait receive object was
+**                  added.
+**  RETURN
+**      PRRecvWait* If the wait group is valid and at least one receive wait
+**                  object is present in the group, that object will be
+**                  marked as PR_MW_INTERRUPT'd and removed from the group's
+**                  queues. Otherwise a NULL will be returned and the reason
+**                  for the NULL may be retrieved by calling PR_GetError().
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**      PR_GROUP_EMPTY_ERROR
+*/
+NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group);
+
+/*
+** FUNCTION:    PR_CreateWaitGroup
+** DESCRIPTION:
+**      A wait group is an opaque object that a client may create in order
+**      to semantically group various wait requests. Each wait group is
+**      unique, including the default wait group (NULL). A wait request
+**      that was added under a wait group will only be serviced by a caller
+**      that specified the same wait group.
+**
+**  INPUT
+**      size        The size of the hash table to be used to contain the
+**                  receive wait objects. This is just the initial size.
+**                  It will grow as it needs to, but to avoid that hassle
+**                  one can suggest a suitable size initially. It should
+**                  be ~30% larger than the maximum number of receive wait
+**                  objects expected.
+**  RETURN
+**      PRWaitGroup If successful, the function will return a pointer to an
+**                  object that was allocated by and owned by the runtime.
+**                  The reference remains valid until it is explicitly destroyed
+**                  by calling PR_DestroyWaitGroup().
+**
+**  ERRORS
+**      PR_OUT_OF_MEMORY_ERROR
+*/
+NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size);
+
+/*
+** FUNCTION:    PR_DestroyWaitGroup
+** DESCRIPTION:
+**      Undo the effects of PR_CreateWaitGroup(). Any receive wait operations
+**      on the group will be treated as if the each had been the target of a
+**      PR_CancelWaitFileDesc().
+**
+**  INPUT
+**      group       Reference to a wait group previously allocated using
+**                  PR_CreateWaitGroup().
+**  RETURN
+**      PRStatus    Will be PR_SUCCESS if the wait group was valid and there
+**                  are no receive wait objects in that group. Otherwise
+**                  will indicate PR_FAILURE.
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The 'group' argument does not reference a known object.
+**      PR_INVALID_STATE_ERROR
+**                  The group still contains receive wait objects.
+*/
+NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group);
+
+/*
+** FUNCTION:    PR_CreateMWaitEnumerator
+** DESCRIPTION:
+**      The PR_CreateMWaitEnumerator() function returns a reference to an
+**      opaque PRMWaitEnumerator object. The enumerator object is required
+**      as an argument for each successive call in the stateless enumeration
+**      of the indicated wait group.
+**
+**      group       The wait group that the enumeration is intended to
+**                  process. It may be be the default wait group (NULL).
+** RETURN
+**      PRMWaitEnumerator* group
+**                  A reference to an object that will be used to store
+**                  intermediate state of enumerations.
+** ERRORS
+**      Errors are indicated by the function returning a NULL.
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The 'group' argument does not reference a known object.
+**      PR_OUT_OF_MEMORY_ERROR
+*/
+NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group);
+
+/*
+** FUNCTION:    PR_DestroyMWaitEnumerator
+** DESCRIPTION:
+**      Destroys the object created by PR_CreateMWaitEnumerator(). The reference
+**      used as an argument becomes invalid.
+**
+** INPUT
+**      PRMWaitEnumerator* enumerator
+**          The PRMWaitEnumerator object to destroy.
+** RETURN
+**      PRStatus
+**          PR_SUCCESS if successful, PR_FAILURE otherwise.
+** ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The enumerator is invalid.
+*/
+NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator);
+
+/*
+** FUNCTION:    PR_EnumerateWaitGroup
+** DESCRIPTION:
+**      PR_EnumerateWaitGroup is a thread safe enumerator over a wait group.
+**      Each call to the enumerator must present a valid PRMWaitEnumerator
+**      rererence and a pointer to the "previous" element returned from the
+**      enumeration process or a NULL.
+**
+**      An enumeration is started by passing a NULL as the "previous" value.
+**      Subsequent calls to the enumerator must pass in the result of the
+**      previous call. The enumeration end is signaled by the runtime returning
+**      a NULL as the result.
+**
+**      Modifications to the content of the wait group are allowed during
+**      an enumeration. The effect is that the enumeration may have to be
+**      "reset" and that may result in duplicates being returned from the
+**      enumeration.
+**
+**      An enumeration may be abandoned at any time. The runtime is not
+**      keeping any state, so there are no issues in that regard.
+*/
+NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup(
+    PRMWaitEnumerator *enumerator, const PRRecvWait *previous);
+   
+PR_END_EXTERN_C
+
+#endif /* defined(_PRMWAIT_H) */
+
+/* prmwait.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prnetdb.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prnetdb.h
new file mode 100644
index 0000000..f1b7ddc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prnetdb.h
@@ -0,0 +1,499 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prnetdb_h___
+#define prnetdb_h___
+
+#include "prtypes.h"
+#include "prio.h"
+
+PR_BEGIN_EXTERN_C
+
+
+/*
+ *********************************************************************
+ *  Translate an Internet address to/from a character string
+ *********************************************************************
+ */
+NSPR_API(PRStatus) PR_StringToNetAddr(
+    const char *string, PRNetAddr *addr);
+
+NSPR_API(PRStatus) PR_NetAddrToString(
+    const PRNetAddr *addr, char *string, PRUint32 size);
+
+/*
+** Structures returned by network data base library.  All addresses are
+** supplied in host order, and returned in network order (suitable for
+** use in system calls).
+*/
+/*
+** Beware that WINSOCK.H defines h_addrtype and h_length as short.
+** Client code does direct struct copies of hostent to PRHostEnt and
+** hence the ifdef.
+*/
+typedef struct PRHostEnt {
+    char *h_name;       /* official name of host */
+    char **h_aliases;   /* alias list */
+#ifdef WIN32
+    PRInt16 h_addrtype; /* host address type */
+    PRInt16 h_length;   /* length of address */
+#else
+    PRInt32 h_addrtype; /* host address type */
+    PRInt32 h_length;   /* length of address */
+#endif
+    char **h_addr_list; /* list of addresses from name server */
+} PRHostEnt;
+
+/* A safe size to use that will mostly work... */
+#if (defined(AIX) && defined(_THREAD_SAFE)) || defined(OSF1)
+#define PR_NETDB_BUF_SIZE sizeof(struct protoent_data)
+#else
+#define PR_NETDB_BUF_SIZE 1024
+#endif
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetHostByName()
+** Lookup a host by name.
+**
+** INPUTS:
+**  char *hostname      Character string defining the host name of interest
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *hostentry
+**                      This structure is filled in by the runtime if
+**                      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().
+***********************************************************************/
+NSPR_API(PRStatus) PR_GetHostByName(
+    const char *hostname, char *buf, PRIntn bufsize, PRHostEnt *hostentry);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetIPNodeByName()
+** Lookup a host by name. Equivalent to getipnodebyname(AI_DEFAULT)
+** of RFC 2553.
+**
+** INPUTS:
+**  char *hostname      Character string defining the host name of interest
+**  PRUint16 af         Address family (either PR_AF_INET or PR_AF_INET6)
+**  PRIntn flags        Specifies the types of addresses that are searched
+**                      for and the types of addresses that are returned.
+**                      The only supported flag is PR_AI_DEFAULT.
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *hostentry
+**                      This structure is filled in by the runtime if
+**                      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_NOCANONNAME 0x8000
+#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);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetHostByAddr()
+** Lookup a host entry by its network address.
+**
+** INPUTS:
+**  char *hostaddr      IP address of host in question
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *hostentry
+**                      This structure is filled in by the runtime if
+**                      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().
+***********************************************************************/
+NSPR_API(PRStatus) PR_GetHostByAddr(
+    const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry);
+
+/***********************************************************************
+** FUNCTION:	PR_EnumerateHostEnt()	
+** DESCRIPTION:
+**  A stateless enumerator over a PRHostEnt structure acquired from
+**  PR_GetHostByName() PR_GetHostByAddr() to evaluate the possible
+**  network addresses.
+**
+** INPUTS:
+**  PRIntn  enumIndex   Index of the enumeration. The enumeration starts
+**                      and ends with a value of zero.
+**
+**  PRHostEnt *hostEnt  A pointer to a host entry struct that was
+**                      previously returned by PR_GetHostByName() or
+**                      PR_GetHostByAddr().
+**
+**  PRUint16 port       The port number to be assigned as part of the
+**                      PRNetAddr.
+**
+** OUTPUTS:
+**  PRNetAddr *address  A pointer to an address structure that will be
+**                      filled in by the call to the enumeration if the
+**                      result of the call is greater than zero.
+**
+** RETURN:
+**  PRIntn              The value that should be used for the next call
+**                      of the enumerator ('enumIndex'). The enumeration
+**                      is ended if this value is returned zero.
+**                      If a value of -1 is returned, the enumeration
+**                      has failed. The reason for the failure can be
+**                      retrieved by calling PR_GetError().
+***********************************************************************/
+NSPR_API(PRIntn) PR_EnumerateHostEnt(
+    PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address);
+
+/***********************************************************************
+** FUNCTION: PR_InitializeNetAddr(), 
+** DESCRIPTION:
+**  Initialize the fields 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:
+**  PRNetAddr *addr     The address to be manipulated.
+**
+** RETURN:
+**  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_IpAddrV4Mapped   /* IPv4 mapped address */
+} PRNetAddrValue;
+
+NSPR_API(PRStatus) PR_InitializeNetAddr(
+    PRNetAddrValue val, PRUint16 port, PRNetAddr *addr);
+
+/***********************************************************************
+** FUNCTION: PR_SetNetAddr(), 
+** DESCRIPTION:
+**  Set the fields of a PRNetAddr, assigning well known values as
+**  appropriate. This function is similar to PR_InitializeNetAddr
+**  but differs in that the address family is specified.
+**
+** 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 af         The address family (either PR_AF_INET or PR_AF_INET6)
+**
+**  PRUint16 port       The port number to be assigned in the structure.
+**
+** OUTPUTS:
+**  PRNetAddr *addr     The address to be manipulated.
+**
+** RETURN:
+**  PRStatus            To indicate success or failure. If the latter, the
+**                      reason for the failure can be retrieved by calling
+**                      PR_GetError();
+***********************************************************************/
+NSPR_API(PRStatus) PR_SetNetAddr(
+    PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_IsNetAddrType()
+** Determine if the network address is of the specified type.
+**
+** INPUTS:
+**  const PRNetAddr *addr   A network address.
+**  PRNetAddrValue          The type of network address 
+**
+** 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:
+**  PRUint16                The 'family' field of 'addr'.
+***********************************************************************/
+#define PR_NetAddrFamily(addr) ((addr)->raw.family)
+
+/***********************************************************************
+** MACRO:	
+** DESCRIPTION:	PR_NetAddrInetPort()
+** Get the 'port' field of a PRNetAddr union.
+**
+** INPUTS:
+**  const PRNetAddr *addr   A network address.
+**
+** RETURN:
+**  PRUint16                The 'port' field of 'addr'.
+***********************************************************************/
+#define PR_NetAddrInetPort(addr) \
+    ((addr)->raw.family == PR_AF_INET6 ? (addr)->ipv6.port : (addr)->inet.port)
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetProtoByName()
+** Lookup a protocol entry based on protocol's name
+**
+** INPUTS:
+**  char *protocolname  Character string of the protocol's name.
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *PRProtoEnt
+**                      This structure is filled in by the runtime if
+**                      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().
+***********************************************************************/
+
+typedef struct PRProtoEnt {
+    char *p_name;       /* official protocol name */
+    char **p_aliases;   /* alias list */
+#ifdef WIN32
+    PRInt16 p_num;      /* protocol # */
+#else
+    PRInt32 p_num;      /* protocol # */
+#endif
+} PRProtoEnt;
+
+NSPR_API(PRStatus) PR_GetProtoByName(
+    const char* protocolname, char* buffer, PRInt32 bufsize, PRProtoEnt* result);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetProtoByNumber()
+** Lookup a protocol entry based on protocol's number
+**
+** INPUTS:
+**  PRInt32 protocolnumber
+**                      Number assigned to the protocol.
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *PRProtoEnt
+**                      This structure is filled in by the runtime if
+**                      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().
+***********************************************************************/
+NSPR_API(PRStatus) PR_GetProtoByNumber(
+    PRInt32 protocolnumber, char* buffer, PRInt32 bufsize, PRProtoEnt* result);
+
+/***********************************************************************
+** FUNCTION:
+** DESCRIPTION: PR_GetAddrInfoByName()
+**  Look up a host by name. Equivalent to getaddrinfo(host, NULL, ...) of
+**  RFC 3493.
+**
+** INPUTS:
+**  char *hostname      Character string defining the host name of interest
+**  PRUint16 af         May be PR_AF_UNSPEC or PR_AF_INET.
+**  PRIntn flags        May be either PR_AI_ADDRCONFIG or
+**                      PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME. Include
+**                      PR_AI_NOCANONNAME to suppress the determination of
+**                      the canonical name corresponding to hostname.
+** RETURN:
+**  PRAddrInfo*         Handle to a data structure containing the results
+**                      of the host lookup. Use PR_EnumerateAddrInfo to
+**                      inspect the PRNetAddr values stored in this object.
+**                      When no longer needed, this handle must be destroyed
+**                      with a call to PR_FreeAddrInfo.  If a lookup error
+**                      occurs, then NULL will be returned.
+***********************************************************************/
+typedef struct PRAddrInfo PRAddrInfo;
+
+NSPR_API(PRAddrInfo*) PR_GetAddrInfoByName(
+    const char *hostname, PRUint16 af, PRIntn flags);
+
+/***********************************************************************
+** FUNCTION:
+** DESCRIPTION: PR_FreeAddrInfo()
+**  Destroy the PRAddrInfo handle allocated by PR_GetAddrInfoByName().
+**
+** INPUTS:
+**  PRAddrInfo *addrInfo
+**                      The handle resulting from a successful call to
+**                      PR_GetAddrInfoByName().
+** RETURN:
+**  void
+***********************************************************************/
+NSPR_API(void) PR_FreeAddrInfo(PRAddrInfo *addrInfo);
+
+/***********************************************************************
+** FUNCTION:
+** DESCRIPTION: PR_EnumerateAddrInfo()
+**  A stateless enumerator over a PRAddrInfo handle acquired from
+**  PR_GetAddrInfoByName() to inspect the possible network addresses.
+**
+** INPUTS:
+**  void *enumPtr       Index pointer of the enumeration. The enumeration
+**                      starts and ends with a value of NULL.
+**  const PRAddrInfo *addrInfo
+**                      The PRAddrInfo handle returned by a successful
+**                      call to PR_GetAddrInfoByName().
+**  PRUint16 port       The port number to be assigned as part of the
+**                      PRNetAddr.
+** OUTPUTS:
+**  PRNetAddr *result   A pointer to an address structure that will be
+**                      filled in by the call to the enumeration if the
+**                      result of the call is not NULL.
+** RETURN:
+**  void*               The value that should be used for the next call
+**                      of the enumerator ('enumPtr'). The enumeration
+**                      is ended if this value is NULL.
+***********************************************************************/
+NSPR_API(void *) PR_EnumerateAddrInfo(
+    void *enumPtr, const PRAddrInfo *addrInfo, PRUint16 port, PRNetAddr *result);
+
+/***********************************************************************
+** FUNCTION:
+** DESCRIPTION: PR_GetCanonNameFromAddrInfo()
+**  Extracts the canonical name of the hostname passed to
+**  PR_GetAddrInfoByName().
+**
+** INPUTS:
+**  const PRAddrInfo *addrInfo 
+**                      The PRAddrInfo handle returned by a successful
+**                      call to PR_GetAddrInfoByName().
+** RETURN:
+**  const char *        A const pointer to the canonical hostname stored
+**                      in the given PRAddrInfo handle. This pointer is
+**                      invalidated once the PRAddrInfo handle is destroyed
+**                      by a call to PR_FreeAddrInfo().
+***********************************************************************/
+NSPR_API(const char *) PR_GetCanonNameFromAddrInfo(
+    const PRAddrInfo *addrInfo);
+
+/***********************************************************************
+** 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
+**      PR_htonl        32 bit conversion from host to network
+**      PR_ntonll       64 bit conversion from host to network
+**
+***********************************************************************/
+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);
+
+PR_END_EXTERN_C
+
+#endif /* prnetdb_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prolock.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prolock.h
new file mode 100644
index 0000000..d8aece9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prolock.h
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prolock_h___
+#define prolock_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** A locking mechanism, built on the existing PRLock definiion,
+** is provided that will permit applications to define a Lock
+** Hierarchy (or Lock Ordering) schema. An application designed
+** using the Ordered Lock functions will terminate with a
+** diagnostic message when a lock inversion condition is
+** detected. 
+** 
+** The lock ordering detection is complile-time enabled only. in
+** optimized builds of NSPR, the Ordered Lock functions map
+** directly to PRLock functions, providing no lock order
+** detection.
+** 
+** The Ordered Lock Facility is compiled in when DEBUG is defined at
+** compile time. Ordered Lock can be forced on in optimized builds by
+** defining FORCE_NSPR_ORDERED_LOCK at compile time. Both the
+** application using Ordered Lock and NSPR must be compiled with the
+** facility enabled to achieve the desired results.
+** 
+** Application designers should use the macro interfaces to the Ordered
+** Lock facility to ensure that it is compiled out in optimized builds.
+**
+** Application designers are responsible for defining their own
+** lock hierarchy. 
+**
+** Ordered Lock is thread-safe and SMP safe.
+**
+** See Also: prlock.h
+**
+** /lth. 10-Jun-1998.
+**
+*/
+
+/*
+** Opaque type for ordered lock.
+** ... Don't even think of looking in here.
+**
+*/
+
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+typedef void * PROrderedLock;
+#else
+/*
+** Map PROrderedLock and methods onto PRLock when ordered locking
+** is not compiled in.
+**  
+*/
+#include "prlock.h"
+
+typedef PRLock PROrderedLock;
+#endif
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_CreateOrderedLock() -- Create an Ordered Lock
+** 
+** DESCRIPTION: PR_CreateOrderedLock() creates an ordered lock.
+** 
+** INPUTS:
+**  order: user defined order of this lock.
+**  name: name of the lock. For debugging purposes.
+** 
+** OUTPUTS: returned
+** 
+** RETURNS: PR_OrderedLock pointer
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+#define PR_CREATE_ORDERED_LOCK(order,name)\
+    PR_CreateOrderedLock((order),(name))
+#else
+#define PR_CREATE_ORDERED_LOCK(order) PR_NewLock()
+#endif
+
+NSPR_API(PROrderedLock *) 
+    PR_CreateOrderedLock( 
+        PRInt32 order,
+        const char *name
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DestroyOrderedLock() -- Destroy an Ordered Lock
+** 
+** DESCRIPTION: PR_DestroyOrderedLock() destroys the ordered lock
+** referenced by lock.
+** 
+** INPUTS: lock: pointer to a PROrderedLock
+** 
+** OUTPUTS: the lock is destroyed
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+#define PR_DESTROY_ORDERED_LOCK(lock) PR_DestroyOrderedLock((lock))
+#else
+#define PR_DESTROY_ORDERED_LOCK(lock) PR_DestroyLock((lock))
+#endif
+
+NSPR_API(void) 
+    PR_DestroyOrderedLock( 
+        PROrderedLock *lock 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_LockOrderedLock() -- Lock an ordered lock
+** 
+** DESCRIPTION: PR_LockOrderedLock() locks the ordered lock
+** referenced by lock. If the order of lock is less than or equal
+** to the order of the highest lock held by the locking thread,
+** the function asserts.
+** 
+** INPUTS: lock: a pointer to a PROrderedLock
+** 
+** OUTPUTS: The lock is held or the function asserts.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+#define PR_LOCK_ORDERED_LOCK(lock) PR_LockOrderedLock((lock))
+#else
+#define PR_LOCK_ORDERED_LOCK(lock) PR_Lock((lock))
+#endif
+
+NSPR_API(void) 
+    PR_LockOrderedLock( 
+        PROrderedLock *lock 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_UnlockOrderedLock() -- unlock and Ordered Lock
+** 
+** DESCRIPTION: PR_UnlockOrderedLock() unlocks the lock referenced
+** by lock.
+** 
+** INPUTS: lock: a pointer to a PROrderedLock
+** 
+** OUTPUTS: the lock is unlocked
+** 
+** RETURNS:
+**  PR_SUCCESS
+**  PR_FAILURE
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+#define PR_UNLOCK_ORDERED_LOCK(lock) PR_UnlockOrderedLock((lock))
+#else
+#define PR_UNLOCK_ORDERED_LOCK(lock) PR_Unlock((lock))
+#endif
+
+NSPR_API(PRStatus) 
+    PR_UnlockOrderedLock( 
+        PROrderedLock *lock 
+);
+
+PR_END_EXTERN_C
+
+#endif /* prolock_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prpdce.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prpdce.h
new file mode 100644
index 0000000..ebd595a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prpdce.h
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:		prpdce.h
+ * Description:	This file is the API defined to allow for DCE (aka POSIX)
+ *				thread emulation in an NSPR environment. It is not the
+ *				intent that this be a fully supported API.
+ */
+
+#if !defined(PRPDCE_H)
+#define PRPDCE_H
+
+#include "prlock.h"
+#include "prcvar.h"
+#include "prtypes.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+#define _PR_NAKED_CV_LOCK (PRLock*)0xdce1dce1
+
+/*
+** Test and acquire a lock.
+**
+** If the lock is acquired by the calling thread, the
+** return value will be PR_SUCCESS. If the lock is
+** already held, by another thread or this thread, the
+** result will be PR_FAILURE.
+*/
+NSPR_API(PRStatus) PRP_TryLock(PRLock *lock);
+
+/*
+** Create a naked condition variable
+**
+** A "naked" condition variable is one that is not created bound
+** to a lock. The CV created with this function is the only type
+** that may be used in the subsequent "naked" condition variable
+** operations (see PRP_NakedWait, PRP_NakedNotify, PRP_NakedBroadcast);
+*/
+NSPR_API(PRCondVar*) PRP_NewNakedCondVar(void);
+
+/*
+** Destroy a naked condition variable
+**
+** Destroy the condition variable created by PR_NewNakedCondVar.
+*/
+NSPR_API(void) PRP_DestroyNakedCondVar(PRCondVar *cvar);
+
+/*
+** Wait on a condition
+**
+** Wait on the condition variable 'cvar'. It is asserted that
+** the lock protecting the condition 'lock' is held by the
+** calling thread. If more time expires than that declared in
+** 'timeout' the condition will be notified. Waits can be
+** interrupted by another thread.
+**
+** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar.
+*/
+NSPR_API(PRStatus) PRP_NakedWait(
+	PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
+
+/*
+** Notify a thread waiting on a condition
+**
+** Notify the condition specified 'cvar'.
+**
+** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar.
+*/
+NSPR_API(PRStatus) PRP_NakedNotify(PRCondVar *cvar);
+
+/*
+** Notify all threads waiting on a condition
+**
+** Notify the condition specified 'cvar'.
+**
+** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar.
+*/
+NSPR_API(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar);
+
+PR_END_EXTERN_C
+
+#endif /* PRPDCE_H */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prprf.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prprf.h
new file mode 100644
index 0000000..e5c4505
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prprf.h
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prprf_h___
+#define prprf_h___
+
+/*
+** API for PR printf like routines. Supports the following formats
+**	%d - decimal
+**	%u - unsigned decimal
+**	%x - unsigned hex
+**	%X - unsigned uppercase hex
+**	%o - unsigned octal
+**	%hd, %hu, %hx, %hX, %ho - 16-bit versions of above
+**	%ld, %lu, %lx, %lX, %lo - 32-bit versions of above
+**	%lld, %llu, %llx, %llX, %llo - 64 bit versions of above
+**	%td, %tu, %tx, %tX, %to - PRPtrdiff versions of the above (deals with machine dependent PRPtrdiff size)
+**	%zd, %zu, %zx, %zX, %zo - PRSize versions of above (deals with machine dependent PRSize size)
+**	%s - string
+**	%c - character
+**	%p - pointer (deals with machine dependent pointer size)
+**	%f - float
+**	%g - float
+*/
+#include "prtypes.h"
+#include "prio.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+PR_BEGIN_EXTERN_C
+
+/*
+** sprintf into a fixed size buffer. Guarantees that a NUL is at the end
+** of the buffer. Returns the length of the written output, NOT including
+** the NUL, or (PRUint32)-1 if an error occurs.
+*/
+NSPR_API(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...);
+
+/*
+** sprintf into a PR_MALLOC'd buffer. Return a pointer to the malloc'd
+** buffer on success, NULL on failure. Call "PR_smprintf_free" to release
+** the memory returned.
+*/
+NSPR_API(char*) PR_smprintf(const char *fmt, ...);
+
+/*
+** Free the memory allocated, for the caller, by PR_smprintf
+*/
+NSPR_API(void) PR_smprintf_free(char *mem);
+
+/*
+** "append" sprintf into a PR_MALLOC'd buffer. "last" is the last value of
+** the PR_MALLOC'd buffer. sprintf will append data to the end of last,
+** growing it as necessary using realloc. If last is NULL, PR_sprintf_append
+** will allocate the initial string. The return value is the new value of
+** last for subsequent calls, or NULL if there is a malloc failure.
+*/
+NSPR_API(char*) PR_sprintf_append(char *last, const char *fmt, ...);
+
+/*
+** sprintf into a function. The function "f" is called with a string to
+** place into the output. "arg" is an opaque pointer used by the stuff
+** function to hold any state needed to do the storage of the output
+** data. The return value is a count of the number of characters fed to
+** the stuff function, or (PRUint32)-1 if an error occurs.
+*/
+typedef PRIntn (*PRStuffFunc)(void *arg, const char *s, PRUint32 slen);
+
+NSPR_API(PRUint32) PR_sxprintf(PRStuffFunc f, void *arg, const char *fmt, ...);
+
+/*
+** fprintf to a PRFileDesc
+*/
+NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...);
+
+/*
+** va_list forms of the above.
+*/
+NSPR_API(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen, const char *fmt, va_list ap);
+NSPR_API(char*) PR_vsmprintf(const char *fmt, va_list ap);
+NSPR_API(char*) PR_vsprintf_append(char *last, const char *fmt, va_list ap);
+NSPR_API(PRUint32) PR_vsxprintf(PRStuffFunc f, void *arg, const char *fmt, va_list ap);
+NSPR_API(PRUint32) PR_vfprintf(struct PRFileDesc* fd, const char *fmt, va_list ap);
+
+/*
+***************************************************************************
+** FUNCTION: PR_sscanf
+** DESCRIPTION:
+**     PR_sscanf() scans the input character string, performs data
+**     conversions, and stores the converted values in the data objects
+**     pointed to by its arguments according to the format control
+**     string.
+**
+**     PR_sscanf() behaves the same way as the sscanf() function in the
+**     Standard C Library (stdio.h), with the following exceptions:
+**     - PR_sscanf() handles the NSPR integer and floating point types,
+**       such as PRInt16, PRInt32, PRInt64, and PRFloat64, whereas
+**       sscanf() handles the standard C types like short, int, long,
+**       and double.
+**     - PR_sscanf() has no multibyte character support, while sscanf()
+**       does.
+** INPUTS:
+**     const char *buf
+**         a character string holding the input to scan
+**     const char *fmt
+**         the format control string for the conversions
+**     ...
+**         variable number of arguments, each of them is a pointer to
+**         a data object in which the converted value will be stored
+** OUTPUTS: none
+** RETURNS: PRInt32
+**     The number of values converted and stored.
+** RESTRICTIONS:
+**    Multibyte characters in 'buf' or 'fmt' are not allowed.
+***************************************************************************
+*/
+
+NSPR_API(PRInt32) PR_sscanf(const char *buf, const char *fmt, ...);
+
+PR_END_EXTERN_C
+
+#endif /* prprf_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prproces.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prproces.h
new file mode 100644
index 0000000..0c1e8a6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prproces.h
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prproces_h___
+#define prproces_h___
+
+#include "prtypes.h"
+#include "prio.h"
+
+PR_BEGIN_EXTERN_C
+
+/************************************************************************/
+/*****************************PROCESS OPERATIONS*************************/
+/************************************************************************/
+
+typedef struct PRProcess PRProcess;
+typedef struct PRProcessAttr PRProcessAttr;
+
+NSPR_API(PRProcessAttr *) PR_NewProcessAttr(void);
+
+NSPR_API(void) PR_ResetProcessAttr(PRProcessAttr *attr);
+
+NSPR_API(void) PR_DestroyProcessAttr(PRProcessAttr *attr);
+
+NSPR_API(void) PR_ProcessAttrSetStdioRedirect(
+    PRProcessAttr *attr,
+    PRSpecialFD stdioFd,
+    PRFileDesc *redirectFd
+);
+
+/*
+ * OBSOLETE -- use PR_ProcessAttrSetStdioRedirect instead.
+ */
+NSPR_API(void) PR_SetStdioRedirect(
+    PRProcessAttr *attr,
+    PRSpecialFD stdioFd,
+    PRFileDesc *redirectFd
+);
+
+NSPR_API(PRStatus) PR_ProcessAttrSetCurrentDirectory(
+    PRProcessAttr *attr,
+    const char *dir
+);
+
+NSPR_API(PRStatus) PR_ProcessAttrSetInheritableFD(
+    PRProcessAttr *attr,
+    PRFileDesc *fd,
+    const char *name
+);
+
+/*
+** Create a new process
+**
+** Create a new process executing the file specified as 'path' and with
+** the supplied arguments and environment.
+**
+** This function may fail because of illegal access (permissions),
+** invalid arguments or insufficient resources.
+**
+** A process may be created such that the creator can later synchronize its
+** termination using PR_WaitProcess(). 
+*/
+
+NSPR_API(PRProcess*) PR_CreateProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr);
+
+NSPR_API(PRStatus) PR_CreateProcessDetached(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr);
+
+NSPR_API(PRStatus) PR_DetachProcess(PRProcess *process);
+
+NSPR_API(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode);
+
+NSPR_API(PRStatus) PR_KillProcess(PRProcess *process);
+
+PR_END_EXTERN_C
+
+#endif /* prproces_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prrng.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prrng.h
new file mode 100644
index 0000000..e94b806
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prrng.h
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/*
+** prrng.h -- NSPR Random Number Generator
+** 
+**
+** lth. 29-Oct-1999.
+*/
+
+#ifndef prrng_h___ 
+#define prrng_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** PR_GetRandomNoise() -- Get random noise from the host platform
+**
+** Description:
+** PR_GetRandomNoise() provides, depending on platform, a random value.
+** The length of the random value is dependent on platform and the
+** platform's ability to provide a random value at that moment.
+**
+** The intent of PR_GetRandomNoise() is to provide a "seed" value for a
+** another random number generator that may be suitable for
+** cryptographic operations. This implies that the random value
+** provided may not be, by itself, cryptographically secure. The value
+** generated by PR_GetRandomNoise() is at best, extremely difficult to
+** predict and is as non-deterministic as the underlying platfrom can
+** provide.
+**
+** Inputs:
+**   buf -- pointer to a caller supplied buffer to contain the
+**          generated random number. buf must be at least as large as
+**          is specified in the 'size' argument.
+**
+**   size -- the requested size of the generated random number
+**
+** Outputs:
+**   a random number provided in 'buf'.
+**
+** Returns:
+**   PRSize value equal to the size of the random number actually
+**   generated, or zero. The generated size may be less than the size
+**   requested. A return value of zero means that PR_GetRandomNoise() is
+**   not implemented on this platform, or there is no available noise
+**   available to be returned at the time of the call.
+**
+** Restrictions:
+**   Calls to PR_GetRandomNoise() may use a lot of CPU on some platforms.
+**   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.
+**
+*/
+NSPR_API(PRSize) PR_GetRandomNoise( 
+    void    *buf,
+    PRSize  size
+);
+
+PR_END_EXTERN_C
+
+#endif /* prrng_h___ */
+/* end prrng.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prrwlock.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prrwlock.h
new file mode 100644
index 0000000..945e5f8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prrwlock.h
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:		prrwlock.h
+** Description:	API to basic reader-writer lock functions of NSPR.
+**
+**/
+
+#ifndef prrwlock_h___
+#define prrwlock_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+ * PRRWLock --
+ *
+ *	The reader writer lock, PRRWLock, is an opaque object to the clients
+ *	of NSPR.  All routines operate on a pointer to this opaque entity.
+ */
+
+
+typedef struct PRRWLock PRRWLock;
+
+#define	PR_RWLOCK_RANK_NONE	0
+
+
+/***********************************************************************
+** FUNCTION:    PR_NewRWLock
+** DESCRIPTION:
+**  Returns a pointer to a newly created reader-writer lock object.
+** INPUTS:      Lock rank
+**				Lock name
+** OUTPUTS:     void
+** RETURN:      PRRWLock*
+**   If the lock cannot be created because of resource constraints, NULL
+**   is returned.
+**  
+***********************************************************************/
+NSPR_API(PRRWLock*) PR_NewRWLock(PRUint32 lock_rank, const char *lock_name);
+
+/***********************************************************************
+** FUNCTION:    PR_DestroyRWLock
+** DESCRIPTION:
+**  Destroys a given RW lock object.
+** INPUTS:      PRRWLock *lock - Lock to be freed.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_DestroyRWLock(PRRWLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_RWLock_Rlock
+** DESCRIPTION:
+**  Apply a read lock (non-exclusive) on a RWLock
+** INPUTS:      PRRWLock *lock - Lock to be read-locked.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_RWLock_Rlock(PRRWLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_RWLock_Wlock
+** DESCRIPTION:
+**  Apply a write lock (exclusive) on a RWLock
+** INPUTS:      PRRWLock *lock - Lock to write-locked.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_RWLock_Wlock(PRRWLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_RWLock_Unlock
+** DESCRIPTION:
+**  Release a RW lock. Unlocking an unlocked lock has undefined results.
+** INPUTS:      PRRWLock *lock - Lock to unlocked.
+** OUTPUTS:     void
+** RETURN:      void
+***********************************************************************/
+NSPR_API(void) PR_RWLock_Unlock(PRRWLock *lock);
+
+PR_END_EXTERN_C
+
+#endif /* prrwlock_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prshm.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prshm.h
new file mode 100644
index 0000000..098566e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prshm.h
@@ -0,0 +1,289 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** prshm.h -- NSPR Shared Memory
+**
+** NSPR Named Shared Memory API provides a cross-platform named
+** shared-memory interface. NSPR Named Shared Memory is modeled on
+** similar constructs in Unix and Windows operating systems. Shared
+** memory allows multiple processes to access one or more common shared
+** memory regions, using it as an inter-process communication channel.
+**
+** Notes on Platform Independence:
+**   NSPR Named Shared Memory is built on the native services offered
+**   by most platforms. The NSPR Named Shared Memory API tries to
+**   provide a least common denominator interface so that it works
+**   across all supported platforms. To ensure that it works everywhere,
+**   some platform considerations must be accomodated and the protocol
+**   for using NSPR Shared Memory API must be observed.
+**
+** Protocol:
+**   Multiple shared memories can be created using NSPR's Shared Memory
+**   feature. For each named shared memory, as defined by the name
+**   given in the PR_OpenSharedMemory() call, a protocol for using the
+**   shared memory API is required to ensure desired behavior. Failing
+**   to follow the protocol may yield unpredictable results.
+**   
+**   PR_OpenSharedMemory() will create the shared memory segment, if it
+**   does not already exist, or open a connection that the existing
+**   shared memory segment if it already exists.
+**   
+**   PR_AttachSharedMemory() should be called following
+**   PR_OpenSharedMemory() to map the memory segment to an address in
+**   the application's address space.
+**   
+**   PR_AttachSharedMemory() may be called to re-map a shared memory
+**   segment after detaching the same PRSharedMemory object. Be
+**   sure to detach it when done.
+**   
+**   PR_DetachSharedMemory() should be called to un-map the shared
+**   memory segment from the application's address space.
+**   
+**   PR_CloseSharedMemory() should be called when no further use of the
+**   PRSharedMemory object is required within a process. Following a
+**   call to  PR_CloseSharedMemory() the PRSharedMemory object is
+**   invalid and cannot be reused.
+**   
+**   PR_DeleteSharedMemory() should be called before process
+**   termination. After calling PR_DeleteSharedMemory() any further use
+**   of the shared memory associated with the name may cause
+**   unpredictable results.
+**   
+** Files:
+**   The name passed to PR_OpenSharedMemory() should be a valid filename
+**   for a unix platform. PR_OpenSharedMemory() creates file using the
+**   name passed in. Some platforms may mangle the name before creating
+**   the file and the shared memory.
+**   
+**   The unix implementation may use SysV IPC shared memory, Posix
+**   shared memory, or memory mapped files; the filename may used to
+**   define the namespace. On Windows, the name is significant, but
+**   there is no file associated with name.
+**   
+**   No assumptions about the persistence of data in the named file
+**   should be made. Depending on platform, the shared memory may be
+**   mapped onto system paging space and be discarded at process
+**   termination.
+**   
+**   All names provided to PR_OpenSharedMemory() should be valid
+**   filename syntax or name syntax for shared memory for the target
+**   platform. Referenced directories should have permissions 
+**   appropriate for writing.
+**
+** Limits:
+**   Different platforms have limits on both the number and size of
+**   shared memory resources. The default system limits on some
+**   platforms may be smaller than your requirements. These limits may
+**   be adjusted on some platforms either via boot-time options or by
+**   setting the size of the system paging space to accomodate more
+**   and/or larger shared memory segment(s).
+**
+** Security:
+**   On unix platforms, depending on implementation, contents of the
+**   backing store for the shared memory can be exposed via the file
+**   system. Set permissions and or access controls at create and attach
+**   time to ensure you get the desired security.
+**
+**   On windows platforms, no special security measures are provided.
+**
+** Example:
+**   The test case pr/tests/nameshm1.c provides an example of use as
+**   well as testing the operation of NSPR's Named Shared Memory.
+**
+** 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;
+
+/*
+** FUNCTION: PR_OpenSharedMemory()
+**
+** DESCRIPTION:
+**   PR_OpenSharedMemory() creates a new shared-memory segment or
+**   associates a previously created memory segment with name.
+**
+**   When parameter create is (PR_SHM_EXCL | PR_SHM_CREATE) and the
+**   shared memory already exists, the function returns NULL with the
+**   error set to PR_FILE_EXISTS_ERROR.
+**
+**   When parameter create is PR_SHM_CREATE and the shared memory
+**   already exists, a handle to that memory segment is returned. If
+**   the segment does not exist, it is created and a pointer to the
+**   related PRSharedMemory structure is returned.
+**
+**   When parameter create is 0, and the shared memory exists, a
+**   pointer to a PRSharedMemory is returned. If the shared memory does
+**   not exist, NULL is returned with the error set to
+**   PR_FILE_NOT_FOUND_ERROR.
+**
+** INPUTS:
+**   name -- the name the shared-memory segment is known as.
+**   size -- the size of the shared memory segment. 
+**   flags -- Options for creating the shared memory
+**   mode -- Same as is passed to PR_Open()
+**
+** OUTPUTS: 
+**   The shared memory is allocated.
+**
+** RETURNS: Pointer to opaque structure PRSharedMemory or NULL.
+**   NULL is returned on error. The reason for the error can be
+**   retrieved via PR_GetError() and PR_GetOSError();
+**
+*/
+NSPR_API( PRSharedMemory * )
+    PR_OpenSharedMemory(
+        const char *name,
+        PRSize      size,
+        PRIntn      flags,
+        PRIntn      mode
+);
+/* Define values for PR_OpenShareMemory(...,create) */
+#define PR_SHM_CREATE 0x1  /* create if not exist */
+#define PR_SHM_EXCL   0x2  /* fail if already exists */
+
+/*
+** FUNCTION: PR_AttachSharedMemory()
+**
+** DESCRIPTION:
+** PR_AttachSharedMemory() maps the shared-memory described by
+** shm to the current process. 
+**
+** INPUTS: 
+**   shm -- The handle returned from PR_OpenSharedMemory().
+**   flags -- options for mapping the shared memory.
+**   PR_SHM_READONLY causes the memory to be attached 
+**   read-only.
+**
+** OUTPUTS:
+**   On success, the shared memory segment represented by shm is mapped
+**   into the process' address space.
+**
+** RETURNS: Address where shared memory is mapped, or NULL.
+**   NULL is returned on error. The reason for the error can be
+**   retrieved via PR_GetError() and PR_GetOSError();
+**
+**
+*/
+NSPR_API( void * )
+    PR_AttachSharedMemory(
+        PRSharedMemory *shm,
+        PRIntn  flags
+);
+/* Define values for PR_AttachSharedMemory(...,flags) */ 
+#define PR_SHM_READONLY 0x01
+
+/*
+** FUNCTION: PR_DetachSharedMemory()
+**
+** DESCRIPTION:
+**   PR_DetachSharedMemory() detaches the shared-memory described
+**   by shm. 
+**
+** INPUTS: 
+**   shm -- The handle returned from PR_OpenSharedMemory().
+**   addr -- The address at which the memory was attached.
+**
+** OUTPUTS:
+**   The shared memory mapped to an address via a previous call to
+**   PR_AttachSharedMemory() is unmapped.
+**
+** RETURNS: PRStatus
+**
+*/
+NSPR_API( PRStatus )
+    PR_DetachSharedMemory(
+        PRSharedMemory *shm,
+        void  *addr
+);
+
+/*
+** FUNCTION: PR_CloseSharedMemory()
+**
+** DESCRIPTION:
+**   PR_CloseSharedMemory() closes the shared-memory described by
+**   shm.
+** 
+** INPUTS:
+**   shm -- The handle returned from PR_OpenSharedMemory().
+**
+** OUTPUTS:
+**   the shared memory represented by shm is closed
+**
+** RETURNS: PRStatus
+**
+*/
+NSPR_API( PRStatus )
+    PR_CloseSharedMemory(
+        PRSharedMemory *shm
+);
+
+/*
+** FUNCTION: PR_DeleteSharedMemory()
+**
+** DESCRIPTION:
+**   The shared memory resource represented by name is released.
+**
+** INPUTS:
+**   name -- the name the shared-memory segment
+**
+** OUTPUTS:
+**   depending on platform, resources may be returned to the underlying
+**   operating system.
+**
+** RETURNS: PRStatus
+**
+*/
+NSPR_API( PRStatus )
+    PR_DeleteSharedMemory( 
+        const char *name
+);
+
+PR_END_EXTERN_C
+
+#endif /* prshm_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prshma.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prshma.h
new file mode 100644
index 0000000..e72ee85
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prshma.h
@@ -0,0 +1,271 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** prshma.h -- NSPR Anonymous Shared Memory
+**
+** NSPR provides an anonymous shared memory based on NSPR's PRFileMap
+** type. The anonymous file-mapped shared memory provides an inheritable
+** shared memory, as in: the child process inherits the shared memory.
+** Compare the file-mapped anonymous shared memory to to a named shared
+** memory described in prshm.h. The intent is to provide a shared
+** memory that is accessable only by parent and child processes. ...
+** It's a security thing.
+** 
+** Depending on the underlying platform, the file-mapped shared memory
+** may be backed by a file. ... surprise! ... On some platforms, no
+** real file backs the shared memory. On platforms where the shared
+** memory is backed by a file, the file's name in the filesystem is
+** visible to other processes for only the duration of the creation of
+** the file, hopefully a very short time. This restricts processess
+** that do not inherit the shared memory from opening the file and
+** reading or writing its contents. Further, when all processes
+** using an anonymous shared memory terminate, the backing file is
+** deleted. ... If you are not paranoid, you're not paying attention.
+** 
+** The file-mapped shared memory requires a protocol for the parent
+** process and child process to share the memory. NSPR provides two
+** protocols. Use one or the other; don't mix and match.
+** 
+** In the first protocol, the job of passing the inheritable shared
+** memory is done via helper-functions with PR_CreateProcess(). In the
+** second protocol, the parent process is responsible for creating the
+** child process; the parent and child are mutually responsible for
+** passing a FileMap string. NSPR provides helper functions for
+** extracting data from the PRFileMap object. ... See the examples
+** below.
+** 
+** Both sides should adhere strictly to the protocol for proper
+** operation. The pseudo-code below shows the use of a file-mapped
+** shared memory by a parent and child processes. In the examples, the
+** server creates the file-mapped shared memory, the client attaches to
+** it.
+**
+** First protocol.
+** Server:
+**
+**   fm = PR_OpenAnonFileMap(dirName, size, FilemapProt); 
+**   addr = PR_MemMap(fm); 
+**   attr = PR_NewProcessAttr();
+**   PR_ProcessAttrSetInheritableFileMap( attr, fm, shmname );
+**   PR_CreateProcess(Client); 
+**   PR_DestroyProcessAttr(attr);
+**   ... yadda ...
+**   PR_MemUnmap( addr );
+**   PR_CloseFileMap(fm);
+**
+**
+** Client: 
+**   ... started by server via PR_CreateProcess()
+**   fm = PR_GetInheritedFileMap( shmname );
+**   addr = PR_MemMap(fm);
+**   ... yadda ...
+**   PR_MemUnmap(addr);
+**   PR_CloseFileMap(fm);
+**
+**
+** Second Protocol:
+** Server:
+**
+**   fm = PR_OpenAnonFileMap(dirName, size, FilemapProt); 
+**   fmstring = PR_ExportFileMapAsString( fm );
+**   addr = PR_MemMap(fm); 
+**    ... application specific technique to pass fmstring to child
+**    ... yadda ... Server uses his own magic to create child
+**   PR_MemUnmap( addr );
+**   PR_CloseFileMap(fm);
+**
+**
+** Client: 
+**   ... started by server via his own magic
+**   ... application specific technique to find fmstring from parent
+**   fm = PR_ImportFileMapFromString( fmstring )
+**   addr = PR_MemMap(fm);
+**   ... yadda ...
+**   PR_MemUnmap(addr);
+**   PR_CloseFileMap(fm);
+**
+**
+** lth. 2-Jul-1999.
+**
+** Note: The second protocol was requested by NelsonB (7/1999); this is
+** to accomodate servers which already create their own child processes
+** using platform native methods.
+** 
+*/
+
+#ifndef prshma_h___
+#define prshma_h___
+
+#include "prtypes.h"
+#include "prio.h"
+#include "prproces.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** PR_OpenAnonFileMap() -- Creates an anonymous file-mapped shared memory
+**
+** Description:
+** PR_OpenAnonFileMap() creates an anonymous shared memory. If the
+** shared memory already exists, a handle is returned to that shared
+** memory object.
+**
+** On Unix platforms, PR_OpenAnonFileMap() uses 'dirName' as a
+** directory name, without the trailing '/', to contain the anonymous
+** file. A filename is generated for the name.
+**
+** On Windows platforms, dirName is ignored.
+**
+** Inputs:
+**   dirName -- A directory name to contain the anonymous file.
+**   size -- The size of the shared memory
+**   prot -- How the shared memory is mapped. See prio.h
+**   
+** Outputs:
+**   PRFileMap *
+**
+** Returns:
+**   Pointer to PRFileMap or NULL on error.
+**
+*/
+NSPR_API( PRFileMap *)
+PR_OpenAnonFileMap(
+    const char *dirName,
+    PRSize      size, 
+    PRFileMapProtect prot
+);  
+
+/*
+** PR_ProcessAttrSetInheritableFileMap() -- Prepare FileMap for export  
+**   to my children processes via PR_CreateProcess()
+**
+** Description:
+** PR_ProcessAttrSetInheritableFileMap() connects the PRFileMap to
+** PRProcessAttr with shmname. A subsequent call to PR_CreateProcess()
+** makes the PRFileMap importable by the child process.
+**
+** Inputs:
+**   attr -- PRProcessAttr, used to pass data to PR_CreateProcess()
+**   fm -- PRFileMap structure to be passed to the child process
+**   shmname -- The name for the PRFileMap; used by child.
+**
+** Outputs:
+**   PRFileMap *
+**
+** Returns:
+**   PRStatus
+**
+*/
+NSPR_API(PRStatus) 
+PR_ProcessAttrSetInheritableFileMap( 
+    PRProcessAttr   *attr,
+    PRFileMap       *fm, 
+    const char      *shmname
+);
+
+/*
+** PR_GetInheritedFileMap() -- Import a PRFileMap previously exported
+**   by my parent process via PR_CreateProcess()
+**
+** Description:
+** PR_GetInheritedFileMap() retrieves a PRFileMap object exported from
+** its parent process via PR_CreateProcess().
+**
+** Inputs:
+**    shmname -- The name provided to PR_ProcessAttrSetInheritableFileMap()
+** 
+** Outputs:
+**   PRFileMap *
+**
+** Returns:
+**   PRFileMap pointer or NULL.
+**
+*/
+NSPR_API( PRFileMap *)
+PR_GetInheritedFileMap( 
+    const char *shmname 
+);
+
+/*
+** PR_ExportFileMapAsString() -- Creates a string identifying a PRFileMap
+**
+** Description:
+** Creates an identifier, as a string, from a PRFileMap object
+** previously created with PR_OpenAnonFileMap().
+**
+** Inputs:
+**   fm -- PRFileMap pointer to be represented as a string.
+**   bufsize -- sizeof(buf)
+**   buf -- a buffer of length PR_FILEMAP_STRING_BUFSIZE
+**
+** Outputs:
+**   buf contains the stringized PRFileMap identifier
+**
+** Returns:
+**   PRStatus
+**
+*/
+NSPR_API( PRStatus )
+PR_ExportFileMapAsString( 
+    PRFileMap *fm,
+    PRSize    bufsize,
+    char      *buf
+);
+#define PR_FILEMAP_STRING_BUFSIZE 128
+
+/*
+** PR_ImportFileMapFromString() -- Creates a PRFileMap from the identifying string
+**
+** Description:
+** PR_ImportFileMapFromString() creates a PRFileMap object from a
+** string previously created by PR_ExportFileMapAsString().
+**
+** Inputs:
+**   fmstring -- string created by PR_ExportFileMapAsString()
+**
+** Returns:
+**   PRFileMap pointer or NULL.
+**
+*/
+NSPR_API( PRFileMap * )
+PR_ImportFileMapFromString( 
+    const char *fmstring
+);
+
+PR_END_EXTERN_C
+#endif /* prshma_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prsystem.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prsystem.h
new file mode 100644
index 0000000..13cf8ba
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prsystem.h
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prsystem_h___
+#define prsystem_h___
+
+/*
+** API to NSPR functions returning system info.
+*/
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Get the host' directory separator.
+**  Pathnames are then assumed to be of the form:
+**      [<sep><root_component><sep>]*(<component><sep>)<leaf_name>
+*/
+
+NSPR_API(char) PR_GetDirectorySeparator(void);
+
+/*
+** OBSOLETE -- the function name is misspelled.
+** Use PR_GetDirectorySeparator instead.
+*/
+
+NSPR_API(char) PR_GetDirectorySepartor(void);
+
+/*
+** Get the host' path separator.
+**  Paths are assumed to be of the form:
+**      <directory>[<sep><directory>]*
+*/
+
+NSPR_API(char) PR_GetPathSeparator(void);
+
+/* Types of information available via PR_GetSystemInfo(...) */
+typedef enum {
+    PR_SI_HOSTNAME,  /* the hostname with the domain name (if any)
+                      * removed */
+    PR_SI_SYSNAME,
+    PR_SI_RELEASE,
+    PR_SI_ARCHITECTURE,
+    PR_SI_HOSTNAME_UNTRUNCATED  /* the hostname exactly as configured
+                                 * on the system */
+} PRSysInfo;
+
+
+/*
+** If successful returns a null termintated string in 'buf' for
+** the information indicated in 'cmd'. If unseccussful the reason for
+** the failure can be retrieved from PR_GetError().
+**
+** The buffer is allocated by the caller and should be at least
+** SYS_INFO_BUFFER_LENGTH bytes in length.
+*/
+
+#define SYS_INFO_BUFFER_LENGTH 256
+
+NSPR_API(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen);
+
+/*
+** Return the number of bytes in a page
+*/
+NSPR_API(PRInt32) PR_GetPageSize(void);
+
+/*
+** Return log2 of the size of a page
+*/
+NSPR_API(PRInt32) PR_GetPageShift(void);
+
+/*
+** PR_GetNumberOfProcessors() -- returns the number of CPUs
+**
+** Description:
+** PR_GetNumberOfProcessors() extracts the number of processors
+** (CPUs available in an SMP system) and returns the number.
+** 
+** Parameters:
+**   none
+**
+** Returns:
+**   The number of available processors or -1 on error
+** 
+*/
+NSPR_API(PRInt32) PR_GetNumberOfProcessors( void );
+
+/*
+** PR_GetPhysicalMemorySize() -- returns the amount of system RAM
+**
+** Description:
+** PR_GetPhysicalMemorySize() determines the amount of physical RAM
+** in the system and returns the size in bytes.
+**
+** Parameters:
+**   none
+**
+** Returns:
+**   The amount of system RAM, or 0 on failure.
+**
+*/
+NSPR_API(PRUint64) PR_GetPhysicalMemorySize(void);
+
+PR_END_EXTERN_C
+
+#endif /* prsystem_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prthread.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prthread.h
new file mode 100644
index 0000000..bb93cbf
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prthread.h
@@ -0,0 +1,286 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prthread_h___
+#define prthread_h___
+
+/*
+** API for NSPR threads. On some architectures (Mac OS Classic
+** notably) pre-emptibility is not guaranteed. Hard priority scheduling
+** is not guaranteed, so programming using priority based synchronization
+** is a no-no.
+**
+** NSPR threads are scheduled based loosely on their client set priority.
+** In general, a thread of a higher priority has a statistically better
+** chance of running relative to threads of lower priority. However,
+** NSPR uses multiple strategies to provide execution vehicles for thread
+** abstraction of various host platforms. As it turns out, there is little
+** NSPR can do to affect the scheduling attributes of "GLOBAL" threads.
+** However, a semblance of GLOBAL threads is used to implement "LOCAL"
+** threads. An arbitrary number of such LOCAL threads can be assigned to
+** a single GLOBAL thread.
+**
+** For scheduling, NSPR will attempt to run the highest priority LOCAL
+** thread associated with a given GLOBAL thread. It is further assumed
+** that the host OS will apply some form of "fair" scheduling on the
+** GLOBAL threads.
+**
+** Threads have a "system flag" which when set indicates the thread
+** doesn't count for determining when the process should exit (the
+** process exits when the last user thread exits).
+**
+** Threads also have a "scope flag" which controls whether the threads
+** are scheduled in the local scope or scheduled by the OS globally. This 
+** indicates whether a thread is permanently bound to a native OS thread. 
+** An unbound thread competes for scheduling resources in the same process.
+**
+** Another flag is "state flag" which control whether the thread is joinable.
+** It allows other threads to wait for the created thread to reach completion.
+**
+** Threads can have "per-thread-data" attached to them. Each thread has a
+** per-thread error number and error string which are updated when NSPR
+** operations fail.
+*/
+#include "prtypes.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRThread PRThread;
+typedef struct PRThreadStack PRThreadStack;
+
+typedef enum PRThreadType {
+    PR_USER_THREAD,
+    PR_SYSTEM_THREAD
+} PRThreadType;
+
+typedef enum PRThreadScope {
+    PR_LOCAL_THREAD,
+    PR_GLOBAL_THREAD,
+    PR_GLOBAL_BOUND_THREAD
+} PRThreadScope;
+
+typedef enum PRThreadState {
+    PR_JOINABLE_THREAD,
+    PR_UNJOINABLE_THREAD
+} PRThreadState;
+
+typedef enum PRThreadPriority
+{
+    PR_PRIORITY_FIRST = 0,      /* just a placeholder */
+    PR_PRIORITY_LOW = 0,        /* the lowest possible priority */
+    PR_PRIORITY_NORMAL = 1,     /* most common expected priority */
+    PR_PRIORITY_HIGH = 2,       /* slightly more aggressive scheduling */
+    PR_PRIORITY_URGENT = 3,     /* it does little good to have more than one */
+    PR_PRIORITY_LAST = 3        /* this is just a placeholder */
+} PRThreadPriority;
+
+/*
+** Create a new thread:
+**     "type" is the type of thread to create
+**     "start(arg)" will be invoked as the threads "main"
+**     "priority" will be created thread's priority
+**     "scope" will specify whether the thread is local or global
+**     "state" will specify whether the thread is joinable or not
+**     "stackSize" the size of the stack, in bytes. The value can be zero
+**        and then a machine specific stack size will be chosen.
+**
+** This can return NULL if some kind of error occurs, such as if memory is
+** tight.
+**
+** If you want the thread to start up waiting for the creator to do
+** something, enter a lock before creating the thread and then have the
+** threads start routine enter and exit the same lock. When you are ready
+** for the thread to run, exit the lock.
+**
+** If you want to detect the completion of the created thread, the thread
+** should be created joinable.  Then, use PR_JoinThread to synchrnoize the
+** termination of another thread.
+**
+** When the start function returns the thread exits. If it is the last
+** PR_USER_THREAD to exit then the process exits.
+*/
+NSPR_API(PRThread*) PR_CreateThread(PRThreadType type,
+                     void (PR_CALLBACK *start)(void *arg),
+                     void *arg,
+                     PRThreadPriority priority,
+                     PRThreadScope scope,
+                     PRThreadState state,
+                     PRUint32 stackSize);
+
+/*
+** Wait for thread termination:
+**     "thread" is the target thread 
+**
+** This can return PR_FAILURE if no joinable thread could be found 
+** corresponding to the specified target thread.
+**
+** The calling thread is blocked until the target thread completes.
+** Several threads cannot wait for the same thread to complete; one thread
+** will operate successfully and others will terminate with an error PR_FAILURE.
+** The calling thread will not be blocked if the target thread has already
+** terminated.
+*/
+NSPR_API(PRStatus) PR_JoinThread(PRThread *thread);
+
+/*
+** Return the current thread object for the currently running code.
+** Never returns NULL.
+*/
+NSPR_API(PRThread*) PR_GetCurrentThread(void);
+#ifndef NO_NSPR_10_SUPPORT
+#define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */
+#endif /* NO_NSPR_10_SUPPORT */
+
+/*
+** Get the priority of "thread".
+*/
+NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread);
+
+/*
+** Change the priority of the "thread" to "priority".
+*/
+NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority);
+
+/*
+** This routine returns a new index for per-thread-private data table. 
+** The index is visible to all threads within a process. This index can 
+** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines 
+** to save and retrieve data associated with the index for a thread.
+**
+** Each index is associationed with a destructor function ('dtor'). The function
+** may be specified as NULL when the index is created. If it is not NULL, the
+** function will be called when:
+**      - the thread exits and the private data for the associated index
+**        is not NULL,
+**      - new thread private data is set and the current private data is
+**        not NULL.
+**
+** The index independently maintains specific values for each binding thread. 
+** A thread can only get access to its own thread-specific-data.
+**
+** Upon a new index return the value associated with the index for all threads
+** is NULL, and upon thread creation the value associated with all indices for 
+** that thread is NULL. 
+**
+** Returns PR_FAILURE if the total number of indices will exceed the maximun 
+** allowed.
+*/
+typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv);
+
+NSPR_API(PRStatus) PR_NewThreadPrivateIndex(
+    PRUintn *newIndex, PRThreadPrivateDTOR destructor);
+
+/*
+** Define some per-thread-private data.
+**     "tpdIndex" is an index into the per-thread private data table
+**     "priv" is the per-thread-private data 
+**
+** If the per-thread private data table has a previously registered
+** destructor function and a non-NULL per-thread-private data value,
+** the destructor function is invoked.
+**
+** This can return PR_FAILURE if the index is invalid.
+*/
+NSPR_API(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv);
+
+/*
+** Recover the per-thread-private data for the current thread. "tpdIndex" is
+** the index into the per-thread private data table. 
+**
+** The returned value may be NULL which is indistinguishable from an error 
+** condition.
+**
+** A thread can only get access to its own thread-specific-data.
+*/
+NSPR_API(void*) PR_GetThreadPrivate(PRUintn tpdIndex);
+
+/*
+** This routine sets the interrupt request for a target thread. The interrupt
+** request remains in the thread's state until it is delivered exactly once
+** or explicitly canceled.
+**
+** A thread that has been interrupted will fail all NSPR blocking operations
+** that return a PRStatus (I/O, waiting on a condition, etc).
+**
+** PR_Interrupt may itself fail if the target thread is invalid.
+*/
+NSPR_API(PRStatus) PR_Interrupt(PRThread *thread);
+
+/*
+** Clear the interrupt request for the calling thread. If no such request
+** is pending, this operation is a noop.
+*/
+NSPR_API(void) PR_ClearInterrupt(void);
+
+/*
+** Block the interrupt for the calling thread.
+*/
+NSPR_API(void) PR_BlockInterrupt(void);
+
+/*
+** Unblock the interrupt for the calling thread.
+*/
+NSPR_API(void) PR_UnblockInterrupt(void);
+
+/*
+** Make the current thread sleep until "ticks" time amount of time
+** has expired. If "ticks" is PR_INTERVAL_NO_WAIT then the call is
+** equivalent to calling PR_Yield. Calling PR_Sleep with an argument
+** equivalent to PR_INTERVAL_NO_TIMEOUT is an error and will result
+** in a PR_FAILURE error return.
+*/
+NSPR_API(PRStatus) PR_Sleep(PRIntervalTime ticks);
+
+/*
+** Get the scoping of this thread.
+*/
+NSPR_API(PRThreadScope) PR_GetThreadScope(const PRThread *thread);
+
+/*
+** Get the type of this thread.
+*/
+NSPR_API(PRThreadType) PR_GetThreadType(const PRThread *thread);
+
+/*
+** Get the join state of this thread.
+*/
+NSPR_API(PRThreadState) PR_GetThreadState(const PRThread *thread);
+
+PR_END_EXTERN_C
+
+#endif /* prthread_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h
new file mode 100644
index 0000000..dd979d6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h
@@ -0,0 +1,310 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * prtime.h --
+ *
+ *     NSPR date and time functions
+ *
+ *-----------------------------------------------------------------------
+ */
+
+#ifndef prtime_h___
+#define prtime_h___
+
+#include "prlong.h"
+
+PR_BEGIN_EXTERN_C
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+#define PR_MSEC_PER_SEC		1000UL
+#define PR_USEC_PER_SEC		1000000UL
+#define PR_NSEC_PER_SEC		1000000000UL
+#define PR_USEC_PER_MSEC	1000UL
+#define PR_NSEC_PER_MSEC	1000000UL
+
+/*
+ * PRTime --
+ *
+ *     NSPR represents basic time as 64-bit signed integers relative
+ *     to midnight (00:00:00), January 1, 1970 Greenwich Mean Time (GMT).
+ *     (GMT is also known as Coordinated Universal Time, UTC.)
+ *     The units of time are in microseconds. Negative times are allowed
+ *     to represent times prior to the January 1970 epoch. Such values are
+ *     intended to be exported to other systems or converted to human
+ *     readable form.
+ *
+ *     Notes on porting: PRTime corresponds to time_t in ANSI C.  NSPR 1.0
+ *     simply uses PRInt64.
+ */
+
+typedef PRInt64 PRTime;
+
+/*
+ * Time zone and daylight saving time corrections applied to GMT to
+ * obtain the local time of some geographic location
+ */
+
+typedef struct PRTimeParameters {
+    PRInt32 tp_gmt_offset;     /* the offset from GMT in seconds */
+    PRInt32 tp_dst_offset;     /* contribution of DST in seconds */
+} PRTimeParameters;
+
+/*
+ * PRExplodedTime --
+ *
+ *     Time broken down into human-readable components such as year, month,
+ *     day, hour, minute, second, and microsecond.  Time zone and daylight
+ *     saving time corrections may be applied.  If they are applied, the
+ *     offsets from the GMT must be saved in the 'tm_params' field so that
+ *     all the information is available to reconstruct GMT.
+ *
+ *     Notes on porting: PRExplodedTime corrresponds to struct tm in
+ *     ANSI C, with the following differences:
+ *       - an additional field tm_usec;
+ *       - replacing tm_isdst by tm_params;
+ *       - the month field is spelled tm_month, not tm_mon;
+ *       - we use absolute year, AD, not the year since 1900.
+ *     The corresponding type in NSPR 1.0 is called PRTime.  Below is
+ *     a table of date/time type correspondence in the three APIs:
+ *         API          time since epoch          time in components
+ *       ANSI C             time_t                  struct tm
+ *       NSPR 1.0           PRInt64                   PRTime
+ *       NSPR 2.0           PRTime                  PRExplodedTime
+ */
+
+typedef struct PRExplodedTime {
+    PRInt32 tm_usec;		    /* microseconds past tm_sec (0-99999)  */
+    PRInt32 tm_sec;             /* seconds past tm_min (0-61, accomodating
+                                   up to two leap seconds) */
+    PRInt32 tm_min;             /* minutes past tm_hour (0-59) */
+    PRInt32 tm_hour;            /* hours past tm_day (0-23) */
+    PRInt32 tm_mday;            /* days past tm_mon (1-31, note that it
+				                starts from 1) */
+    PRInt32 tm_month;           /* months past tm_year (0-11, Jan = 0) */
+    PRInt16 tm_year;            /* absolute year, AD (note that we do not
+				                count from 1900) */
+
+    PRInt8 tm_wday;		        /* calculated day of the week
+				                (0-6, Sun = 0) */
+    PRInt16 tm_yday;            /* calculated day of the year
+				                (0-365, Jan 1 = 0) */
+
+    PRTimeParameters tm_params;  /* time parameters used by conversion */
+} PRExplodedTime;
+
+/*
+ * PRTimeParamFn --
+ *
+ *     A function of PRTimeParamFn type returns the time zone and
+ *     daylight saving time corrections for some geographic location,
+ *     given the current time in GMT.  The input argument gmt should
+ *     point to a PRExplodedTime that is in GMT, i.e., whose
+ *     tm_params contains all 0's.
+ *
+ *     For any time zone other than GMT, the computation is intended to
+ *     consist of two steps:
+ *       - Figure out the time zone correction, tp_gmt_offset.  This number
+ *         usually depends on the geographic location only.  But it may
+ *         also depend on the current time.  For example, all of China
+ *         is one time zone right now.  But this situation may change
+ *         in the future.
+ *       - Figure out the daylight saving time correction, tp_dst_offset.
+ *         This number depends on both the geographic location and the
+ *         current time.  Most of the DST rules are expressed in local
+ *         current time.  If so, one should apply the time zone correction
+ *         to GMT before applying the DST rules.
+ */
+
+typedef PRTimeParameters (PR_CALLBACK *PRTimeParamFn)(const PRExplodedTime *gmt);
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/*
+ * The PR_Now routine returns the current time relative to the
+ * epoch, midnight, January 1, 1970 UTC. The units of the returned
+ * value are microseconds since the epoch.
+ *
+ * The values returned are not guaranteed to advance in a linear fashion
+ * due to the application of time correction protocols which synchronize
+ * computer clocks to some external time source. Consequently it should
+ * not be depended on for interval timing.
+ *
+ * The implementation is machine dependent.
+ * Cf. time_t time(time_t *tp) in ANSI C.
+ */
+NSPR_API(PRTime)
+PR_Now(void);
+
+/*
+ * Expand time binding it to time parameters provided by PRTimeParamFn.
+ * The calculation is envisoned to proceed in the following steps:
+ *   - From given PRTime, calculate PRExplodedTime in GMT
+ *   - Apply the given PRTimeParamFn to the GMT that we just calculated
+ *     to obtain PRTimeParameters.
+ *   - Add the PRTimeParameters offsets to GMT to get the local time
+ *     as PRExplodedTime.
+ */
+
+NSPR_API(void) PR_ExplodeTime(
+    PRTime usecs, PRTimeParamFn params, PRExplodedTime *exploded);
+
+/* Reverse operation of PR_ExplodeTime */
+NSPR_API(PRTime)
+PR_ImplodeTime(const PRExplodedTime *exploded);
+
+/*
+ * Adjust exploded time to normalize field overflows after manipulation.
+ * Note that the following fields of PRExplodedTime should not be
+ * manipulated:
+ *   - tm_month and tm_year: because the number of days in a month and
+ *     number of days in a year are not constant, it is ambiguous to
+ *     manipulate the month and year fields, although one may be tempted
+ *     to.  For example, what does "a month from January 31st" mean?
+ *   - tm_wday and tm_yday: these fields are calculated by NSPR.  Users
+ *     should treat them as "read-only".
+ */
+
+NSPR_API(PRTime) PR_NormalizeTime(
+    PRExplodedTime *exploded, PRTimeParamFn params);
+
+NSPR_API(void) PR_NormalizeTime_NoDSTAdjust(
+    PRExplodedTime *exploded, PRTimeParamFn params);
+
+/**********************************************************************/
+/*********************** TIME PARAMETER FUNCTIONS *********************/
+/**********************************************************************/
+
+/* Time parameters that suit current host machine */
+NSPR_API(PRTimeParameters) PR_LocalTimeParameters(const PRExplodedTime *gmt);
+
+/* Time parameters that represent Greenwich Mean Time */
+NSPR_API(PRTimeParameters) PR_GMTParameters(const PRExplodedTime *gmt);
+
+/*
+ * Time parameters that represent the US Pacific Time Zone, with the
+ * current daylight saving time rules (for testing only)
+ */
+NSPR_API(PRTimeParameters) PR_USPacificTimeParameters(const PRExplodedTime *gmt);
+
+/*
+ * This parses a time/date string into a PRExplodedTime
+ * struct. It populates all fields but it can't split
+ * the offset from UTC into tp_gmt_offset and tp_dst_offset in
+ * most cases (exceptions: PST/PDT, MST/MDT, CST/CDT, EST/EDT, GMT/BST).
+ * In those cases tp_gmt_offset will be the sum of these two and
+ * tp_dst_offset will be 0.
+ * It returns PR_SUCCESS on success, and PR_FAILURE
+ * if the time/date string can't be parsed.
+ *
+ * Many formats are handled, including:
+ *
+ *   14 Apr 89 03:20:12
+ *   14 Apr 89 03:20 GMT
+ *   Fri, 17 Mar 89 4:01:33
+ *   Fri, 17 Mar 89 4:01 GMT
+ *   Mon Jan 16 16:12 PDT 1989
+ *   Mon Jan 16 16:12 +0130 1989
+ *   6 May 1992 16:41-JST (Wednesday)
+ *   22-AUG-1993 10:59:12.82
+ *   22-AUG-1993 10:59pm
+ *   22-AUG-1993 12:59am
+ *   22-AUG-1993 12:59 PM
+ *   Friday, August 04, 1995 3:54 PM
+ *   06/21/95 04:24:34 PM
+ *   20/06/95 21:07
+ *   95-06-08 19:32:48 EDT
+ *
+ * If the input string doesn't contain a description of the timezone,
+ * we consult the `default_to_gmt' to decide whether the string should
+ * be interpreted relative to the local time zone (PR_FALSE) or GMT (PR_TRUE).
+ * The correct value for this argument depends on what standard specified
+ * the time string which you are parsing.
+ */
+
+NSPR_API(PRStatus) PR_ParseTimeStringToExplodedTime (
+        const char *string,
+        PRBool default_to_gmt,
+        PRExplodedTime *result);
+
+/*
+ * This uses PR_ParseTimeStringToExplodedTime to parse
+ * a time/date string and PR_ImplodeTime to transform it into
+ * a PRTime (microseconds after "1-Jan-1970 00:00:00 GMT").
+ * It returns PR_SUCCESS on success, and PR_FAILURE
+ * if the time/date string can't be parsed.
+ */
+
+NSPR_API(PRStatus) PR_ParseTimeString (
+	const char *string,
+	PRBool default_to_gmt,
+	PRTime *result);
+
+/*
+ * FIXME: should we also have a formatting function, such as asctime, ctime,
+ * and strftime in standard C library?  But this would involve
+ * internationalization issues.  Might want to provide a US English version.
+ */
+
+/**********************************************************************/
+/*********************** OLD COMPATIBILITYFUNCTIONS *******************/
+/**********************************************************************/
+#ifndef NO_NSPR_10_SUPPORT
+
+/* Format a time value into a buffer. Same semantics as strftime() */
+NSPR_API(PRUint32) PR_FormatTime(char *buf, int buflen, const char *fmt,
+                                           const PRExplodedTime *tm);
+
+/* Format a time value into a buffer. Time is always in US English format, regardless
+ * of locale setting.
+ */
+NSPR_API(PRUint32)
+PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize,
+                        const char* format, const PRExplodedTime* tm );
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+PR_END_EXTERN_C
+
+#endif /* prtime_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prtpool.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prtpool.h
new file mode 100644
index 0000000..2e1f6dd
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prtpool.h
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prtpool_h___
+#define prtpool_h___
+
+#include "prtypes.h"
+#include "prthread.h"
+#include "prio.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 *PRJobFn) (void *arg);
+
+/* Create thread pool */
+NSPR_API(PRThreadPool *)
+PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
+                          PRUint32 stacksize);
+
+/* queue a job */
+NSPR_API(PRJob *)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable);
+
+/* queue a job, when a socket is readable */
+NSPR_API(PRJob *)
+PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod,
+							PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when a socket is writeable */
+NSPR_API(PRJob *)
+PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod,
+								PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when a socket has a pending connection */
+NSPR_API(PRJob *)
+PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod,
+									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 */
+NSPR_API(PRJob *)
+PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
+								PRJobFn fn, void * arg, PRBool joinable);
+/* cancel a job */
+NSPR_API(PRStatus)
+PR_CancelJob(PRJob *job);
+
+/* join a job */
+NSPR_API(PRStatus)
+PR_JoinJob(PRJob *job);
+
+/* shutdown pool */
+NSPR_API(PRStatus)
+PR_ShutdownThreadPool(PRThreadPool *tpool);
+
+/* join pool, wait for exit of all threads */
+NSPR_API(PRStatus)
+PR_JoinThreadPool(PRThreadPool *tpool);
+
+PR_END_EXTERN_C
+
+#endif /* prtpool_h___ */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prtrace.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prtrace.h
new file mode 100644
index 0000000..42f88e9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prtrace.h
@@ -0,0 +1,678 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prtrace_h___
+#define prtrace_h___
+/*
+** prtrace.h -- NSPR's Trace Facility.  		           
+**                                                               		           
+** The Trace Facility provides a means to trace application				           
+** program events within a process. When implementing an         		           
+** application program an engineer may insert a "Trace" function 		           
+** call, passing arguments to be traced. The "Trace" function     		           
+** combines the user trace data with identifying data and        		           
+** writes this data in time ordered sequence into a circular     		           
+** in-memory buffer; when the buffer fills, it wraps.
+**                                                               		           
+** Functions are provided to set and/or re-configure the size of		           
+** the trace buffer, control what events are recorded in the			           
+** buffer, enable and disable tracing based on specific user			           
+** supplied data and other control functions. Methods are provided		           
+** to record the trace entries in the in-memory trace buffer to
+** a file.
+**                                                               		           
+** Tracing may cause a performance degredation to the application		           
+** depending on the number and placement of calls to the tracing		           
+** facility. When tracing is compiled in and all tracing is				           
+** disabled via the runtime controls, the overhead should be			           
+** minimal. ... Famous last words, eh?									           
+** 																                   
+** When DEBUG is defined at compile time, the Trace Facility is                    
+** compiled as part of NSPR and any application using NSPR's                       
+** header files will have tracing compiled in. When DEBUG is not                   
+** defined, the Trace Facility is not compiled into NSPR nor                       
+** exported in its header files.  If the Trace Facility is                         
+** desired in a non-debug build, then FORCE_NSPR_TRACE may be                      
+** defined at compile time for both the optimized build of NSPR                    
+** and the application. NSPR and any application using  NSPR's                     
+** Trace Facility must be compiled with the same level of trace                    
+** conditioning or unresolved references may be realized at link                   
+** time.                                                                           
+**                                                                                 
+** For any of the Trace Facility methods that requires a trace                     
+** handle as an input argument, the caller must ensure that the                    
+** trace handle argument is valid. An invalid trace handle                         
+** argument may cause unpredictable results.                                       
+**                                                                                 
+** Trace Facility methods are thread-safe and SMP safe.                            
+**                                                                                 
+** Users of the Trace Facility should use the defined macros to                     
+** invoke trace methods, not the function calls directly. e.g.                      
+** PR_TRACE( h1,0,1,2, ...); not PR_Trace(h1,0,1,2, ...);
+**                                                                                  
+** Application designers should be aware of the effects of
+** debug and optimized build differences when using result of the
+** Trace Facility macros in expressions.
+** 
+** See Also: prcountr.h                                                                                 
+**                                                                                  
+** /lth. 08-Jun-1998.                                                                                  
+*/
+
+#include "prtypes.h"
+#include "prthread.h"
+#include "prtime.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Opaque type for the trace handle 
+** ... Don't even think about looking in here.
+**
+*/
+typedef void *  PRTraceHandle;
+
+/*
+** PRTraceEntry -- A trace entry in the in-memory trace buffer
+** looks like this.
+**
+*/
+typedef struct PRTraceEntry
+{
+    PRThread        *thread;        /* The thread creating the trace entry */
+    PRTraceHandle   handle;         /* PRTraceHandle creating the trace entry */
+    PRTime          time;           /* Value of PR_Now() at time of trace entry */
+    PRUint32        userData[8];    /* user supplied trace data */
+} PRTraceEntry;
+
+/*
+** PRTraceOption -- command operands to
+** PR_[Set|Get]TraceOption(). See descriptive meanings there.
+**
+*/
+typedef enum PRTraceOption
+{
+    PRTraceBufSize,
+    PRTraceEnable,              
+    PRTraceDisable,
+    PRTraceSuspend,
+    PRTraceResume,
+    PRTraceSuspendRecording,
+    PRTraceResumeRecording,
+    PRTraceLockHandles,
+    PRTraceUnLockHandles,
+    PRTraceStopRecording
+} PRTraceOption;
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DEFINE_TRACE() -- Define a PRTraceHandle
+** 
+** DESCRIPTION: PR_DEFINE_TRACE() is used to define a trace
+** handle.
+** 
+*/
+#define PR_DEFINE_TRACE(name) PRTraceHandle name
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_INIT_TRACE_HANDLE() -- Set the value of a PRTraceHandle
+** 
+** DESCRIPTION: 
+** PR_INIT_TRACE_HANDLE() sets the value of a PRTraceHandle
+** to value. e.g. PR_INIT_TRACE_HANDLE( myHandle, NULL );
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_INIT_TRACE_HANDLE(handle,value)\
+    (handle) = (PRCounterHandle)(value)
+#else
+#define PR_INIT_TRACE_HANDLE(handle,value)
+#endif
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_CreateTrace() -- Create a trace handle
+** 
+** DESCRIPTION:
+**  PR_CreateTrace() creates a new trace handle. Tracing is
+**  enabled for this handle when it is created. The trace handle
+**  is intended for use in other Trace Facility calls.
+**  
+**  PR_CreateTrace() registers the QName, RName and description
+**  data so that this data can be retrieved later.
+** 
+** INPUTS: 
+**  qName: pointer to string. QName for this trace handle. 
+** 
+**  rName: pointer to string. RName for this trace handle. 
+** 
+**  description: pointer to string. Descriptive data about this
+**  trace handle.
+**
+** OUTPUTS:
+**  Creates the trace handle. 
+**  Registers the QName and RName with the trace facility.
+** 
+** RETURNS: 
+**  PRTraceHandle
+** 
+** RESTRICTIONS:
+**  qName is limited to 31 characters.
+**  rName is limited to 31 characters.
+**  description is limited to 255 characters.
+** 
+*/
+#define PRTRACE_NAME_MAX 31
+#define PRTRACE_DESC_MAX 255
+
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_CREATE_TRACE(handle,qName,rName,description)\
+    (handle) = PR_CreateTrace((qName),(rName),(description))
+#else
+#define PR_CREATE_TRACE(handle,qName,rName,description)
+#endif
+
+NSPR_API(PRTraceHandle)
+	PR_CreateTrace( 
+    	const char *qName,          /* QName for this trace handle */
+	    const char *rName,          /* RName for this trace handle */
+	    const char *description     /* description for this trace handle */
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DestroyTrace() -- Destroy a trace handle
+** 
+** DESCRIPTION: 
+**  PR_DestroyTrace() removes the referenced trace handle and
+** associated QName, RName and description data from the Trace
+** Facility.
+** 
+** INPUTS: handle. A PRTraceHandle
+** 
+** OUTPUTS: 
+**  The trace handle is unregistered.
+**  The QName, RName and description are removed.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_DESTROY_TRACE(handle)\
+    PR_DestroyTrace((handle))
+#else
+#define PR_DESTROY_TRACE(handle)
+#endif
+
+NSPR_API(void) 
+	PR_DestroyTrace( 
+		PRTraceHandle handle    /* Handle to be destroyed */
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_Trace() -- Make a trace entry in the in-memory trace
+** 
+** DESCRIPTION:
+** PR_Trace() makes an entry in the in-memory trace buffer for
+** the referenced trace handle. The next logically available
+** PRTraceEntry is used; when the next trace entry would overflow
+** the trace table, the table wraps.
+**
+** PR_Trace() for a specific trace handle may be disabled by
+** calling PR_SetTraceOption() specifying PRTraceDisable for the
+** trace handle to be disabled.
+** 
+** INPUTS:
+** handle: PRTraceHandle. The trace handle for this trace.
+** 
+** userData[0..7]: unsigned 32bit integers. user supplied data
+** that is copied into the PRTraceEntry
+** 
+** OUTPUTS:
+**  A PRTraceEntry is (conditionally) formatted in the in-memory
+** trace buffer.
+** 
+** RETURNS: void.
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_TRACE(handle,ud0,ud1,ud2,ud3,ud4,ud5,ud6,ud7)\
+    PR_Trace((handle),(ud0),(ud1),(ud2),(ud3),(ud4),(ud5),(ud6),(ud7))
+#else
+#define PR_TRACE(handle,ud0,ud1,ud2,ud3,ud4,ud5,ud6,ud7)
+#endif
+
+NSPR_API(void) 
+	PR_Trace( 
+    	PRTraceHandle handle,       /* use this trace handle */
+	    PRUint32    userData0,      /* User supplied data word 0 */
+	    PRUint32    userData1,      /* User supplied data word 1 */
+	    PRUint32    userData2,      /* User supplied data word 2 */
+	    PRUint32    userData3,      /* User supplied data word 3 */
+	    PRUint32    userData4,      /* User supplied data word 4 */
+	    PRUint32    userData5,      /* User supplied data word 5 */
+	    PRUint32    userData6,      /* User supplied data word 6 */
+	    PRUint32    userData7       /* User supplied data word 7 */
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_SetTraceOption() -- Control the Trace Facility
+** 
+** DESCRIPTION:
+** PR_SetTraceOption() controls the Trace Facility. Depending on
+** command and value, attributes of the Trace Facility may be
+** changed.
+** 
+** INPUTS:
+**  command: An enumerated value in the set of PRTraceOption.
+**  value: pointer to the data to be set. Type of the data is
+**  dependent on command; for each value of command, the type
+**  and meaning of dereferenced value is shown.
+**
+**  PRTraceBufSize: unsigned long: the size of the trace buffer,
+** in bytes.
+** 
+**  PRTraceEnable: PRTraceHandle. The trace handle to be
+** enabled.
+** 
+**  PRTraceDisable: PRTraceHandle. The trace handle to be
+** disabled.
+** 
+**  PRTraceSuspend: void. value must be NULL. All tracing is
+** suspended.
+** 
+**  PRTraceResume: void. value must be NULL. Tracing for all
+** previously enabled, prior to a PRTraceSuspend, is resumed.
+** 
+**  PRTraceStopRecording: void. value must be NULL. If recording
+** (see: ** PR_RecordTraceEntries()) is being done, 
+** PRTraceStopRecording causes PR_RecordTraceEntries() to return
+** to its caller. If recording is not being done, this function
+** has no effect.
+** 
+**  PRTraceSuspendRecording: void. Must be NULL. If recording is
+** being done, PRTraceSuspendRecording causes further writes to
+** the trace file to be suspended. Data in the in-memory
+** trace buffer that would ordinarily be written to the
+** trace file will not be written. Trace entries will continue
+** to be entered in the in-memory buffer. If the Trace Facility
+** recording is already in a suspended state, the call has no
+** effect.
+** 
+**  PRTraceResumeRecording: void. value must be NULL. If
+** recording for the Trace Facility has been previously been
+** suspended, this causes recording to resume. Recording resumes
+** with the next in-memory buffer segment that would be written
+** if trace recording had not been suspended. If recording is
+** not currently suspended, the call has no effect.
+** 
+**  PRTraceLockHandles: void. value must be NULL. Locks the
+** trace handle lock. While the trace handle lock is held,
+** calls to PR_CreateTrace() will block until the lock is
+** released.
+** 
+**  PRTraceUnlockHandles: void. value must be NULL. Unlocks the
+** trace handle lock.
+** 
+** OUTPUTS:
+**  The operation of the Trace Facility may be changed.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_SET_TRACE_OPTION(command,value)\
+    PR_SetTraceOption((command),(value))
+#else
+#define PR_SET_TRACE_OPTION(command,value)
+#endif
+
+NSPR_API(void) 
+	PR_SetTraceOption( 
+	    PRTraceOption command,  /* One of the enumerated values */
+	    void *value             /* command value or NULL */
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetTraceOption() -- Retrieve settings from the Trace Facility
+** 
+** DESCRIPTION:
+** PR_GetTraceOption() retrieves the current setting of the
+** Trace Facility control depending on command.
+** 
+** 
+**  PRTraceBufSize: unsigned long: the size of the trace buffer,
+** in bytes.
+** 
+** 
+** INPUTS:
+**  command: one of the enumerated values in PRTraceOptions
+** valid for PR_GetTraceOption().
+** 
+** OUTPUTS:
+**  dependent on command.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_GET_TRACE_OPTION(command,value)\
+    PR_GetTraceOption((command),(value))
+#else
+#define PR_GET_TRACE_OPTION(command,value)
+#endif
+
+NSPR_API(void) 
+	PR_GetTraceOption( 
+    	PRTraceOption command,  /* One of the enumerated values */
+	    void *value             /* command value or NULL */
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetTraceHandleFromName() -- Retrieve an existing
+** handle by name.
+** 
+** DESCRIPTION:
+** PR_GetTraceHandleFromName() retreives an existing tracehandle
+** using the name specified by qName and rName.
+** 
+** INPUTS:
+**  qName: pointer to string. QName for this trace handle. 
+** 
+**  rName: pointer to string. RName for this trace handle. 
+** 
+** 
+** OUTPUTS: returned.
+** 
+** RETURNS: 
+**  PRTraceHandle associated with qName and rName or NULL when
+** there is no match.
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_GET_TRACE_HANDLE_FROM_NAME(handle,qName,rName)\
+    (handle) = PR_GetTraceHandleFromName((qName),(rName))
+#else
+#define PR_GET_TRACE_HANDLE_FROM_NAME(handle,qName,rName)
+#endif
+
+NSPR_API(PRTraceHandle) 
+	PR_GetTraceHandleFromName( 
+    	const char *qName,      /* QName search argument */
+        const char *rName       /* RName search argument */
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetTraceNameFromHandle() -- Retreive trace name
+** by bandle.
+** 
+** DESCRIPTION:
+** PR_GetTraceNameFromHandle() retreives the existing qName,
+** rName, and description for the referenced trace handle.
+** 
+** INPUTS: handle: PRTraceHandle.
+** 
+** OUTPUTS: pointers to the Trace Facility's copy of qName,
+** rName and description. ... Don't mess with these values.
+** They're mine.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_GET_TRACE_NAME_FROM_HANDLE(handle,qName,rName,description)\
+    PR_GetTraceNameFromHandle((handle),(qName),(rName),(description))
+#else
+#define PR_GET_TRACE_NAME_FROM_HANDLE(handle,qName,rName,description)
+#endif
+
+NSPR_API(void) 
+	PR_GetTraceNameFromHandle( 
+    	PRTraceHandle handle,       /* handle as search argument */
+	    const char **qName,         /* pointer to associated QName */
+	    const char **rName,         /* pointer to associated RName */
+    	const char **description    /* pointer to associated description */
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_FindNextTraceQname() -- Retrieive a QName handle
+** iterator.
+** 
+** DESCRIPTION:
+** PR_FindNextTraceQname() retreives the first or next trace
+** QName handle, depending on the value of handle, from the trace
+** database. The PRTraceHandle returned can be used as an
+** iterator to traverse the QName handles in the Trace database.
+** 
+** INPUTS:
+**  handle: When NULL, PR_FindNextQname() returns the first QName
+** handle. When a handle is a valid PRTraceHandle previously
+** retreived using PR_FindNextQname() the next QName handle is
+** retreived.
+** 
+** OUTPUTS: returned.
+** 
+** RETURNS: 
+**  PRTraceHandle or NULL when there are no trace handles.
+** 
+** RESTRICTIONS:
+**  Iterating thru the trace handles via FindFirst/FindNext
+** should be done under protection of the trace handle lock.
+** See: PR_SetTraceOption( PRLockTraceHandles ).
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_FIND_NEXT_TRACE_QNAME(next,handle)\
+    (next) = PR_FindNextTraceQname((handle))
+#else
+#define PR_FIND_NEXT_TRACE_QNAME(next,handle)
+#endif
+
+NSPR_API(PRTraceHandle) 
+	PR_FindNextTraceQname( 
+        PRTraceHandle handle
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_FindNextTraceRname() -- Retrieive an RName handle
+** iterator.
+** 
+** DESCRIPTION:
+** PR_FindNextTraceRname() retreives the first or next trace
+** RName handle, depending on the value of handle, from the trace
+** database. The PRTraceHandle returned can be used as an
+** iterator to traverse the RName handles in the Trace database.
+** 
+** INPUTS:
+**  rhandle: When NULL, PR_FindNextRname() returns the first
+** RName handle. When a handle is a valid PRTraceHandle
+** previously retreived using PR_FindNextRname() the next RName
+** handle is retreived.
+**  qhandle: A valid PRTraceHandle retruned from a previous call
+** to PR_FIND_NEXT_TRACE_QNAME().
+** 
+** OUTPUTS: returned.
+** 
+** RETURNS: 
+**  PRTraceHandle or NULL when there are no trace handles.
+** 
+** RESTRICTIONS:
+**  Iterating thru the trace handles via FindNext should be done
+** under protection of the trace handle lock. See: (
+** PR_SetTraceOption( PRLockTraceHandles ).
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_FIND_NEXT_TRACE_RNAME(next,rhandle,qhandle)\
+    (next) = PR_FindNextTraceRname((rhandle),(qhandle))
+#else
+#define PR_FIND_NEXT_TRACE_RNAME(next,rhandle,qhandle)
+#endif
+
+NSPR_API(PRTraceHandle) 
+	PR_FindNextTraceRname( 
+        PRTraceHandle rhandle,
+        PRTraceHandle qhandle
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_RecordTraceEntries() -- Write trace entries to external media
+** 
+** DESCRIPTION:
+** PR_RecordTraceEntries() causes entries in the in-memory trace
+** buffer to be written to external media.
+**
+** When PR_RecordTraceEntries() is called from an application
+** thread, the function appears to block until another thread
+** calls PR_SetTraceOption() with the PRTraceStopRecording
+** option. This suggests that PR_RecordTraceEntries() should be
+** called from a user supplied thread whose only job is to
+** record trace entries. 
+** 
+** The environment variable NSPR_TRACE_LOG controls the operation
+** of this function. When NSPR_TRACE_LOG is not defined in the
+** environment, no recording of trace entries occurs. When
+** NSPR_TRACE_LOG is defined, the value of its definition must be
+** the filename of the file to receive the trace entry buffer.
+**
+** PR_RecordTraceEntries() attempts to record the in-memory
+** buffer to a file, subject to the setting of the environment
+** variable NSPR_TRACE_LOG. It is possible because of system
+** load, the thread priority of the recording thread, number of
+** active trace records being written over time, and other
+** variables that some trace records can be lost. ... In other
+** words: don't bet the farm on getting everything.
+** 
+** INPUTS: none
+** 
+** OUTPUTS: none
+** 
+** RETURNS: PR_STATUS
+**    PR_SUCCESS no errors were found.
+**    PR_FAILURE errors were found.
+** 
+** RESTRICTIONS:
+** Only one thread can call PR_RecordTraceEntries() within a
+** process.
+** 
+** On error, PR_RecordTraceEntries() may return prematurely.
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_RECORD_TRACE_ENTRIES()\
+	PR_RecordTraceEntries()
+#else
+#define PR_RECORD_TRACE_ENTRIES()
+#endif
+    
+NSPR_API(void)
+	PR_RecordTraceEntries(
+        void 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetTraceEntries() -- Retreive trace entries from
+** the Trace Facility
+** 
+** DESCRIPTION:
+** PR_GetTraceEntries() retreives trace entries from the Trace
+** Facility. Up to count trace entries are copied from the Trace
+** Facility into buffer. Only those trace entries that have not
+** been copied via a previous call to PR_GetTraceEntries() are
+** copied. The actual number copied is placed in the PRInt32
+** variable pointed to by found.
+**
+** If more than count trace entries have entered the Trace
+** Facility since the last call to PR_GetTraceEntries() 
+** a lost data condition is returned. In this case, the most
+** recent count trace entries are copied into buffer and found is
+** set to count.
+** 
+** INPUTS:
+**  count. The number of trace entries to be copied into buffer.
+** 
+** 
+** OUTPUTS:
+**  buffer. An array of PRTraceEntries. The buffer is supplied
+** by the caller.
+** 
+** found: 32bit signed integer. The number of PRTraceEntries
+** actually copied. found is always less than or equal to count.
+** 
+** RETURNS: 
+**  zero when there is no lost data.
+**  non-zero when some PRTraceEntries have been lost.
+** 
+** RESTRICTIONS:
+** This is a real performance pig. The copy out operation is bad
+** enough, but depending on then frequency of calls to the
+** function, serious performance impact to the operating
+** application may be realized. ... YMMV.
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_GET_TRACE_ENTRIES(buffer,count,found)\
+        PR_GetTraceEntries((buffer),(count),(found))
+#else
+#define PR_GET_TRACE_ENTRIES(buffer,count,found)
+#endif
+
+NSPR_API(PRIntn)
+    PR_GetTraceEntries(
+        PRTraceEntry    *buffer,    /* where to write output */
+        PRInt32         count,      /* number to get */
+        PRInt32         *found      /* number you got */
+);
+
+PR_END_EXTERN_C
+
+#endif /* prtrace_h___ */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prtypes.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prtypes.h
new file mode 100644
index 0000000..b764b27
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prtypes.h
@@ -0,0 +1,533 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:                prtypes.h
+** Description: Definitions of NSPR's basic types
+**
+** Prototypes and macros used to make up for deficiencies that we have found
+** in ANSI environments.
+**
+** Since we do not wrap <stdlib.h> and all the other standard headers, authors
+** of portable code will not know in general that they need these definitions.
+** Instead of requiring these authors to find the dependent uses in their code
+** and take the following steps only in those C files, we take steps once here
+** for all C files.
+**/
+
+#ifndef prtypes_h___
+#define prtypes_h___
+
+#ifdef MDCPUCFG
+#include MDCPUCFG
+#else
+#include "prcpucfg.h"
+#endif
+
+#include <stddef.h>
+
+/***********************************************************************
+** MACROS:      PR_EXTERN
+**              PR_IMPLEMENT
+** DESCRIPTION:
+**      These are only for externally visible routines and globals.  For
+**      internal routines, just use "extern" for type checking and that
+**      will not export internal cross-file or forward-declared symbols.
+**      Define a macro for declaring procedures return types. We use this to
+**      deal with windoze specific type hackery for DLL definitions. Use
+**      PR_EXTERN when the prototype for the method is declared. Use
+**      PR_IMPLEMENT for the implementation of the method.
+**
+** Example:
+**   in dowhim.h
+**     PR_EXTERN( void ) DoWhatIMean( void );
+**   in dowhim.c
+**     PR_IMPLEMENT( void ) DoWhatIMean( void ) { return; }
+**
+**
+***********************************************************************/
+#if defined(WIN32)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_BEOS)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_OS2) && defined(__declspec)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) extern  __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(SYMBIAN)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#ifdef __WINS__
+#define PR_IMPORT(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type
+#else
+#define PR_IMPORT(__type) extern __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type
+#endif
+
+#define PR_EXTERN(__type) extern __type
+#define PR_IMPLEMENT(__type) __type
+#define PR_EXTERN_DATA(__type) extern __type
+#define PR_IMPLEMENT_DATA(__type) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#else /* Unix */
+
+/* GCC 3.3 and later support the visibility attribute. */
+#if (__GNUC__ >= 4) || \
+    (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+#define PR_VISIBILITY_DEFAULT __attribute__((visibility("default")))
+#else
+#define PR_VISIBILITY_DEFAULT
+#endif
+
+#define PR_EXPORT(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_EXPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_IMPORT(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_IMPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type
+
+#define PR_EXTERN(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_IMPLEMENT(__type) PR_VISIBILITY_DEFAULT __type
+#define PR_EXTERN_DATA(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_IMPLEMENT_DATA(__type) PR_VISIBILITY_DEFAULT __type
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#endif
+
+#if defined(_NSPR_BUILD_)
+#define NSPR_API(__type) PR_EXPORT(__type)
+#define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type)
+#else
+#define NSPR_API(__type) PR_IMPORT(__type)
+#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type)
+#endif
+
+/***********************************************************************
+** MACROS:      PR_BEGIN_MACRO
+**              PR_END_MACRO
+** DESCRIPTION:
+**      Macro body brackets so that macros with compound statement definitions
+**      behave syntactically more like functions when called.
+***********************************************************************/
+#define PR_BEGIN_MACRO  do {
+#define PR_END_MACRO    } while (0)
+
+/***********************************************************************
+** MACROS:      PR_BEGIN_EXTERN_C
+**              PR_END_EXTERN_C
+** DESCRIPTION:
+**      Macro shorthands for conditional C++ extern block delimiters.
+***********************************************************************/
+#ifdef __cplusplus
+#define PR_BEGIN_EXTERN_C       extern "C" {
+#define PR_END_EXTERN_C         }
+#else
+#define PR_BEGIN_EXTERN_C
+#define PR_END_EXTERN_C
+#endif
+
+/***********************************************************************
+** MACROS:      PR_BIT
+**              PR_BITMASK
+** DESCRIPTION:
+** Bit masking macros.  XXX n must be <= 31 to be portable
+***********************************************************************/
+#define PR_BIT(n)       ((PRUint32)1 << (n))
+#define PR_BITMASK(n)   (PR_BIT(n) - 1)
+
+/***********************************************************************
+** MACROS:      PR_ROUNDUP
+**              PR_MIN
+**              PR_MAX
+**              PR_ABS
+** DESCRIPTION:
+**      Commonly used macros for operations on compatible types.
+***********************************************************************/
+#define PR_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
+#define PR_MIN(x,y)     ((x)<(y)?(x):(y))
+#define PR_MAX(x,y)     ((x)>(y)?(x):(y))
+#define PR_ABS(x)       ((x)<0?-(x):(x))
+
+PR_BEGIN_EXTERN_C
+
+/************************************************************************
+** TYPES:       PRUint8
+**              PRInt8
+** DESCRIPTION:
+**  The int8 types are known to be 8 bits each. There is no type that
+**      is equivalent to a plain "char". 
+************************************************************************/
+#if PR_BYTES_PER_BYTE == 1
+typedef unsigned char PRUint8;
+/*
+** Some cfront-based C++ compilers do not like 'signed char' and
+** issue the warning message:
+**     warning: "signed" not implemented (ignored)
+** For these compilers, we have to define PRInt8 as plain 'char'.
+** Make sure that plain 'char' is indeed signed under these compilers.
+*/
+#if (defined(HPUX) && defined(__cplusplus) \
+        && !defined(__GNUC__) && __cplusplus < 199707L) \
+    || (defined(SCO) && defined(__cplusplus) \
+        && !defined(__GNUC__) && __cplusplus == 1L)
+typedef char PRInt8;
+#else
+typedef signed char PRInt8;
+#endif
+#else
+#error No suitable type for PRInt8/PRUint8
+#endif
+
+/************************************************************************
+ * MACROS:      PR_INT8_MAX
+ *              PR_INT8_MIN
+ *              PR_UINT8_MAX
+ * DESCRIPTION:
+ *  The maximum and minimum values of a PRInt8 or PRUint8.
+************************************************************************/
+
+#define PR_INT8_MAX 127
+#define PR_INT8_MIN (-128)
+#define PR_UINT8_MAX 255U
+
+/************************************************************************
+** TYPES:       PRUint16
+**              PRInt16
+** DESCRIPTION:
+**  The int16 types are known to be 16 bits each. 
+************************************************************************/
+#if PR_BYTES_PER_SHORT == 2
+typedef unsigned short PRUint16;
+typedef short PRInt16;
+#else
+#error No suitable type for PRInt16/PRUint16
+#endif
+
+/************************************************************************
+ * MACROS:      PR_INT16_MAX
+ *              PR_INT16_MIN
+ *              PR_UINT16_MAX
+ * DESCRIPTION:
+ *  The maximum and minimum values of a PRInt16 or PRUint16.
+************************************************************************/
+
+#define PR_INT16_MAX 32767
+#define PR_INT16_MIN (-32768)
+#define PR_UINT16_MAX 65535U
+
+/************************************************************************
+** TYPES:       PRUint32
+**              PRInt32
+** DESCRIPTION:
+**  The int32 types are known to be 32 bits each. 
+************************************************************************/
+#if PR_BYTES_PER_INT == 4
+typedef unsigned int PRUint32;
+typedef int PRInt32;
+#define PR_INT32(x)  x
+#define PR_UINT32(x) x ## U
+#elif PR_BYTES_PER_LONG == 4
+typedef unsigned long PRUint32;
+typedef long PRInt32;
+#define PR_INT32(x)  x ## L
+#define PR_UINT32(x) x ## UL
+#else
+#error No suitable type for PRInt32/PRUint32
+#endif
+
+/************************************************************************
+ * MACROS:      PR_INT32_MAX
+ *              PR_INT32_MIN
+ *              PR_UINT32_MAX
+ * DESCRIPTION:
+ *  The maximum and minimum values of a PRInt32 or PRUint32.
+************************************************************************/
+
+#define PR_INT32_MAX PR_INT32(2147483647)
+#define PR_INT32_MIN (-PR_INT32_MAX - 1)
+#define PR_UINT32_MAX PR_UINT32(4294967295)
+
+/************************************************************************
+** TYPES:       PRUint64
+**              PRInt64
+** DESCRIPTION:
+**  The int64 types are known to be 64 bits each. Care must be used when
+**      declaring variables of type PRUint64 or PRInt64. Different hardware
+**      architectures and even different compilers have varying support for
+**      64 bit values. The only guaranteed portability requires the use of
+**      the LL_ macros (see prlong.h).
+************************************************************************/
+#ifdef HAVE_LONG_LONG
+/* Keep this in sync with prlong.h. */
+/*
+ * On 64-bit Mac OS X, uint64 needs to be defined as unsigned long long to
+ * match uint64_t, otherwise our uint64 typedef conflicts with the uint64
+ * typedef in cssmconfig.h, which CoreServices.h includes indirectly.
+ */
+#if PR_BYTES_PER_LONG == 8 && !defined(__APPLE__)
+typedef long PRInt64;
+typedef unsigned long PRUint64;
+#elif defined(WIN32) && !defined(__GNUC__)
+typedef __int64  PRInt64;
+typedef unsigned __int64 PRUint64;
+#else
+typedef long long PRInt64;
+typedef unsigned long long PRUint64;
+#endif /* PR_BYTES_PER_LONG == 8 */
+#else  /* !HAVE_LONG_LONG */
+typedef struct {
+#ifdef IS_LITTLE_ENDIAN
+    PRUint32 lo, hi;
+#else
+    PRUint32 hi, lo;
+#endif
+} PRInt64;
+typedef PRInt64 PRUint64;
+#endif /* !HAVE_LONG_LONG */
+
+/************************************************************************
+** TYPES:       PRUintn
+**              PRIntn
+** DESCRIPTION:
+**  The PRIntn types are most appropriate for automatic variables. They are
+**      guaranteed to be at least 16 bits, though various architectures may
+**      define them to be wider (e.g., 32 or even 64 bits). These types are
+**      never valid for fields of a structure. 
+************************************************************************/
+#if PR_BYTES_PER_INT >= 2
+typedef int PRIntn;
+typedef unsigned int PRUintn;
+#else
+#error 'sizeof(int)' not sufficient for platform use
+#endif
+
+/************************************************************************
+** TYPES:       PRFloat64
+** DESCRIPTION:
+**  NSPR's floating point type is always 64 bits. 
+************************************************************************/
+typedef double          PRFloat64;
+
+/************************************************************************
+** TYPES:       PRSize
+** DESCRIPTION:
+**  A type for representing the size of objects. 
+************************************************************************/
+typedef size_t PRSize;
+
+
+/************************************************************************
+** TYPES:       PROffset32, PROffset64
+** DESCRIPTION:
+**  A type for representing byte offsets from some location. 
+************************************************************************/
+typedef PRInt32 PROffset32;
+typedef PRInt64 PROffset64;
+
+/************************************************************************
+** TYPES:       PRPtrDiff
+** DESCRIPTION:
+**  A type for pointer difference. Variables of this type are suitable
+**      for storing a pointer or pointer subtraction. 
+************************************************************************/
+typedef ptrdiff_t PRPtrdiff;
+
+/************************************************************************
+** TYPES:       PRUptrdiff
+** DESCRIPTION:
+**  A type for pointer difference. Variables of this type are suitable
+**      for storing a pointer or pointer sutraction. 
+************************************************************************/
+#ifdef _WIN64
+typedef PRUint64 PRUptrdiff;
+#else
+typedef unsigned long PRUptrdiff;
+#endif
+
+/************************************************************************
+** TYPES:       PRBool
+** DESCRIPTION:
+**  Use PRBool for variables and parameter types. Use PR_FALSE and PR_TRUE
+**      for clarity of target type in assignments and actual arguments. Use
+**      'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
+**      just as you would C int-valued conditions. 
+************************************************************************/
+typedef PRIntn PRBool;
+#define PR_TRUE 1
+#define PR_FALSE 0
+
+/************************************************************************
+** TYPES:       PRPackedBool
+** DESCRIPTION:
+**  Use PRPackedBool within structs where bitfields are not desirable
+**      but minimum and consistant overhead matters.
+************************************************************************/
+typedef PRUint8 PRPackedBool;
+
+/*
+** Status code used by some routines that have a single point of failure or 
+** special status return.
+*/
+typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
+
+#ifndef __PRUNICHAR__
+#define __PRUNICHAR__
+#ifdef WIN32
+typedef wchar_t PRUnichar;
+#else
+typedef PRUint16 PRUnichar;
+#endif
+#endif
+
+/*
+** WARNING: The undocumented data types PRWord and PRUword are
+** only used in the garbage collection and arena code.  Do not
+** use PRWord and PRUword in new code.
+**
+** A PRWord is an integer that is the same size as a void*.
+** It implements the notion of a "word" in the Java Virtual
+** Machine.  (See Sec. 3.4 "Words", The Java Virtual Machine
+** Specification, Addison-Wesley, September 1996.
+** http://java.sun.com/docs/books/vmspec/index.html.)
+*/
+#ifdef _WIN64
+typedef PRInt64 PRWord;
+typedef PRUint64 PRUword;
+#else
+typedef long PRWord;
+typedef unsigned long PRUword;
+#endif
+
+#if defined(NO_NSPR_10_SUPPORT)
+#else
+/********* ???????????????? FIX ME       ??????????????????????????? *****/
+/********************** Some old definitions until pr=>ds transition is done ***/
+/********************** Also, we are still using NSPR 1.0. GC ******************/
+/*
+** Fundamental NSPR macros, used nearly everywhere.
+*/
+
+#define PR_PUBLIC_API		PR_IMPLEMENT
+
+/*
+** Macro body brackets so that macros with compound statement definitions
+** behave syntactically more like functions when called.
+*/
+#define NSPR_BEGIN_MACRO        do {
+#define NSPR_END_MACRO          } while (0)
+
+/*
+** Macro shorthands for conditional C++ extern block delimiters.
+*/
+#ifdef NSPR_BEGIN_EXTERN_C
+#undef NSPR_BEGIN_EXTERN_C
+#endif
+#ifdef NSPR_END_EXTERN_C
+#undef NSPR_END_EXTERN_C
+#endif
+
+#ifdef __cplusplus
+#define NSPR_BEGIN_EXTERN_C     extern "C" {
+#define NSPR_END_EXTERN_C       }
+#else
+#define NSPR_BEGIN_EXTERN_C
+#define NSPR_END_EXTERN_C
+#endif
+
+#include "obsolete/protypes.h"
+
+/********* ????????????? End Fix me ?????????????????????????????? *****/
+#endif /* NO_NSPR_10_SUPPORT */
+
+/*
+** Compile-time assert. "condition" must be a constant expression.
+** The macro can be used only in places where an "extern" declaration is
+** allowed.
+*/
+#define PR_STATIC_ASSERT(condition) \
+    extern void pr_static_assert(int arg[(condition) ? 1 : -1])
+
+PR_END_EXTERN_C
+
+#endif /* prtypes_h___ */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prvrsion.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prvrsion.h
new file mode 100755
index 0000000..eb8e1e6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prvrsion.h
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/* author: jstewart */
+
+#if defined(_PRVERSION_H)
+#else
+#define _PRVERSION_H
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/* All components participating in the PR version protocol must expose
+ * a structure and a function. The structure is defined below and named
+ * according to the naming conventions outlined further below.  The function
+ * is called libVersionPoint and returns a pointer to this structure.
+ */
+
+/* on NT, always pack the structure the same. */
+#ifdef _WIN32
+#pragma pack(push, 8)
+#endif
+
+typedef struct {
+    /*
+     * The first field defines which version of this structure is in use.
+     * At this time, only version 2 is specified. If this value is not 
+     * 2, you must read no further into the structure.
+     */
+    PRInt32    version; 
+  
+    /* for Version 2, this is the body format. */
+    PRInt64         buildTime;      /* 64 bits - usecs since midnight, 1/1/1970 */
+    char *          buildTimeString;/* a human readable version of the time */
+  
+    PRUint8   vMajor;               /* Major version of this component */
+    PRUint8   vMinor;               /* Minor version of this component */
+    PRUint8   vPatch;               /* Patch level of this component */
+  
+    PRBool          beta;           /* true if this is a beta component */
+    PRBool          debug;          /* true if this is a debug component */
+    PRBool          special;        /* true if this component is a special build */
+  
+    char *          filename;       /* The original filename */
+    char *          description;    /* description of this component */
+    char *          security;       /* level of security in this component */
+    char *          copyright;      /* The copyright for this file */
+    char *          comment;        /* free form field for misc usage */
+    char *          specialString;  /* the special variant for this build */
+} PRVersionDescription;
+
+/* 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;
+ *   }
+ */
+typedef const PRVersionDescription *(*versionEntryPointType)(void);
+
+/* 
+ * Where you declare your libVersionPoint, do it like this: 
+ * PR_IMPLEMENT(const PRVersionDescription *) libVersionPoint(void) {
+ *  fill it in...
+ * }
+ */
+
+/*
+ * NAMING CONVENTION FOR struct
+ *
+ * all components should also expose a static PRVersionDescription
+ * The name of the struct should be calculated as follows:
+ * Take the value of filename. (If filename is not specified, calculate
+ * a short, unique string.)  Convert all non-alphanumeric characters
+ * to '_'.  To this, prepend "PRVersionDescription_".  Thus for libfoo.so,
+ * the symbol name is "PRVersionDescription_libfoo_so".
+ * so the file should have
+ * PRVersionDescription PRVersionDescription_libfoo_so { fill it in };
+ * on NT, this file should be declspec export.
+ */
+
+PR_END_EXTERN_C
+
+#endif  /* defined(_PRVERSION_H) */
+
+/* prvrsion.h */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/include/prwin16.h b/nspr-4.8.6/mozilla/nsprpub/pr/include/prwin16.h
new file mode 100644
index 0000000..215b051
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/include/prwin16.h
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prwin16_h___
+#define prwin16_h___
+
+/*
+** Condition use of this header on platform.
+*/
+#if (defined(XP_PC) && !defined(_WIN32) && !defined(XP_OS2) && defined(MOZILLA_CLIENT)) || defined(WIN16)
+#include <stdio.h>
+
+PR_BEGIN_EXTERN_C
+/* 
+** Win16 stdio special case.
+** To get stdio to work for Win16, all calls to printf() and related
+** things must be called from the environment of the .EXE; calls to
+** printf() from the .DLL send output to the bit-bucket.
+**
+** To make sure that PR_fprintf(), and related functions, work correctly,
+** the actual stream I/O to stdout, stderr, stdin must be done in the
+** .EXE. To do this, a hack is placed in _MD_Write() such that the
+** fd for stdio handles results in a call to the .EXE.
+**
+** file w16stdio.c contains the functions that get called from NSPR
+** to do the actual I/O. w16stdio.o must be statically linked with
+** any application needing stdio for Win16.
+**
+** The address of these functions must be made available to the .DLL
+** so he can call back to the .EXE. To do this, function 
+** PR_MD_RegisterW16StdioCallbacks() is called from the .EXE.
+** The arguments are the functions defined in w16stdio.c
+** At runtime, MD_Write() calls the registered functions, if any
+** were registered.
+**
+** prinit.h contains a macro PR_STDIO_INIT() that calls the registration
+** function for Win16; For other platforms, the macro is a No-Op.
+**
+** Note that stdio is not operational at all on Win16 GUI applications.
+** This special case exists to provide stdio capability from the NSPR
+** .DLL for command line applications only. NSPR's test cases are
+** almost exclusively command line applications.
+**
+** See also: w16io.c, w16stdio.c
+*/
+typedef PRInt32 (PR_CALLBACK *PRStdinRead)( void *buf, PRInt32 amount);
+typedef PRInt32 (PR_CALLBACK *PRStdoutWrite)( void *buf, PRInt32 amount);
+typedef PRInt32 (PR_CALLBACK *PRStderrWrite)( void *buf, PRInt32 amount);
+
+NSPR_API(PRStatus)
+PR_MD_RegisterW16StdioCallbacks( 
+    PRStdinRead inReadf,            /* i: function pointer for stdin read       */
+    PRStdoutWrite outWritef,        /* i: function pointer for stdout write     */
+    PRStderrWrite errWritef         /* i: function pointer for stderr write     */
+    );
+
+NSPR_API(PRInt32)
+_PL_W16StdioWrite( void *buf, PRInt32 amount );
+
+NSPR_API(PRInt32)
+_PL_W16StdioRead( void *buf, PRInt32 amount );
+
+#define PR_STDIO_INIT() PR_MD_RegisterW16StdioCallbacks( \
+    _PL_W16StdioRead, _PL_W16StdioWrite, _PL_W16StdioWrite ); \
+    PR_INIT_CALLBACKS();
+
+/*
+** Win16 hackery.
+**
+*/
+struct PRMethodCallbackStr {
+    int     (PR_CALLBACK *auxOutput)(const char *outputString);
+    size_t  (PR_CALLBACK *strftime)(char *s, size_t len, const char *fmt, const struct tm *p);
+    void *  (PR_CALLBACK *malloc)( size_t size );
+    void *  (PR_CALLBACK *calloc)(size_t n, size_t size );
+    void *  (PR_CALLBACK *realloc)( void* old_blk, size_t size );
+    void    (PR_CALLBACK *free)( void *ptr );
+    void *  (PR_CALLBACK *getenv)( const char *name);
+    int     (PR_CALLBACK *putenv)( const char *assoc);
+/*    void *  (PR_CALLBACK *perror)( const char *prefix ); */
+};
+
+NSPR_API(void) PR_MDRegisterCallbacks(struct PRMethodCallbackStr *);
+
+int PR_CALLBACK _PL_W16CallBackPuts( const char *outputString );
+size_t PR_CALLBACK _PL_W16CallBackStrftime( 
+    char *s, 
+    size_t len, 
+    const char *fmt,
+    const struct tm *p );
+void * PR_CALLBACK _PL_W16CallBackMalloc( size_t size );
+void * PR_CALLBACK _PL_W16CallBackCalloc( size_t n, size_t size );
+void * PR_CALLBACK _PL_W16CallBackRealloc( 
+    void *old_blk, 
+    size_t size );
+void   PR_CALLBACK _PL_W16CallBackFree( void *ptr );
+void * PR_CALLBACK _PL_W16CallBackGetenv( const char *name );
+int PR_CALLBACK _PL_W16CallBackPutenv( const char *assoc );
+
+/*
+** Hackery! 
+**
+** These functions are provided as static link points.
+** This is to satisfy the quick port of Gromit to NSPR 2.0
+** ... Don't do this! ... alas, It may never go away.
+** 
+*/
+NSPR_API(int)     PR_MD_printf(const char *, ...);
+NSPR_API(void)    PR_MD_exit(int);
+NSPR_API(size_t)  PR_MD_strftime(char *, size_t, const char *, const struct tm *); 
+NSPR_API(int)     PR_MD_sscanf(const char *, const char *, ...);
+NSPR_API(void*)   PR_MD_malloc( size_t size );
+NSPR_API(void*)   PR_MD_calloc( size_t n, size_t size );
+NSPR_API(void*)   PR_MD_realloc( void* old_blk, size_t size );
+NSPR_API(void)    PR_MD_free( void *ptr );
+NSPR_API(char*)   PR_MD_getenv( const char *name );
+NSPR_API(int)     PR_MD_putenv( const char *assoc );
+NSPR_API(int)     PR_MD_fprintf(FILE *fPtr, const char *fmt, ...);
+
+#define PR_INIT_CALLBACKS()                         \
+    {                                               \
+        static struct PRMethodCallbackStr cbf = {   \
+            _PL_W16CallBackPuts,                    \
+            _PL_W16CallBackStrftime,                \
+            _PL_W16CallBackMalloc,                  \
+            _PL_W16CallBackCalloc,                  \
+            _PL_W16CallBackRealloc,                 \
+            _PL_W16CallBackFree,                    \
+            _PL_W16CallBackGetenv,                  \
+            _PL_W16CallBackPutenv,                  \
+        };                                          \
+        PR_MDRegisterCallbacks( &cbf );             \
+    }
+
+
+/*
+** Get the exception context for Win16 MFC applications threads
+*/
+NSPR_API(void *) PR_W16GetExceptionContext(void);
+/*
+** Set the exception context for Win16 MFC applications threads
+*/
+NSPR_API(void) PR_W16SetExceptionContext(void *context);
+
+PR_END_EXTERN_C
+#else
+/*
+** For platforms other than Win16, define
+** PR_STDIO_INIT() as a No-Op.
+*/
+#define PR_STDIO_INIT()
+#endif /* WIN16 || MOZILLA_CLIENT */
+
+#endif /* prwin16_h___ */
+
+
+
+
+
+
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/Makefile.in
new file mode 100644
index 0000000..3514ab1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/Makefile.in
@@ -0,0 +1,406 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = io linking malloc md memory misc threads
+
+ifeq ($(USE_PTHREADS), 1)
+	DIRS += pthreads
+endif
+
+ifeq ($(USE_BTHREADS), 1)
+	DIRS += bthreads
+endif
+
+ifeq ($(USE_CPLUS), 1)
+	DIRS += cplus
+endif
+
+#
+# Define platform-dependent OS_LIBS
+#
+
+ifeq ($(OS_ARCH),SunOS)
+ifeq ($(OS_RELEASE),4.1.3_U1)
+OS_LIBS			= -lm
+else	# 4.1.3_U1
+MAPFILE = $(OBJDIR)/nsprmap.sun
+GARBAGE += $(MAPFILE)
+ifdef NS_USE_GCC
+ifdef GCC_USE_GNU_LD
+MKSHLIB += -Wl,--version-script,$(MAPFILE)
+else
+MKSHLIB += -Wl,-M,$(MAPFILE)
+endif
+else
+MKSHLIB += -M $(MAPFILE)
+endif
+#
+# In Solaris 2.6 or earlier, -lrt is called -lposix4.
+# 
+LIBRT_TEST=$(firstword $(sort 5.7 $(OS_RELEASE)))
+ifeq (5.7, $(LIBRT_TEST))
+LIBRT=-lrt
+else
+LIBRT=-lposix4
+endif
+
+ifdef USE_PTHREADS
+OS_LIBS			= -lpthread ${LIBRT} -lsocket -lnsl -ldl -lc
+else
+OS_LIBS			= -lsocket -lnsl -ldl -lc
+endif	# USE_PTHREADS
+ifeq ($(CPU_ARCH),sparc)
+ifndef USE_64
+DSO_LDOPTS	+= -Wl,-f,\$$ORIGIN/cpu/\$$ISALIST/lib$(ULTRASPARC_LIBRARY)$(LIBRARY_VERSION).so
+endif
+endif	# sparc
+endif	# 4.1.3_U1
+endif	# SunOS
+
+ifeq ($(OS_ARCH), IRIX)
+ifeq ($(USE_PTHREADS), 1)
+OS_LIBS = -lpthread
+endif
+OS_LIBS += -lc
+endif
+
+ifeq ($(OS_ARCH),AIX)
+DSO_LDOPTS	+= -binitfini::_PR_Fini
+OS_LIBS		= -lodm -lcfg
+ifeq ($(CLASSIC_NSPR),1)
+ifeq ($(OS_RELEASE),4.1)
+OS_LIBS		+= -lsvld -lc
+else
+OS_LIBS		+= -ldl -lc
+endif
+else
+ifeq ($(OS_RELEASE),4.1)
+OS_LIBS		+= -lpthreads -lsvld -lC_r -lC -lc_r -lm /usr/lib/libc.a
+else
+OS_LIBS		+= -lpthreads -ldl -lC_r -lC -lc_r -lm /usr/lib/libc.a
+endif
+endif
+endif
+
+# On AIX, we override malloc in non-pthread versions.  On AIX 4.2 or
+# above, this requires that we use the rtl-enabled version of libc.a.
+ifeq ($(OS_ARCH),AIX)
+ifneq (,$(filter-out 3.2 4.1,$(OS_RELEASE)))
+ifneq ($(USE_PTHREADS),1)
+BUILD_AIX_RTL_LIBC = 1
+AIX_RTL_LIBC	= $(OBJDIR)/libc.a
+endif
+endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def
+ADD_TO_DEF_FILE = cat $(srcdir)/os2extra.def >> $(MAPFILE)
+GARBAGE += $(MAPFILE)
+MKSHLIB += $(MAPFILE)
+endif
+
+ifeq ($(OS_ARCH),OSF1)
+ifeq ($(USE_PTHREADS), 1)
+OS_LIBS 	= -lpthread -lrt
+endif
+ifneq ($(OS_RELEASE),V2.0)
+OS_LIBS		+= -lc_r
+endif
+endif
+
+ifeq ($(OS_ARCH),Linux)
+ifeq ($(USE_PTHREADS), 1)
+OS_LIBS		= -lpthread -ldl
+else
+OS_LIBS		= -ldl
+endif
+endif
+
+ifeq ($(OS_ARCH),HP-UX)
+ifeq ($(USE_PTHREADS), 1)
+ifeq (,$(filter-out B.10.10 B.10.20,$(OS_RELEASE)))
+OS_LIBS 	= -ldce
+else
+OS_LIBS 	= -lpthread -lrt
+endif
+endif
+ifeq ($(PTHREADS_USER), 1)
+OS_LIBS 	= -lpthread
+endif
+ifeq ($(basename $(OS_RELEASE)),A.09)
+OS_LIBS		+= -ldld -L/lib/pa1.1 -lm
+else
+OS_LIBS		+= -ldld -lm -lc
+endif
+ifneq ($(OS_TEST),ia64)
+ifndef USE_64
+DSO_LDOPTS	+= +I PR_HPUX10xInit
+endif
+endif
+endif
+
+ifeq ($(OS_ARCH),UNIXWARE)
+OS_LIBS		= -lsocket -lc
+endif
+
+ifeq ($(OS_ARCH),NEWS-OS)
+OS_LIBS		= -lsocket -lnsl -lgen -lresolv
+endif
+
+ifeq ($(OS_ARCH),WINNT)
+ifdef NS_USE_GCC
+OS_LIBS		= -ladvapi32 -lwsock32 -lwinmm
+else
+OS_LIBS		= advapi32.lib wsock32.lib winmm.lib
+endif
+endif
+
+ifeq ($(OS_ARCH),WINCE)
+OS_LIBS		= ws2.lib
+endif
+
+ifeq ($(OS_TARGET),MacOSX)
+OS_LIBS		= -framework CoreServices -framework CoreFoundation
+endif
+
+ifdef GC_LEAK_DETECTOR
+EXTRA_LIBS	= -L$(dist_libdir) -lboehm
+endif
+
+EXTRA_LIBS += $(OS_LIBS)
+
+#
+# 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) \
+	threads/$(OBJDIR)/prrwlock.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prtpd.$(OBJ_SUFFIX) \
+    linking/$(OBJDIR)/prlink.$(OBJ_SUFFIX) \
+    malloc/$(OBJDIR)/prmalloc.$(OBJ_SUFFIX) \
+    malloc/$(OBJDIR)/prmem.$(OBJ_SUFFIX) \
+    md/$(OBJDIR)/prosdep.$(OBJ_SUFFIX) \
+    memory/$(OBJDIR)/prshm.$(OBJ_SUFFIX) \
+    memory/$(OBJDIR)/prshma.$(OBJ_SUFFIX) \
+    memory/$(OBJDIR)/prseg.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/pralarm.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/pratom.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prcountr.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prdtoa.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prenv.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prerr.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prerror.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prerrortable.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prinit.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prinrval.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/pripc.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prlog2.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prlong.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prnetdb.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/praton.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prolock.$(OBJ_SUFFIX)	 \
+    misc/$(OBJDIR)/prrng.$(OBJ_SUFFIX)	 \
+    misc/$(OBJDIR)/prsystem.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prthinfo.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prtpool.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prtrace.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prtime.$(OBJ_SUFFIX)
+
+ifdef USE_PTHREADS
+OBJS += \
+    pthreads/$(OBJDIR)/ptsynch.$(OBJ_SUFFIX) \
+    pthreads/$(OBJDIR)/ptio.$(OBJ_SUFFIX) \
+    pthreads/$(OBJDIR)/ptthread.$(OBJ_SUFFIX) \
+    pthreads/$(OBJDIR)/ptmisc.$(OBJ_SUFFIX)
+else
+OBJS += \
+    io/$(OBJDIR)/prdir.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prfile.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prio.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prsocket.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/pripcsem.$(OBJ_SUFFIX)
+
+ifndef USE_BTHREADS
+OBJS += \
+	threads/$(OBJDIR)/prcthr.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prdump.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prmon.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prsem.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/prucpu.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX)
+endif
+
+endif
+
+ifeq ($(USE_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) \
+	cplus/$(OBJDIR)/rcnetdb.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rcnetio.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rcthread.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rctime.$(OBJ_SUFFIX)
+endif
+
+ifdef GC_LEAK_DETECTOR
+OBJS += memory/$(OBJDIR)/prgcleak.$(OBJ_SUFFIX)
+endif
+
+ifeq ($(OS_ARCH), WINNT)
+RES=$(OBJDIR)/nspr.res
+RESNAME=nspr.rc
+endif # WINNT
+
+include $(srcdir)/md/$(PR_MD_ARCH_DIR)/objs.mk
+ifdef USE_BTHREADS
+include $(srcdir)/bthreads/objs.mk
+endif
+
+LIBRARY_NAME = nspr
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_LIBS = $(TARGETS)
+
+include $(topsrcdir)/config/rules.mk
+
+ifeq ($(BUILD_AIX_RTL_LIBC),1)
+TARGETS		+= $(AIX_RTL_LIBC)
+# XXX is this a shared library?
+endif
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+TINC = $(OBJDIR)/_pr_bld.h
+
+ifeq ($(OS_TARGET),OS2)
+PROD = nspr$(MOD_MAJOR_VERSION).$(DLL_SUFFIX)
+else
+PROD = $(notdir $(SHARED_LIBRARY))
+endif
+
+NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
+SH_DATE = $(shell date "+%Y-%m-%d %T")
+SH_NOW = $(shell $(NOW))
+
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	SUF = i64
+else
+	SUF = LL
+endif
+
+DEFINES		+= -D_NSPR_BUILD_
+
+GARBAGE += $(TINC)
+
+$(TINC):
+	@$(MAKE_OBJDIR)
+	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+	@if test ! -z "$(SH_NOW)"; then \
+	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+	else \
+	    true; \
+	fi
+	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
+
+
+$(OBJDIR)/prvrsion.$(OBJ_SUFFIX): prvrsion.c $(TINC)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+	$(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+endif
+#
+# Version information generation (end)
+#
+
+
+#
+# The Client build wants the shared libraries in $(dist_bindir)
+# so we also install them there.
+#
+
+export:: $(TARGETS)
+	$(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifdef SHARED_LIBRARY
+ifeq ($(OS_ARCH),HP-UX)
+	$(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir)
+	$(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir)
+else
+	$(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir)
+endif
+endif
+
+ifeq ($(BUILD_AIX_RTL_LIBC),1)
+$(AIX_RTL_LIBC): /usr/ccs/lib/libc.a
+	rtl_enable -o $@ $<
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/Makefile.in
new file mode 100644
index 0000000..285f217
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/Makefile.in
@@ -0,0 +1,63 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+include $(srcdir)/bsrcs.mk
+CSRCS += $(BTCSRCS)
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES		+= -D_NSPR_BUILD_
+
+export:: $(TARGETS)
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/bsrcs.mk b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/bsrcs.mk
new file mode 100644
index 0000000..af01bb7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/bsrcs.mk
@@ -0,0 +1,49 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# this file lists the source files to be compiled (used in Makefile) and
+# then enumerated as object files (in objs.mk) for inclusion in the NSPR
+# shared library
+
+BTCSRCS = \
+	btthread.c \
+	btlocks.c \
+	btcvar.c \
+	btmon.c \
+	btsem.c \
+	btmisc.c \
+	$(NULL)
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btcvar.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btcvar.c
new file mode 100644
index 0000000..f615bf5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btcvar.c
@@ -0,0 +1,276 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <kernel/OS.h>
+
+#include "primpl.h"
+
+/*
+** Create a new condition variable.
+**
+** 	"lock" is the lock used to protect the condition variable.
+**
+** Condition variables are synchronization objects that threads can use
+** to wait for some condition to occur.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low. In such cases, a NULL will be returned.
+*/
+PR_IMPLEMENT(PRCondVar*)
+    PR_NewCondVar (PRLock *lock)
+{
+    PRCondVar *cv = PR_NEW( PRCondVar );
+    PR_ASSERT( NULL != lock );
+    if( NULL != cv )
+    {
+	cv->lock = lock;
+	cv->sem = create_sem(0, "CVSem");
+	cv->handshakeSem = create_sem(0, "CVHandshake");
+	cv->signalSem = create_sem( 0, "CVSignal");
+	cv->signalBenCount = 0;
+	cv->ns = cv->nw = 0;
+	PR_ASSERT( cv->sem >= B_NO_ERROR );
+	PR_ASSERT( cv->handshakeSem >= B_NO_ERROR );
+	PR_ASSERT( cv->signalSem >= B_NO_ERROR );
+    }
+    return cv;
+} /* PR_NewCondVar */
+
+/*
+** Destroy a condition variable. There must be no thread
+** waiting on the condvar. The caller is responsible for guaranteeing
+** that the condvar is no longer in use.
+**
+*/
+PR_IMPLEMENT(void)
+    PR_DestroyCondVar (PRCondVar *cvar)
+{
+    status_t result = delete_sem( cvar->sem );
+    PR_ASSERT( result == B_NO_ERROR );
+    
+    result = delete_sem( cvar->handshakeSem );
+    PR_ASSERT( result == B_NO_ERROR );
+
+    result = delete_sem( cvar->signalSem );
+    PR_ASSERT( result == B_NO_ERROR );
+
+    PR_DELETE( cvar );
+}
+
+/*
+** The thread that waits on a condition is blocked in a "waiting on
+** condition" state until another thread notifies the condition or a
+** caller specified amount of time expires. The lock associated with
+** the condition variable will be released, which must have be held
+** prior to the call to wait.
+**
+** Logically a notified thread is moved from the "waiting on condition"
+** state and made "ready." When scheduled, it will attempt to reacquire
+** the lock that it held when wait was called.
+**
+** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and
+** PR_INTERVAL_NO_WAIT. The former value requires that a condition be
+** notified (or the thread interrupted) before it will resume from the
+** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect
+** is to release the lock, possibly causing a rescheduling within the
+** runtime, then immediately attempting to reacquire the lock and resume.
+**
+** Any other value for timeout will cause the thread to be rescheduled
+** either due to explicit notification or an expired interval. The latter
+** must be determined by treating time as one part of the monitored data
+** being protected by the lock and tested explicitly for an expired
+** interval.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable or the thread was interrupted (PR_Interrupt()).
+** The particular reason can be extracted with PR_GetError().
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_WaitCondVar (PRCondVar *cvar, PRIntervalTime timeout)
+{
+    status_t err;
+    if( timeout == PR_INTERVAL_NO_WAIT ) 
+    {
+        PR_Unlock( cvar->lock );
+        PR_Lock( cvar->lock );
+        return PR_SUCCESS;
+    }
+
+    if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) 
+    {
+        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
+        {
+            atomic_add( &cvar->signalBenCount, -1 );
+            return PR_FAILURE;
+        }
+    }
+    cvar->nw += 1;
+    if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+    {
+        release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+    }
+
+    PR_Unlock( cvar->lock );
+    if( timeout==PR_INTERVAL_NO_TIMEOUT ) 
+    {
+    	err = acquire_sem(cvar->sem);
+    } 
+    else 
+    {
+    	err = acquire_sem_etc(cvar->sem, 1, B_RELATIVE_TIMEOUT, PR_IntervalToMicroseconds(timeout) );
+    }
+
+    if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) 
+    {
+        while (acquire_sem(cvar->signalSem) == B_INTERRUPTED);
+    }
+
+    if (cvar->ns > 0)
+    {
+        release_sem_etc(cvar->handshakeSem, 1, B_DO_NOT_RESCHEDULE);
+        cvar->ns -= 1;
+    }
+    cvar->nw -= 1;
+    if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+    {
+        release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+    }
+
+    PR_Lock( cvar->lock );
+    if(err!=B_NO_ERROR) 
+    {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+/*
+** Notify ONE thread that is currently waiting on 'cvar'. Which thread is
+** dependent on the implementation of the runtime. Common sense would dictate
+** that all threads waiting on a single condition have identical semantics,
+** therefore which one gets notified is not significant. 
+**
+** The calling thead must hold the lock that protects the condition, as
+** well as the invariants that are tightly bound to the condition, when
+** notify is called.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_NotifyCondVar (PRCondVar *cvar)
+{
+    status_t err ;
+    if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) 
+    {
+        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
+        {
+            atomic_add( &cvar->signalBenCount, -1 );
+            return PR_FAILURE;
+        }
+    }
+    if (cvar->nw > cvar->ns)
+    {
+        cvar->ns += 1;
+        release_sem_etc(cvar->sem, 1, B_DO_NOT_RESCHEDULE);
+        if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+        {
+            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+        }
+
+        while (acquire_sem(cvar->handshakeSem) == B_INTERRUPTED) 
+        {
+            err = B_INTERRUPTED; 
+        }
+    }
+    else
+    {
+        if( atomic_add( &cvar->signalBenCount, -1 ) > 1 )
+        {
+            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+        }
+    }
+    return PR_SUCCESS; 
+}
+
+/*
+** Notify all of the threads waiting on the condition variable. The order
+** that the threads are notified is indeterminant. The lock that protects
+** the condition must be held.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_NotifyAllCondVar (PRCondVar *cvar)
+{
+    int32 handshakes;
+    status_t err = B_OK;
+
+    if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) 
+    {
+        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
+        {
+            atomic_add( &cvar->signalBenCount, -1 );
+            return PR_FAILURE;
+        }
+    }
+
+    if (cvar->nw > cvar->ns)
+    {
+        handshakes = cvar->nw - cvar->ns;
+        cvar->ns = cvar->nw;				
+        release_sem_etc(cvar->sem, handshakes, B_DO_NOT_RESCHEDULE);	
+        if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+        {
+            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+        }
+
+        while (acquire_sem_etc(cvar->handshakeSem, handshakes, 0, 0) == B_INTERRUPTED) 
+        {
+            err = B_INTERRUPTED; 
+        }
+    }
+    else
+    {
+        if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+        {
+            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+        }
+    }
+    return PR_SUCCESS;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btlocks.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btlocks.c
new file mode 100644
index 0000000..7dd125b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btlocks.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        btlocks.c
+** Description: Implemenation for thread locks using bthreads
+** Exports:     prlock.h
+*/
+
+#include "primpl.h"
+
+#include <string.h>
+#include <sys/time.h>
+
+void
+_PR_InitLocks (void)
+{
+}
+
+PR_IMPLEMENT(PRLock*)
+    PR_NewLock (void)
+{
+    PRLock *lock;
+    status_t semresult;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    lock = PR_NEWZAP(PRLock);
+    if (lock != NULL) {
+
+	lock->benaphoreCount = 0;
+	lock->semaphoreID = create_sem( 0, "nsprLockSem" );
+	if( lock->semaphoreID < B_NO_ERROR ) {
+
+	    PR_DELETE( lock );
+	    lock = NULL;
+	}
+    }
+
+    return lock;
+}
+
+PR_IMPLEMENT(void)
+    PR_DestroyLock (PRLock* lock)
+{
+    status_t result;
+
+    PR_ASSERT(NULL != lock);
+    result = delete_sem(lock->semaphoreID);
+    PR_ASSERT(result == B_NO_ERROR);
+    PR_DELETE(lock);
+}
+
+PR_IMPLEMENT(void)
+    PR_Lock (PRLock* lock)
+{
+    PR_ASSERT(lock != NULL);
+
+    if( atomic_add( &lock->benaphoreCount, 1 ) > 0 ) {
+
+	if( acquire_sem(lock->semaphoreID ) != B_NO_ERROR ) {
+
+	    atomic_add( &lock->benaphoreCount, -1 );
+	    return;
+	}
+    }
+
+    lock->owner = find_thread( NULL );
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_Unlock (PRLock* lock)
+{
+    PR_ASSERT(lock != NULL);
+    lock->owner = NULL;
+    if( atomic_add( &lock->benaphoreCount, -1 ) > 1 ) {
+
+	release_sem_etc( lock->semaphoreID, 1, B_DO_NOT_RESCHEDULE );
+    }
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(void)
+    PR_AssertCurrentThreadOwnsLock(PRLock *lock)
+{
+    PR_ASSERT(lock != NULL);
+    PR_ASSERT(lock->owner == find_thread( NULL ));
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btmisc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btmisc.c
new file mode 100644
index 0000000..2d678a9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btmisc.c
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <stdio.h>
+
+// void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")}
+// void _MD_StartInterrupts(void) {PT_LOG("_MD_StartInterrupts")}
+
+/* this is a total hack.. */
+
+struct protoent* getprotobyname(const char* name)
+{
+    return 0;
+}
+
+struct protoent* getprotobynumber(int number)
+{
+    return 0;
+}
+
+/* this is needed by prinit for some reason */
+void
+_PR_InitStacks (void)
+{
+}
+
+/* this is needed by prinit for some reason */
+void
+_PR_InitTPD (void)
+{
+}
+
+/*
+** Create extra virtual processor threads. Generally used with MP systems.
+*/
+PR_IMPLEMENT(void)
+    PR_SetConcurrency (PRUintn numCPUs)
+{
+}
+
+/*
+** Set thread recycle mode to on (1) or off (0)
+*/
+PR_IMPLEMENT(void)
+    PR_SetThreadRecycleMode (PRUint32 flag)
+{
+}
+
+/*
+** Get context registers, return with error for now.
+*/
+
+PR_IMPLEMENT(PRWord *)
+_MD_HomeGCRegisters( PRThread *t, int isCurrent, int *np )
+{
+     return 0;
+}
+
+PR_IMPLEMENT(void *)
+PR_GetSP( PRThread *t )
+{
+    return 0;
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_EnumerateThreads( PREnumerator func, void *arg )
+{
+    return PR_FAILURE;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btmon.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btmon.c
new file mode 100644
index 0000000..be6d5a7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btmon.c
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <kernel/OS.h>
+
+#include "primpl.h"
+
+/*
+** Create a new monitor. Monitors are re-entrant locks with a single built-in
+** condition variable.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low.
+*/
+PR_IMPLEMENT(PRMonitor*)
+    PR_NewMonitor (void)
+{
+    PRMonitor *mon;
+    PRCondVar *cvar;
+    PRLock    *lock;
+
+    mon = PR_NEWZAP( PRMonitor );
+    if( mon )
+    {
+	lock = PR_NewLock();
+	if( !lock )
+        {
+	    PR_DELETE( mon );
+	    return( 0 );
+	}
+
+	cvar = PR_NewCondVar( lock );
+	if( !cvar )
+	{
+	    PR_DestroyLock( lock );
+	    PR_DELETE( mon );
+	    return( 0 );
+	}
+
+	mon->cvar = cvar;
+	mon->name = NULL;
+    }
+
+    return( mon );
+}
+
+PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name)
+{
+    PRMonitor* mon = PR_NewMonitor();
+    if( mon )
+    {
+        mon->name = name;
+    }
+    return mon;
+}
+
+/*
+** Destroy a monitor. The caller is responsible for guaranteeing that the
+** monitor is no longer in use. There must be no thread waiting on the
+** monitor's condition variable and that the lock is not held.
+**
+*/
+PR_IMPLEMENT(void)
+    PR_DestroyMonitor (PRMonitor *mon)
+{
+    PR_DestroyLock( mon->cvar->lock );
+    PR_DestroyCondVar( mon->cvar );
+    PR_DELETE( mon );
+}
+
+/*
+** Enter the lock associated with the monitor. If the calling thread currently
+** is in the monitor, the call to enter will silently succeed. In either case,
+** it will increment the entry count by one.
+*/
+PR_IMPLEMENT(void)
+    PR_EnterMonitor (PRMonitor *mon)
+{
+    if( mon->cvar->lock->owner == find_thread( NULL ) )
+    {
+	mon->entryCount++;
+
+    } else
+    {
+	PR_Lock( mon->cvar->lock );
+	mon->entryCount = 1;
+    }
+}
+
+/*
+** Decrement the entry count associated with the monitor. If the decremented
+** entry count is zero, the monitor is exited. Returns PR_FAILURE if the
+** calling thread has not entered the monitor.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_ExitMonitor (PRMonitor *mon)
+{
+    if( mon->cvar->lock->owner != find_thread( NULL ) )
+    {
+	return( PR_FAILURE );
+    }
+    if( --mon->entryCount == 0 )
+    {
+	return( PR_Unlock( mon->cvar->lock ) );
+    }
+    return( PR_SUCCESS );
+}
+
+/*
+** Wait for a notify on the monitor's condition variable. Sleep for "ticks"
+** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is
+** indefinite).
+**
+** While the thread is waiting it exits the monitor (as if it called
+** PR_ExitMonitor as many times as it had called PR_EnterMonitor).  When
+** the wait has finished the thread regains control of the monitors lock
+** with the same entry count as before the wait began.
+**
+** The thread waiting on the monitor will be resumed when the monitor is
+** notified (assuming the thread is the next in line to receive the
+** notify) or when the "ticks" timeout elapses.
+**
+** Returns PR_FAILURE if the caller has not entered the monitor.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_Wait (PRMonitor *mon, PRIntervalTime ticks)
+{
+    PRUint32 entryCount;
+    PRUintn  status;
+    PRThread *meThread;
+    thread_id me = find_thread( NULL );
+    meThread = PR_GetCurrentThread();
+
+    if( mon->cvar->lock->owner != me ) return( PR_FAILURE );
+
+    entryCount = mon->entryCount;
+    mon->entryCount = 0;
+
+    status = PR_WaitCondVar( mon->cvar, ticks );
+
+    mon->entryCount = entryCount;
+
+    return( status );
+}
+
+/*
+** Notify a thread waiting on the monitor's condition variable. If a thread
+** is waiting on the condition variable (using PR_Wait) then it is awakened
+** and attempts to reenter the monitor.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_Notify (PRMonitor *mon)
+{
+    if( mon->cvar->lock->owner != find_thread( NULL ) )
+    {
+	return( PR_FAILURE );
+    }
+
+    PR_NotifyCondVar( mon->cvar );
+    return( PR_SUCCESS );
+}
+
+/*
+** Notify all of the threads waiting on the monitor's condition variable.
+** All of threads waiting on the condition are scheduled to reenter the
+** monitor.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_NotifyAll (PRMonitor *mon)
+{
+    if( mon->cvar->lock->owner != find_thread( NULL ) )
+    {
+	return( PR_FAILURE );
+    }
+
+    PR_NotifyAllCondVar( mon->cvar );
+    return( PR_SUCCESS );
+}
+
+/*
+** Return the number of times that the current thread has entered the
+** lock. Returns zero if the current thread has not entered the lock.
+*/
+PR_IMPLEMENT(PRIntn)
+    PR_GetMonitorEntryCount(PRMonitor *mon)
+{
+    return( (mon->cvar->lock->owner == find_thread( NULL )) ?
+            mon->entryCount : 0 );
+}
+
+/*
+** If the current thread is in |mon|, this assertion is guaranteed to
+** succeed.  Otherwise, the behavior of this function is undefined.
+*/
+PR_IMPLEMENT(void)
+    PR_AssertCurrentThreadInMonitor(PRMonitor *mon)
+{
+    PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mon->cvar->lock);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btsem.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btsem.c
new file mode 100644
index 0000000..bce2814
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btsem.c
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <kernel/OS.h>
+
+#include "primpl.h"
+
+/*
+** Create a new semaphore object.
+*/
+PR_IMPLEMENT(PRSemaphore*)
+    PR_NewSem (PRUintn value)
+{
+	PRSemaphore *semaphore;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	semaphore = PR_NEWZAP(PRSemaphore);
+	if (NULL != semaphore) {
+		if ((semaphore->sem = create_sem(value, "nspr_sem")) < B_NO_ERROR)
+			return NULL;
+		else 
+			return semaphore;
+	}
+	return NULL;
+}
+
+/*
+** Destroy the given semaphore object.
+**
+*/
+PR_IMPLEMENT(void)
+    PR_DestroySem (PRSemaphore *sem)
+{
+	status_t result;
+
+	PR_ASSERT(sem != NULL);
+	result = delete_sem(sem->sem);
+	PR_ASSERT(result == B_NO_ERROR);
+	PR_DELETE(sem);
+} 
+
+/*
+** Wait on a Semaphore.
+** 
+** This routine allows a calling thread to wait or proceed depending upon
+** the state of the semahore sem. The thread can proceed only if the
+** counter value of the semaphore sem is currently greater than 0. If the
+** value of semaphore sem is positive, it is decremented by one and the
+** routine returns immediately allowing the calling thread to continue. If
+** the value of semaphore sem is 0, the calling thread blocks awaiting the
+** semaphore to be released by another thread.
+** 
+** This routine can return PR_PENDING_INTERRUPT if the waiting thread 
+** has been interrupted.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_WaitSem (PRSemaphore *sem)
+{
+	PR_ASSERT(sem != NULL);
+	if (acquire_sem(sem->sem) == B_NO_ERROR)
+		return PR_SUCCESS;
+	else
+		return PR_FAILURE;
+}
+
+/*
+** This routine increments the counter value of the semaphore. If other
+** threads are blocked for the semaphore, then the scheduler will
+** determine which ONE thread will be unblocked.
+*/
+PR_IMPLEMENT(void)
+    PR_PostSem (PRSemaphore *sem)
+{
+	status_t result;
+
+	PR_ASSERT(sem != NULL);
+	result = release_sem_etc(sem->sem, 1, B_DO_NOT_RESCHEDULE);
+	PR_ASSERT(result == B_NO_ERROR);
+}
+
+/*
+** Returns the value of the semaphore referenced by sem without affecting
+** the state of the semaphore.  The value represents the semaphore value
+** at the time of the call, but may not be the actual value when the
+** caller inspects it.
+*/
+PR_IMPLEMENT(PRUintn)
+    PR_GetValueSem (PRSemaphore *sem)
+{
+	sem_info	info;
+
+	PR_ASSERT(sem != NULL);
+	get_sem_info(sem->sem, &info);
+	return info.count;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btthread.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btthread.c
new file mode 100644
index 0000000..33bdfcc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/btthread.c
@@ -0,0 +1,694 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <kernel/OS.h>
+#include <support/TLS.h>
+
+#include "prlog.h"
+#include "primpl.h"
+#include "prcvar.h"
+#include "prpdce.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+/* values for PRThread.state */
+#define BT_THREAD_PRIMORD   0x01    /* this is the primordial thread */
+#define BT_THREAD_SYSTEM    0x02    /* this is a system thread */
+#define BT_THREAD_JOINABLE  0x04	/* this is a joinable thread */
+
+struct _BT_Bookeeping
+{
+    PRLock *ml;                 /* a lock to protect ourselves */
+	sem_id cleanUpSem;		/* the primoridal thread will block on this
+							   sem while waiting for the user threads */
+    PRInt32 threadCount;	/* user thred count */
+
+} bt_book = { NULL, B_ERROR, 0 };
+
+
+#define BT_TPD_LIMIT 128	/* number of TPD slots we'll provide (arbitrary) */
+
+/* these will be used to map an index returned by PR_NewThreadPrivateIndex()
+   to the corresponding beos native TLS slot number, and to the destructor
+   for that slot - note that, because it is allocated globally, this data
+   will be automatically zeroed for us when the program begins */
+static int32 tpd_beosTLSSlots[BT_TPD_LIMIT];
+static PRThreadPrivateDTOR tpd_dtors[BT_TPD_LIMIT];
+
+static vint32 tpd_slotsUsed=0;	/* number of currently-allocated TPD slots */
+static int32 tls_prThreadSlot;	/* TLS slot in which PRThread will be stored */
+
+/* this mutex will be used to synchronize access to every
+   PRThread.md.joinSem and PRThread.md.is_joining (we could
+   actually allocate one per thread, but that seems a bit excessive,
+   especially considering that there will probably be little
+   contention, PR_JoinThread() is allowed to block anyway, and the code
+   protected by the mutex is short/fast) */
+static PRLock *joinSemLock;
+
+static PRUint32 _bt_MapNSPRToNativePriority( PRThreadPriority priority );
+static PRThreadPriority _bt_MapNativeToNSPRPriority( PRUint32 priority );
+static void _bt_CleanupThread(void *arg);
+static PRThread *_bt_AttachThread();
+
+void
+_PR_InitThreads (PRThreadType type, PRThreadPriority priority,
+                 PRUintn maxPTDs)
+{
+    PRThread *primordialThread;
+    PRUint32  beThreadPriority;
+
+	/* allocate joinSem mutex */
+	joinSemLock = PR_NewLock();
+	if (joinSemLock == NULL)
+	{
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+		return;
+    }
+
+    /*
+    ** Create and initialize NSPR structure for our primordial thread.
+    */
+    
+    primordialThread = PR_NEWZAP(PRThread);
+    if( NULL == primordialThread )
+    {
+        PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 );
+        return;
+    }
+
+	primordialThread->md.joinSem = B_ERROR;
+
+    /*
+    ** Set the priority to the desired level.
+    */
+
+    beThreadPriority = _bt_MapNSPRToNativePriority( priority );
+    
+    set_thread_priority( find_thread( NULL ), beThreadPriority );
+    
+    primordialThread->priority = priority;
+
+
+	/* set the thread's state - note that the thread is not joinable */
+    primordialThread->state |= BT_THREAD_PRIMORD;
+	if (type == PR_SYSTEM_THREAD)
+		primordialThread->state |= BT_THREAD_SYSTEM;
+
+    /*
+    ** Allocate a TLS slot for the PRThread structure (just using
+    ** native TLS, as opposed to NSPR TPD, will make PR_GetCurrentThread()
+    ** somewhat faster, and will leave one more TPD slot for our client)
+    */
+	
+	tls_prThreadSlot = tls_allocate();
+
+    /*
+    ** Stuff our new PRThread structure into our thread specific
+    ** slot.
+    */
+
+	tls_set(tls_prThreadSlot, primordialThread);
+    
+	/* allocate lock for bt_book */
+    bt_book.ml = PR_NewLock();
+    if( NULL == bt_book.ml )
+    {
+    	PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 );
+	return;
+    }
+}
+
+PRUint32
+_bt_MapNSPRToNativePriority( PRThreadPriority priority )
+    {
+    switch( priority )
+    {
+    	case PR_PRIORITY_LOW:	 return( B_LOW_PRIORITY );
+	case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY );
+	case PR_PRIORITY_HIGH:	 return( B_DISPLAY_PRIORITY );
+	case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY );
+	default:		 return( B_NORMAL_PRIORITY );
+    }
+}
+
+PRThreadPriority
+_bt_MapNativeToNSPRPriority(PRUint32 priority)
+    {
+	if (priority < B_NORMAL_PRIORITY)
+		return PR_PRIORITY_LOW;
+	if (priority < B_DISPLAY_PRIORITY)
+		return PR_PRIORITY_NORMAL;
+	if (priority < B_URGENT_DISPLAY_PRIORITY)
+		return PR_PRIORITY_HIGH;
+	return PR_PRIORITY_URGENT;
+}
+
+PRUint32
+_bt_mapNativeToNSPRPriority( int32 priority )
+{
+    switch( priority )
+    {
+    	case PR_PRIORITY_LOW:	 return( B_LOW_PRIORITY );
+	case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY );
+	case PR_PRIORITY_HIGH:	 return( B_DISPLAY_PRIORITY );
+	case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY );
+	default:		 return( B_NORMAL_PRIORITY );
+    }
+}
+
+/* This method is called by all NSPR threads as they exit */
+void _bt_CleanupThread(void *arg)
+{
+	PRThread *me = PR_GetCurrentThread();
+	int32 i;
+
+	/* first, clean up all thread-private data */
+	for (i = 0; i < tpd_slotsUsed; i++)
+	{
+		void *oldValue = tls_get(tpd_beosTLSSlots[i]);
+		if ( oldValue != NULL && tpd_dtors[i] != NULL )
+			(*tpd_dtors[i])(oldValue);
+	}
+
+	/* if this thread is joinable, wait for someone to join it */
+	if (me->state & BT_THREAD_JOINABLE)
+	{
+		/* protect access to our joinSem */
+		PR_Lock(joinSemLock);
+
+		if (me->md.is_joining)
+		{
+			/* someone is already waiting to join us (they've
+			   allocated a joinSem for us) - let them know we're
+			   ready */
+			delete_sem(me->md.joinSem);
+
+			PR_Unlock(joinSemLock);
+
+		}
+		else
+    {
+			/* noone is currently waiting for our demise - it
+			   is our responsibility to allocate the joinSem
+			   and block on it */
+			me->md.joinSem = create_sem(0, "join sem");
+
+			/* we're done accessing our joinSem */
+			PR_Unlock(joinSemLock);
+
+			/* wait for someone to join us */
+			while (acquire_sem(me->md.joinSem) == B_INTERRUPTED);
+	    }
+	}
+
+	/* if this is a user thread, we must update our books */
+	if ((me->state & BT_THREAD_SYSTEM) == 0)
+	{
+		/* synchronize access to bt_book */
+    PR_Lock( bt_book.ml );
+
+		/* decrement the number of currently-alive user threads */
+	bt_book.threadCount--;
+
+		if (bt_book.threadCount == 0 && bt_book.cleanUpSem != B_ERROR) {
+			/* we are the last user thread, and the primordial thread is
+			   blocked in PR_Cleanup() waiting for us to finish - notify
+			   it */
+			delete_sem(bt_book.cleanUpSem);
+	}
+
+    PR_Unlock( bt_book.ml );
+	}
+
+	/* finally, delete this thread's PRThread */
+	PR_DELETE(me);
+}
+
+/**
+ * This is a wrapper that all threads invoke that allows us to set some
+ * things up prior to a thread's invocation and clean up after a thread has
+ * exited.
+ */
+static void*
+_bt_root (void* arg)
+	{
+    PRThread *thred = (PRThread*)arg;
+    PRIntn rv;
+    void *privData;
+    status_t result;
+    int i;
+
+	/* save our PRThread object into our TLS */
+	tls_set(tls_prThreadSlot, thred);
+
+    thred->startFunc(thred->arg);  /* run the dang thing */
+
+	/* clean up */
+	_bt_CleanupThread(NULL);
+
+	return 0;
+}
+
+PR_IMPLEMENT(PRThread*)
+    PR_CreateThread (PRThreadType type, void (*start)(void* arg), void* arg,
+                     PRThreadPriority priority, PRThreadScope scope,
+                     PRThreadState state, PRUint32 stackSize)
+{
+    PRUint32 bePriority;
+
+    PRThread* thred;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	thred = PR_NEWZAP(PRThread);
+ 	if (thred == NULL)
+	{
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    thred->md.joinSem = B_ERROR;
+
+        thred->arg = arg;
+        thred->startFunc = start;
+        thred->priority = priority;
+
+	if( state == PR_JOINABLE_THREAD )
+	{
+	    thred->state |= BT_THREAD_JOINABLE;
+	}
+
+        /* keep some books */
+
+	PR_Lock( bt_book.ml );
+
+	if (type == PR_USER_THREAD)
+	{
+	    bt_book.threadCount++;
+        }
+
+	PR_Unlock( bt_book.ml );
+
+	bePriority = _bt_MapNSPRToNativePriority( priority );
+
+        thred->md.tid = spawn_thread((thread_func)_bt_root, "moz-thread",
+                                     bePriority, thred);
+        if (thred->md.tid < B_OK) {
+            PR_SetError(PR_UNKNOWN_ERROR, thred->md.tid);
+            PR_DELETE(thred);
+			return NULL;
+        }
+
+        if (resume_thread(thred->md.tid) < B_OK) {
+            PR_SetError(PR_UNKNOWN_ERROR, 0);
+            PR_DELETE(thred);
+			return NULL;
+        }
+
+    return thred;
+    }
+
+PR_IMPLEMENT(PRThread*)
+	PR_AttachThread(PRThreadType type, PRThreadPriority priority,
+					PRThreadStack *stack)
+{
+	/* PR_GetCurrentThread() will attach a thread if necessary */
+	return PR_GetCurrentThread();
+}
+
+PR_IMPLEMENT(void)
+	PR_DetachThread()
+{
+	/* we don't support detaching */
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_JoinThread (PRThread* thred)
+{
+    status_t eval, status;
+
+    PR_ASSERT(thred != NULL);
+
+	if ((thred->state & BT_THREAD_JOINABLE) == 0)
+    {
+	PR_SetError( PR_INVALID_ARGUMENT_ERROR, 0 );
+	return( PR_FAILURE );
+    }
+
+	/* synchronize access to the thread's joinSem */
+	PR_Lock(joinSemLock);
+	
+	if (thred->md.is_joining)
+	{
+		/* another thread is already waiting to join the specified
+		   thread - we must fail */
+		PR_Unlock(joinSemLock);
+		return PR_FAILURE;
+	}
+
+	/* let others know we are waiting to join */
+	thred->md.is_joining = PR_TRUE;
+
+	if (thred->md.joinSem == B_ERROR)
+	{
+		/* the thread hasn't finished yet - it is our responsibility to
+		   allocate a joinSem and wait on it */
+		thred->md.joinSem = create_sem(0, "join sem");
+
+		/* we're done changing the joinSem now */
+		PR_Unlock(joinSemLock);
+
+		/* wait for the thread to finish */
+		while (acquire_sem(thred->md.joinSem) == B_INTERRUPTED);
+
+	}
+	else
+	{
+		/* the thread has already finished, and has allocated the
+		   joinSem itself - let it know it can finally die */
+		delete_sem(thred->md.joinSem);
+		
+		PR_Unlock(joinSemLock);
+    }
+
+	/* make sure the thread is dead */
+    wait_for_thread(thred->md.tid, &eval);
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRThread*)
+    PR_GetCurrentThread ()
+{
+    PRThread* thred;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    thred = (PRThread *)tls_get( tls_prThreadSlot);
+	if (thred == NULL)
+	{
+		/* this thread doesn't have a PRThread structure (it must be
+		   a native thread not created by the NSPR) - assimilate it */
+		thred = _bt_AttachThread();
+	}
+    PR_ASSERT(NULL != thred);
+
+    return thred;
+}
+
+PR_IMPLEMENT(PRThreadScope)
+    PR_GetThreadScope (const PRThread* thred)
+{
+    PR_ASSERT(thred != NULL);
+    return PR_GLOBAL_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadType)
+    PR_GetThreadType (const PRThread* thred)
+{
+    PR_ASSERT(thred != NULL);
+    return (thred->state & BT_THREAD_SYSTEM) ?
+        PR_SYSTEM_THREAD : PR_USER_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadState)
+    PR_GetThreadState (const PRThread* thred)
+{
+    PR_ASSERT(thred != NULL);
+    return (thred->state & BT_THREAD_JOINABLE)?
+    					PR_JOINABLE_THREAD: PR_UNJOINABLE_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadPriority)
+    PR_GetThreadPriority (const PRThread* thred)
+{
+    PR_ASSERT(thred != NULL);
+    return thred->priority;
+}  /* PR_GetThreadPriority */
+
+PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred,
+                                        PRThreadPriority newPri)
+{
+    PRUint32 bePriority;
+
+    PR_ASSERT( thred != NULL );
+
+    thred->priority = newPri;
+    bePriority = _bt_MapNSPRToNativePriority( newPri );
+    set_thread_priority( thred->md.tid, bePriority );
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_NewThreadPrivateIndex (PRUintn* newIndex,
+                              PRThreadPrivateDTOR destructor)
+{
+	int32    index;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	/* reserve the next available tpd slot */
+	index = atomic_add( &tpd_slotsUsed, 1 );
+	if (index >= BT_TPD_LIMIT)
+	{
+		/* no slots left - decrement value, then fail */
+		atomic_add( &tpd_slotsUsed, -1 );
+		PR_SetError( PR_TPD_RANGE_ERROR, 0 );
+	    return( PR_FAILURE );
+	}
+
+	/* allocate a beos-native TLS slot for this index (the new slot
+	   automatically contains NULL) */
+	tpd_beosTLSSlots[index] = tls_allocate();
+
+	/* remember the destructor */
+	tpd_dtors[index] = destructor;
+
+    *newIndex = (PRUintn)index;
+
+    return( PR_SUCCESS );
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_SetThreadPrivate (PRUintn index, void* priv)
+{
+	void *oldValue;
+
+    /*
+    ** Sanity checking
+    */
+
+    if(index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT)
+    {
+		PR_SetError( PR_TPD_RANGE_ERROR, 0 );
+	return( PR_FAILURE );
+    }
+
+	/* if the old value isn't NULL, and the dtor for this slot isn't
+	   NULL, we must destroy the data */
+	oldValue = tls_get(tpd_beosTLSSlots[index]);
+	if (oldValue != NULL && tpd_dtors[index] != NULL)
+		(*tpd_dtors[index])(oldValue);
+
+	/* save new value */
+	tls_set(tpd_beosTLSSlots[index], priv);
+
+	    return( PR_SUCCESS );
+	}
+
+PR_IMPLEMENT(void*)
+    PR_GetThreadPrivate (PRUintn index)
+{
+	/* make sure the index is valid */
+	if (index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT)
+    {   
+		PR_SetError( PR_TPD_RANGE_ERROR, 0 );
+		return NULL;
+    }
+
+	/* return the value */
+	return tls_get( tpd_beosTLSSlots[index] );
+	}
+
+
+PR_IMPLEMENT(PRStatus)
+    PR_Interrupt (PRThread* thred)
+{
+    PRIntn rv;
+
+    PR_ASSERT(thred != NULL);
+
+    /*
+    ** there seems to be a bug in beos R5 in which calling
+    ** resume_thread() on a blocked thread returns B_OK instead
+    ** of B_BAD_THREAD_STATE (beos bug #20000422-19095).  as such,
+    ** to interrupt a thread, we will simply suspend then resume it
+    ** (no longer call resume_thread(), check for B_BAD_THREAD_STATE,
+    ** the suspend/resume to wake up a blocked thread).  this wakes
+    ** up blocked threads properly, and doesn't hurt unblocked threads
+    ** (they simply get stopped then re-started immediately)
+    */
+
+    rv = suspend_thread( thred->md.tid );
+    if( rv != B_NO_ERROR )
+    {
+        /* this doesn't appear to be a valid thread_id */
+        PR_SetError( PR_UNKNOWN_ERROR, rv );
+        return PR_FAILURE;
+    }
+
+    rv = resume_thread( thred->md.tid );
+    if( rv != B_NO_ERROR )
+    {
+        PR_SetError( PR_UNKNOWN_ERROR, rv );
+        return PR_FAILURE;
+    }
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(void)
+    PR_ClearInterrupt ()
+{
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_Yield ()
+{
+    /* we just sleep for long enough to cause a reschedule (100
+       microseconds) */
+    snooze(100);
+}
+
+#define BT_MILLION 1000000UL
+
+PR_IMPLEMENT(PRStatus)
+    PR_Sleep (PRIntervalTime ticks)
+{
+    bigtime_t tps;
+    status_t status;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    tps = PR_IntervalToMicroseconds( ticks );
+
+    status = snooze(tps);
+    if (status == B_NO_ERROR) return PR_SUCCESS;
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, status);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_Cleanup ()
+{
+    PRThread *me = PR_GetCurrentThread();
+
+    PR_ASSERT(me->state & BT_THREAD_PRIMORD);
+    if ((me->state & BT_THREAD_PRIMORD) == 0) {
+        return PR_FAILURE;
+    }
+
+    PR_Lock( bt_book.ml );
+
+	if (bt_book.threadCount != 0)
+    {
+		/* we'll have to wait for some threads to finish - create a
+		   sem to block on */
+		bt_book.cleanUpSem = create_sem(0, "cleanup sem");
+    }
+
+    PR_Unlock( bt_book.ml );
+
+	/* note that, if all the user threads were already dead, we
+	   wouldn't have created a sem above, so this acquire_sem()
+	   will fail immediately */
+	while (acquire_sem(bt_book.cleanUpSem) == B_INTERRUPTED);
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(void)
+    PR_ProcessExit (PRIntn status)
+{
+    exit(status);
+}
+
+PRThread *_bt_AttachThread()
+{
+	PRThread *thread;
+	thread_info tInfo;
+
+	/* make sure this thread doesn't already have a PRThread structure */
+	PR_ASSERT(tls_get(tls_prThreadSlot) == NULL);
+
+	/* allocate a PRThread structure for this thread */
+	thread = PR_NEWZAP(PRThread);
+	if (thread == NULL)
+	{
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+		return NULL;
+	}
+
+	/* get the native thread's current state */
+	get_thread_info(find_thread(NULL), &tInfo);
+
+	/* initialize new PRThread */
+	thread->md.tid = tInfo.thread;
+	thread->md.joinSem = B_ERROR;
+	thread->priority = _bt_MapNativeToNSPRPriority(tInfo.priority);
+
+	/* attached threads are always non-joinable user threads */
+	thread->state = 0;
+
+	/* increment user thread count */
+	PR_Lock(bt_book.ml);
+	bt_book.threadCount++;
+	PR_Unlock(bt_book.ml);
+
+	/* store this thread's PRThread */
+	tls_set(tls_prThreadSlot, thread);
+	
+	/* the thread must call _bt_CleanupThread() before it dies, in order
+	   to clean up its PRThread, synchronize with the primordial thread,
+	   etc. */
+	on_exit_thread(_bt_CleanupThread, NULL);
+	
+	return thread;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/objs.mk b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/objs.mk
new file mode 100644
index 0000000..60455a3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/bthreads/objs.mk
@@ -0,0 +1,43 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This makefile appends to the variable OBJS the bthread object modules
+# that will be part of the nspr20 library.
+
+include $(srcdir)/bthreads/bsrcs.mk
+
+OBJS += $(BTCSRCS:%.c=bthreads/$(OBJDIR)/%.$(OBJ_SUFFIX))
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/Makefile.in
new file mode 100644
index 0000000..46e62e7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/Makefile.in
@@ -0,0 +1,75 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+CXXSRCS =           \
+	rcbase.cpp      \
+	rccv.cpp		\
+	rcfileio.cpp    \
+	rcinrval.cpp	\
+	rcio.cpp	    \
+	rclock.cpp	    \
+	rcnetdb.cpp	    \
+	rcnetio.cpp	    \
+	rcthread.cpp	\
+	rctime.cpp      \
+	$(NULL)
+
+OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX)))
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir)
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcascii.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcascii.h
new file mode 100644
index 0000000..8476fc4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcascii.h
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Class definitions to format ASCII data.
+*/
+
+#if defined(_RCASCII_H)
+#else
+#define _RCASCII_H
+
+/*
+** RCFormatStuff
+**  This class maintains no state - that is the responsibility of
+**  the class' client. For each call to Sx_printf(), the StuffFunction
+**  will be called for each embedded "%" in the 'fmt' string and once
+**  for each interveaning literal.
+*/
+class PR_IMPLEMENT(RCFormatStuff)
+{
+public:
+    RCFormatStuff();
+    virtual ~RCFormatStuff();
+
+    /*
+    ** Process the arbitrary argument list using as indicated by
+    ** the 'fmt' string. Each segment of the processing the stuff
+    ** function is called with the relavent translation.
+    */
+    virtual PRInt32 Sx_printf(void *state, const char *fmt, ...);
+
+    /*
+    ** The 'state' argument is not processed by the runtime. It
+    ** is merely passed from the Sx_printf() call. It is intended
+    ** to be used by the client to figure out what to do with the
+    ** new string.
+    **
+    ** The new string ('stuff') is ASCII translation driven by the
+    ** Sx_printf()'s 'fmt' string. It is not guaranteed to be a null
+    ** terminated string.
+    **
+    ** The return value is the number of bytes copied from the 'stuff'
+    ** string. It is accumulated for each of the calls to the stuff
+    ** function and returned from the original caller of Sx_printf().
+    */
+    virtual PRSize StuffFunction(
+        void *state, const char *stuff, PRSize stufflen) = 0;
+};  /* RCFormatStuff */
+
+
+/*
+** RCFormatBuffer
+**  The caller is supplying the buffer, the runtime is doing all
+**  the conversion. The object contains no state, so is reusable
+**  and reentrant.
+*/
+class PR_IMPLEMENT(RCFormatBuffer): public RCFormatStuff
+{
+public:
+    RCFormatBuffer();
+    virtual ~RCFormatBuffer();
+
+    /*
+    ** Format the trailing arguments as indicated by the 'fmt'
+    ** string. Put the result in 'buffer'. Return the number
+    ** of bytes moved into 'buffer'. 'buffer' will always be
+    ** a properly terminated string even if the convresion fails.
+    */
+    virtual PRSize Sn_printf(
+        char *buffer, PRSize length, const char *fmt, ...);
+
+    virtual char *Sm_append(char *buffer, const char *fmt, ...);
+
+private:
+    /*
+    ** This class overrides the stuff function, does not preserve
+    ** its virtual-ness and no longer allows the clients to call
+    ** it in the clear. In other words, it is now the implementation
+    ** for this class.
+    */
+    PRSize StuffFunction(void*, const char*, PRSize);
+        
+};  /* RCFormatBuffer */
+
+/*
+** RCFormat
+**  The runtime is supplying the buffer. The object has state - the
+**  buffer. Each operation must run to completion before the object
+**  can be reused. When it is, the buffer is reset (whatever that
+**  means). The result of a conversion is available via the extractor.
+**  After extracted, the memory still belongs to the class - if the
+**  caller wants to retain or modify, it must first be copied.
+*/
+class PR_IMPLEMENT(RCFormat): pubic RCFormatBuffer
+{
+public:
+    RCFormat();
+    virtual ~RCFormat();
+
+    /*
+    ** Translate the trailing arguments according to the 'fmt'
+    ** string and store the results in the object.
+    */
+    virtual PRSize Sm_printf(const char *fmt, ...);
+
+    /*
+    ** Extract the latest translation.
+    ** The object does not surrender the memory occupied by
+    ** the string. If the caller wishes to modify the data,
+    ** it must first be copied.
+    */
+    const char*();
+
+private:
+    char *buffer;
+
+    RCFormat(const RCFormat&);
+    RCFormat& operator=(const RCFormat&);
+}; /* RCFormat */
+
+/*
+** RCPrint
+**  The output is formatted and then written to an associated file
+**  descriptor. The client can provide a suitable file descriptor
+**  or can indicate that the output should be directed to one of
+**  the well-known "console" devices.
+*/
+class PR_IMPLEMENT(RCPrint): public RCFormat
+{
+    virtual ~RCPrint();
+    RCPrint(RCIO* output);
+    RCPrint(RCFileIO::SpecialFile output);
+
+    virtual PRSize Printf(const char *fmt, ...);
+private:
+    RCPrint();
+};  /* RCPrint */
+
+#endif /* defined(_RCASCII_H) */
+
+/* RCAscii.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcbase.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcbase.cpp
new file mode 100644
index 0000000..84662d9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcbase.cpp
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** RCBase.cpp - Mixin class for NSPR C++ wrappers
+*/
+
+#include "rcbase.h"
+
+RCBase::~RCBase() { }
+
+PRSize RCBase::GetErrorTextLength() { return PR_GetErrorTextLength(); }
+PRSize RCBase::CopyErrorText(char *text) { return PR_GetErrorText(text); }
+
+void RCBase::SetError(PRErrorCode error, PRInt32 oserror)
+    { PR_SetError(error, oserror); }
+
+void RCBase::SetErrorText(PRSize text_length, const char *text)
+    { PR_SetErrorText(text_length, text); }
+
+/* rcbase.cpp */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcbase.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcbase.h
new file mode 100644
index 0000000..0910a15
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcbase.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** RCBase.h - Mixin class for NSPR C++ wrappers
+*/
+
+#if defined(_RCRUNTIME_H)
+#else
+#define _RCRUNTIME_H
+
+#include <prerror.h>
+
+/*
+** Class: RCBase (mixin)
+**
+** Generally mixed into every base class. The functions in this class are all
+** static. Therefore this entire class is just syntatic sugar. It gives the
+** illusion that errors (in particular) are retrieved via the same object
+** that just reported a failure. It also (unfortunately) might lead one to
+** believe that the errors are persistent in that object. They're not.
+*/
+
+class PR_IMPLEMENT(RCBase)
+{
+public:
+    virtual ~RCBase();
+
+    static void AbortSelf();
+
+    static PRErrorCode GetError();
+    static PRInt32 GetOSError();
+
+    static PRSize GetErrorTextLength();
+    static PRSize CopyErrorText(char *text);
+
+    static void SetError(PRErrorCode error, PRInt32 oserror);
+    static void SetErrorText(PRSize textLength, const char *text);
+
+protected:
+    RCBase() { }
+};  /* RCObject */
+
+inline PRErrorCode RCBase::GetError() { return PR_GetError(); }
+inline PRInt32 RCBase::GetOSError() { return PR_GetOSError(); }
+
+#endif  /* defined(_RCRUNTIME_H) */
+
+/* rcbase.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rccv.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rccv.cpp
new file mode 100644
index 0000000..5e03ae7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rccv.cpp
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** RCCondition - C++ wrapper around NSPR's PRCondVar
+*/
+
+#include "rccv.h"
+
+#include <prlog.h>
+#include <prerror.h>
+#include <prcvar.h>
+
+RCCondition::RCCondition(class RCLock *lock): RCBase()
+{
+    cv = PR_NewCondVar(lock->lock);
+    PR_ASSERT(NULL != cv);
+    timeout = PR_INTERVAL_NO_TIMEOUT;
+}  /* RCCondition::RCCondition */
+
+RCCondition::~RCCondition()
+{
+    if (NULL != cv) PR_DestroyCondVar(cv);
+}  /* RCCondition::~RCCondition */
+
+PRStatus RCCondition::Wait()
+{
+    PRStatus rv;
+    PR_ASSERT(NULL != cv);
+    if (NULL == cv)
+    {
+        SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        rv = PR_FAILURE;
+    }
+    else
+        rv = PR_WaitCondVar(cv, timeout.interval);
+    return rv;
+}  /* RCCondition::Wait */
+
+PRStatus RCCondition::Notify()
+{
+    return PR_NotifyCondVar(cv);
+}  /* RCCondition::Notify */
+
+PRStatus RCCondition::Broadcast()
+{
+    return PR_NotifyAllCondVar(cv);
+}  /* RCCondition::Broadcast */
+
+PRStatus RCCondition::SetTimeout(const RCInterval& tmo)
+{
+    if (NULL == cv)
+    {
+        SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    timeout = tmo;
+    return PR_SUCCESS;
+}  /* RCCondition::SetTimeout */
+
+RCInterval RCCondition::GetTimeout() const { return timeout; }
+
+/* rccv.cpp */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rccv.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rccv.h
new file mode 100644
index 0000000..56923af
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rccv.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** RCCondition - C++ wrapper around NSPR's PRCondVar
+**
+** Conditions have a notion of timeouts. A thread that waits on a condition
+** will resume execution when the condition is notified OR when a specified
+** interval of time has expired.
+**
+** Most applications don't adjust the timeouts on conditions. The literature
+** would argue that all threads waiting on a single condition must have the
+** same semantics. But if an application wishes to modify the timeout with
+** (perhaps) each wait call, that modification should be done consistantly
+** and under protection of the condition's associated lock.
+**
+** The default timeout is infinity.
+*/
+
+#if defined(_RCCOND_H)
+#else
+#define _RCCOND_H
+
+#include "rclock.h"
+#include "rcbase.h"
+#include "rcinrval.h"
+
+struct PRCondVar;
+
+class PR_IMPLEMENT(RCCondition): public RCBase
+{
+public:
+    RCCondition(RCLock*);           /* associates CV with a lock and infinite tmo */
+    virtual ~RCCondition();
+
+    virtual PRStatus Wait();        /* applies object's current timeout */
+
+    virtual PRStatus Notify();      /* perhaps ready one thread */
+    virtual PRStatus Broadcast();   /* perhaps ready many threads */
+
+    virtual PRStatus SetTimeout(const RCInterval&);
+                                    /* set object's current timeout value */
+
+private:
+    PRCondVar *cv;
+    RCInterval timeout;
+
+    RCCondition();
+    RCCondition(const RCCondition&);
+    void operator=(const RCCondition&);
+
+public:
+    RCInterval GetTimeout() const;
+};  /* RCCondition */
+
+inline RCCondition::RCCondition(): RCBase() { }
+inline RCCondition::RCCondition(const RCCondition&): RCBase() { }
+inline void RCCondition::operator=(const RCCondition&) { }
+
+#endif /* defined(_RCCOND_H) */
+
+/* RCCond.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcfileio.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcfileio.cpp
new file mode 100644
index 0000000..7646c89
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcfileio.cpp
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Class implementation for normal and special file I/O (ref: prio.h)
+*/
+
+#include "rcfileio.h"
+
+#include <string.h>
+
+RCFileIO::RCFileIO(): RCIO(RCIO::file) { }
+
+RCFileIO::~RCFileIO() { if (NULL != fd) (void)Close(); }
+
+PRInt64 RCFileIO::Available()
+    { return fd->methods->available(fd); }
+
+PRStatus RCFileIO::Close()
+    { PRStatus rv = fd->methods->close(fd); fd = NULL; return rv; }
+
+PRStatus RCFileIO::Delete(const char* filename) { return PR_Delete(filename); }
+
+PRStatus RCFileIO::FileInfo(RCFileInfo* info) const
+    { return fd->methods->fileInfo64(fd, &info->info); }
+
+PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo* info)
+    { return PR_GetFileInfo64(name, &info->info); }
+
+PRStatus RCFileIO::Fsync()
+    { return fd->methods->fsync(fd); }
+
+PRStatus RCFileIO::Open(const char *filename, PRIntn flags, PRIntn mode)
+{
+    fd = PR_Open(filename, flags, mode);
+    return (NULL == fd) ? PR_FAILURE : PR_SUCCESS;
+}  /* RCFileIO::Open */
+
+PRInt32 RCFileIO::Read(void *buf, PRSize amount)
+    { return fd->methods->read(fd, buf, amount); }
+
+PRInt64 RCFileIO::Seek(PRInt64 offset, RCIO::Whence how)
+{
+    PRSeekWhence whence;
+    switch (how)
+    {
+        case RCFileIO::set: whence = PR_SEEK_SET; break;
+        case RCFileIO::current: whence = PR_SEEK_CUR; break;
+        case RCFileIO::end: whence = PR_SEEK_END; break;
+        default: whence = (PRSeekWhence)-1;
+    }
+    return fd->methods->seek64(fd, offset, whence);
+}  /* RCFileIO::Seek */
+
+PRInt32 RCFileIO::Write(const void *buf, PRSize amount)
+    { return fd->methods->write(fd, buf, amount); }
+
+PRInt32 RCFileIO::Writev(
+    const PRIOVec *iov, PRSize size, const RCInterval& timeout)
+    { return fd->methods->writev(fd, iov, size, timeout); }
+
+RCIO *RCFileIO::GetSpecialFile(RCFileIO::SpecialFile special)
+{
+    PRFileDesc* fd;
+    PRSpecialFD which;
+    RCFileIO* spec = NULL;
+
+    switch (special)
+    {
+        case RCFileIO::input: which = PR_StandardInput; break;
+        case RCFileIO::output: which = PR_StandardOutput; break;
+        case RCFileIO::error: which = PR_StandardError; break;
+        default: which = (PRSpecialFD)-1;
+    }
+    fd = PR_GetSpecialFD(which);
+    if (NULL != fd)
+    {
+        spec = new RCFileIO();
+        if (NULL != spec) spec->fd = fd;
+    }
+    return spec;
+}  /* RCFileIO::GetSpecialFile */
+
+
+/*
+** The following methods have been made non-virtual and private. These
+** default implementations are intended to NEVER be called. They
+** are not valid for this type of I/O class (normal and special file).
+*/
+PRStatus RCFileIO::Connect(const RCNetAddr&, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::GetLocalName(RCNetAddr*) const
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::GetPeerName(RCNetAddr*) const
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::GetSocketOption(PRSocketOptionData*) const
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::Listen(PRIntn)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRInt16 RCFileIO::Poll(PRInt16, PRInt16*)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return 0; }
+
+PRInt32 RCFileIO::Recv(void*, PRSize, PRIntn, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+PRInt32 RCFileIO::Recvfrom(void*, PRSize, PRIntn, RCNetAddr*, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+PRInt32 RCFileIO::Send(
+    const void*, PRSize, PRIntn, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+PRInt32 RCFileIO::Sendto(
+    const void*, PRSize, PRIntn, const RCNetAddr&, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+RCIO* RCFileIO::Accept(RCNetAddr*, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return NULL; }
+
+PRStatus RCFileIO::Bind(const RCNetAddr&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRInt32 RCFileIO::AcceptRead(
+    RCIO**, RCNetAddr**, void*, PRSize, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+PRStatus RCFileIO::SetSocketOption(const PRSocketOptionData*)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::Shutdown(RCIO::ShutdownHow)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRInt32 RCFileIO::TransmitFile(
+    RCIO*, const void*, PRSize, RCIO::FileDisposition, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+/*
+** Class implementation for file information object (ref: prio.h)
+*/
+
+RCFileInfo::~RCFileInfo() { }
+
+RCFileInfo::RCFileInfo(const RCFileInfo& her): RCBase()
+    { info = her.info; }  /* RCFileInfo::RCFileInfo */
+
+RCTime RCFileInfo::CreationTime() const { return RCTime(info.creationTime); }
+
+RCTime RCFileInfo::ModifyTime() const { return RCTime(info.modifyTime); }
+
+RCFileInfo::FileType RCFileInfo::Type() const
+{
+    RCFileInfo::FileType type;
+    switch (info.type)
+    {
+        case PR_FILE_FILE: type = RCFileInfo::file; break;
+        case PR_FILE_DIRECTORY: type = RCFileInfo::directory; break;
+        default: type = RCFileInfo::other;
+    }
+    return type;
+}  /* RCFileInfo::Type */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcfileio.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcfileio.h
new file mode 100644
index 0000000..576b37d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcfileio.h
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Class definitions for normal and special file I/O (ref: prio.h)
+*/
+
+#if defined(_RCFILEIO_H)
+#else
+#define _RCFILEIO_H
+
+#include "rcio.h"
+#include "rctime.h"
+
+/*
+** One would normally create a concrete class, such as RCFileIO, but then
+** pass around more generic references, ie., RCIO.
+**
+** This subclass of RCIO hides (makes private) the methods that are not
+** applicable to normal files.
+*/
+
+class RCFileInfo;
+
+class PR_IMPLEMENT(RCFileIO): public RCIO
+{
+public:
+    RCFileIO();
+    virtual ~RCFileIO();
+
+    virtual PRInt64     Available();
+    virtual PRStatus    Close();
+    static  PRStatus    Delete(const char *name);
+    virtual PRStatus    FileInfo(RCFileInfo* info) const;
+    static  PRStatus    FileInfo(const char *name, RCFileInfo* info);
+    virtual PRStatus    Fsync();
+    virtual PRStatus    Open(const char *name, PRIntn flags, PRIntn mode);
+    virtual PRInt32     Read(void *buf, PRSize amount);
+    virtual PRInt64     Seek(PRInt64 offset, RCIO::Whence how);
+    virtual PRInt32     Write(const void *buf, PRSize amount);
+    virtual PRInt32     Writev(
+                            const PRIOVec *iov, PRSize size,
+                            const RCInterval& timeout);
+
+private:
+
+    /* These methods made private are unavailable for this object */
+    RCFileIO(const RCFileIO&);
+    void operator=(const RCFileIO&);
+
+    RCIO*       Accept(RCNetAddr* addr, const RCInterval& timeout);
+    PRInt32     AcceptRead(
+                    RCIO **newfd, RCNetAddr **address, void *buffer,
+                    PRSize amount, const RCInterval& timeout);
+    PRStatus    Bind(const RCNetAddr& addr);
+    PRStatus    Connect(const RCNetAddr& addr, const RCInterval& timeout);
+    PRStatus    GetLocalName(RCNetAddr *addr) const;
+    PRStatus    GetPeerName(RCNetAddr *addr) const;
+    PRStatus    GetSocketOption(PRSocketOptionData *data) const;
+    PRStatus    Listen(PRIntn backlog);
+    PRInt16     Poll(PRInt16 in_flags, PRInt16 *out_flags);
+    PRInt32     Recv(
+                    void *buf, PRSize amount, PRIntn flags,
+                    const RCInterval& timeout);
+    PRInt32     Recvfrom(
+                    void *buf, PRSize amount, PRIntn flags,
+                    RCNetAddr* addr, const RCInterval& timeout);
+    PRInt32     Send(
+                    const void *buf, PRSize amount, PRIntn flags,
+                    const RCInterval& timeout);
+    PRInt32     Sendto(
+                    const void *buf, PRSize amount, PRIntn flags,
+                    const RCNetAddr& addr,
+                    const RCInterval& timeout);
+    PRStatus    SetSocketOption(const PRSocketOptionData *data);
+    PRStatus    Shutdown(RCIO::ShutdownHow how);
+    PRInt32     TransmitFile(
+                    RCIO *source, const void *headers,
+                    PRSize hlen, RCIO::FileDisposition flags,
+                    const RCInterval& timeout);
+public:
+
+    /*
+    ** The following function return a valid normal file object,
+    ** Such objects can be used for scanned input and console output.
+    */
+    typedef enum {
+        input = PR_StandardInput,
+        output = PR_StandardOutput,
+        error = PR_StandardError
+    } SpecialFile;
+
+    static RCIO *GetSpecialFile(RCFileIO::SpecialFile special);
+
+};  /* RCFileIO */
+
+class PR_IMPLEMENT(RCFileInfo): public RCBase
+{
+public:
+    typedef enum {
+        file = PR_FILE_FILE,
+        directory = PR_FILE_DIRECTORY,
+        other = PR_FILE_OTHER
+    } FileType;
+
+public:
+    RCFileInfo();
+    RCFileInfo(const RCFileInfo&);
+
+    virtual ~RCFileInfo();
+
+    PRInt64 Size() const;
+    RCTime CreationTime() const;
+    RCTime ModifyTime() const;
+    RCFileInfo::FileType Type() const;
+
+friend PRStatus RCFileIO::FileInfo(RCFileInfo*) const;
+friend PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo*);
+
+private:
+    PRFileInfo64 info;
+};  /* RCFileInfo */
+
+inline RCFileInfo::RCFileInfo(): RCBase() { }
+inline PRInt64 RCFileInfo::Size() const { return info.size; }
+
+#endif /* defined(_RCFILEIO_H) */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcinrval.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcinrval.cpp
new file mode 100644
index 0000000..ff075a3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcinrval.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** C++ interval times (ref: prinrval.h)
+**
+**  An interval is a period of time. The start of the interval (epoch)
+**  must be defined by the application. The unit of time of an interval
+**  is platform dependent, therefore so is the maximum interval that is
+**  representable. However, that interval is never less that ~12 hours.
+*/
+
+#include "rcinrval.h"
+
+RCInterval::~RCInterval() { }
+
+RCInterval::RCInterval(RCInterval::RCReservedInterval special): RCBase()
+{
+    switch (special)
+    {
+    case RCInterval::now:
+        interval = PR_IntervalNow();
+        break;
+    case RCInterval::no_timeout:
+        interval = PR_INTERVAL_NO_TIMEOUT;
+        break;
+    case RCInterval::no_wait:
+        interval = PR_INTERVAL_NO_WAIT;
+        break;
+    default:
+        break;
+    }
+}  /* RCInterval::RCInterval */
+
+/* rcinrval.cpp */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcinrval.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcinrval.h
new file mode 100644
index 0000000..2dc2498
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcinrval.h
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** C++ interval times (ref: prinrval.h)
+**
+**  An interval is a period of time. The start of the interval (epoch)
+**  must be defined by the application. The unit of time of an interval
+**  is platform dependent, therefore so is the maximum interval that is
+**  representable. However, that interval is never less than ~6 hours.
+*/
+#if defined(_RCINTERVAL_H)
+#else
+#define _RCINTERVAL_H
+
+#include "rcbase.h"
+#include <prinrval.h>
+
+class PR_IMPLEMENT(RCInterval): public RCBase
+{
+public:
+    typedef enum {now, no_timeout, no_wait} RCReservedInterval;
+
+    virtual ~RCInterval();
+
+    RCInterval();
+
+    RCInterval(PRIntervalTime interval);
+    RCInterval(const RCInterval& copy);
+    RCInterval(RCReservedInterval special);
+
+    void SetToNow();
+
+    void operator=(const RCInterval&);
+    void operator=(PRIntervalTime interval);
+
+    PRBool operator<(const RCInterval&);
+    PRBool operator>(const RCInterval&);
+    PRBool operator==(const RCInterval&);
+    PRBool operator>=(const RCInterval&);
+    PRBool operator<=(const RCInterval&);
+
+    RCInterval operator+(const RCInterval&);
+    RCInterval operator-(const RCInterval&);
+    RCInterval& operator+=(const RCInterval&);
+    RCInterval& operator-=(const RCInterval&);
+
+    RCInterval operator/(PRUint32);
+    RCInterval operator*(PRUint32);
+    RCInterval& operator/=(PRUint32);
+    RCInterval& operator*=(PRUint32);
+
+
+    PRUint32 ToSeconds() const;
+    PRUint32 ToMilliseconds() const;
+    PRUint32 ToMicroseconds() const;
+    operator PRIntervalTime() const;
+
+    static PRIntervalTime FromSeconds(PRUint32 seconds);
+    static PRIntervalTime FromMilliseconds(PRUint32 milli);
+    static PRIntervalTime FromMicroseconds(PRUint32 micro);
+
+    friend class RCCondition;
+
+private:
+    PRIntervalTime interval;
+    
+};  /* RCInterval */
+
+
+inline RCInterval::RCInterval(): RCBase() { }
+
+inline RCInterval::RCInterval(const RCInterval& his): RCBase()
+    { interval = his.interval; }
+
+inline RCInterval::RCInterval(PRIntervalTime ticks): RCBase()
+    { interval = ticks; }
+
+inline void RCInterval::SetToNow() { interval = PR_IntervalNow(); }
+
+inline void RCInterval::operator=(const RCInterval& his)
+    { interval = his.interval; }
+
+inline void RCInterval::operator=(PRIntervalTime his)
+    { interval = his; }
+
+inline PRBool RCInterval::operator==(const RCInterval& his)
+    { return (interval == his.interval) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCInterval::operator<(const RCInterval& his)
+    { return (interval < his.interval)? PR_TRUE : PR_FALSE; }
+inline PRBool RCInterval::operator>(const RCInterval& his)
+    { return (interval > his.interval) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCInterval::operator<=(const RCInterval& his)
+    { return (interval <= his.interval) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCInterval::operator>=(const RCInterval& his)
+    { return (interval <= his.interval) ? PR_TRUE : PR_FALSE; }
+
+inline RCInterval RCInterval::operator+(const RCInterval& his)
+    { return RCInterval((PRIntervalTime)(interval + his.interval)); }
+inline RCInterval RCInterval::operator-(const RCInterval& his)
+    { return RCInterval((PRIntervalTime)(interval - his.interval)); }
+inline RCInterval& RCInterval::operator+=(const RCInterval& his)
+    { interval += his.interval; return *this; }
+inline RCInterval& RCInterval::operator-=(const RCInterval& his)
+    { interval -= his.interval; return *this; }
+
+inline RCInterval RCInterval::operator/(PRUint32 him)
+    { return RCInterval((PRIntervalTime)(interval / him)); }
+inline RCInterval RCInterval::operator*(PRUint32 him)
+    { return RCInterval((PRIntervalTime)(interval * him)); }
+
+inline RCInterval& RCInterval::operator/=(PRUint32 him)
+    { interval /= him; return *this; }
+
+inline RCInterval& RCInterval::operator*=(PRUint32 him)
+    { interval *= him; return *this; }
+
+inline PRUint32 RCInterval::ToSeconds() const
+    { return PR_IntervalToSeconds(interval); }
+inline PRUint32 RCInterval::ToMilliseconds() const
+    { return PR_IntervalToMilliseconds(interval); }
+inline PRUint32 RCInterval::ToMicroseconds() const
+    { return PR_IntervalToMicroseconds(interval); }
+inline RCInterval::operator PRIntervalTime() const { return interval; }
+
+inline PRIntervalTime RCInterval::FromSeconds(PRUint32 seconds)
+    { return PR_SecondsToInterval(seconds); }
+inline PRIntervalTime RCInterval::FromMilliseconds(PRUint32 milli)
+    { return PR_MillisecondsToInterval(milli); }
+inline PRIntervalTime RCInterval::FromMicroseconds(PRUint32 micro)
+    { return PR_MicrosecondsToInterval(micro); }
+
+#endif  /* defined(_RCINTERVAL_H) */
+
+/* RCInterval.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcio.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcio.cpp
new file mode 100644
index 0000000..27f9e78
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcio.cpp
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Base class implmenation for I/O (ref: prio.h)
+*/
+
+#include "rcio.h"
+
+RCIO::~RCIO() { }
+
+RCIO::RCIO(RCIO::RCIOType): RCBase() { }
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcio.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcio.h
new file mode 100644
index 0000000..5550a88
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcio.h
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Base class definitions for I/O (ref: prio.h)
+**
+** This class is a virtual base class. Construction must be done by a
+** subclass, but the I/O operations can be done on a RCIO object reference.
+*/
+
+#if defined(_RCIO_H)
+#else
+#define _RCIO_H
+
+#include "rcbase.h"
+#include "rcnetdb.h"
+#include "rcinrval.h"
+
+#include "prio.h"
+
+class RCFileInfo;
+
+class PR_IMPLEMENT(RCIO): public RCBase
+{
+public:
+    typedef enum {
+        open = PR_TRANSMITFILE_KEEP_OPEN,   /* socket is left open after file
+                                             * is transmitted. */
+        close = PR_TRANSMITFILE_CLOSE_SOCKET/* socket is closed after file
+                                             * is transmitted. */
+    } FileDisposition;
+
+    typedef enum {
+        set = PR_SEEK_SET,                  /* Set to value specified */
+        current = PR_SEEK_CUR,              /* Seek relative to current position */
+        end = PR_SEEK_END                   /* seek past end of current eof */
+    } Whence;
+
+    typedef enum {
+        recv = PR_SHUTDOWN_RCV,             /* receives will be disallowed */
+        send = PR_SHUTDOWN_SEND,            /* sends will be disallowed */
+        both = PR_SHUTDOWN_BOTH             /* sends & receives will be disallowed */
+    } ShutdownHow;
+
+public:
+    virtual ~RCIO();
+
+    virtual RCIO*       Accept(RCNetAddr* addr, const RCInterval& timeout) = 0;
+    virtual PRInt32     AcceptRead(
+                            RCIO **nd, RCNetAddr **raddr, void *buf,
+                            PRSize amount, const RCInterval& timeout) = 0;
+    virtual PRInt64     Available() = 0;
+    virtual PRStatus    Bind(const RCNetAddr& addr) = 0;
+    virtual PRStatus    Close() = 0;
+    virtual PRStatus    Connect(
+                            const RCNetAddr& addr,
+                            const RCInterval& timeout) = 0;
+    virtual PRStatus    FileInfo(RCFileInfo *info) const = 0;
+    virtual PRStatus    Fsync() = 0;
+    virtual PRStatus    GetLocalName(RCNetAddr *addr) const = 0;
+    virtual PRStatus    GetPeerName(RCNetAddr *addr) const = 0;
+    virtual PRStatus    GetSocketOption(PRSocketOptionData *data) const = 0;
+    virtual PRStatus    Listen(PRIntn backlog) = 0;
+    virtual PRStatus    Open(const char *name, PRIntn flags, PRIntn mode) = 0;
+    virtual PRInt16     Poll(PRInt16 in_flags, PRInt16 *out_flags) = 0;
+    virtual PRInt32     Read(void *buf, PRSize amount) = 0;
+    virtual PRInt32     Recv(
+                            void *buf, PRSize amount, PRIntn flags,
+                            const RCInterval& timeout) = 0;
+    virtual PRInt32     Recvfrom(
+                            void *buf, PRSize amount, PRIntn flags,
+                            RCNetAddr* addr, const RCInterval& timeout) = 0;
+    virtual PRInt64     Seek(PRInt64 offset, Whence how) = 0;
+    virtual PRInt32     Send(
+                            const void *buf, PRSize amount, PRIntn flags,
+                            const RCInterval& timeout) = 0;
+    virtual PRInt32     Sendto(
+                            const void *buf, PRSize amount, PRIntn flags,
+                            const RCNetAddr& addr,
+                            const RCInterval& timeout) = 0;
+    virtual PRStatus    SetSocketOption(const PRSocketOptionData *data) = 0;
+    virtual PRStatus    Shutdown(ShutdownHow how) = 0;
+    virtual PRInt32     TransmitFile(
+                            RCIO *source, const void *headers,
+                            PRSize hlen, RCIO::FileDisposition flags,
+                            const RCInterval& timeout) = 0;
+    virtual PRInt32     Write(const void *buf, PRSize amount) = 0;
+    virtual PRInt32     Writev(
+                            const PRIOVec *iov, PRSize size,
+                            const RCInterval& timeout) = 0;
+
+protected:
+    typedef enum {
+        file = PR_DESC_FILE,
+        tcp = PR_DESC_SOCKET_TCP,
+        udp = PR_DESC_SOCKET_UDP,
+        layered = PR_DESC_LAYERED} RCIOType;
+
+    RCIO(RCIOType);
+
+    PRFileDesc *fd;  /* where the real code hides */
+
+private:
+    /* no default construction and no copies allowed */
+    RCIO();
+    RCIO(const RCIO&);
+
+};  /* RCIO */
+
+#endif /* defined(_RCIO_H) */
+
+/* RCIO.h */
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rclock.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rclock.cpp
new file mode 100644
index 0000000..87b326b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rclock.cpp
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+** C++ access to NSPR locks (PRLock)
+*/
+
+#include "rclock.h"
+#include <prlog.h>
+
+RCLock::RCLock()
+{
+    lock = PR_NewLock();  /* it might be NULL */
+    PR_ASSERT(NULL != lock);
+}  /* RCLock::RCLock */
+
+RCLock::~RCLock()
+{
+    if (NULL != lock) PR_DestroyLock(lock);
+    lock = NULL;
+}  /* RCLock::~RCLock */
+
+void RCLock::Acquire()
+{
+    PR_ASSERT(NULL != lock);
+    PR_Lock(lock);
+}  /* RCLock::Acquire */
+
+void RCLock::Release()
+{
+    PRStatus rv;
+    PR_ASSERT(NULL != lock);
+    rv = PR_Unlock(lock);
+    PR_ASSERT(PR_SUCCESS == rv);
+}  /* RCLock::Release */
+
+/* RCLock.cpp */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rclock.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rclock.h
new file mode 100644
index 0000000..9e20ef0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rclock.h
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** C++ access to NSPR locks (PRLock)
+*/
+
+#if defined(_RCLOCK_H)
+#else
+#define _RCLOCK_H
+
+#include "rcbase.h"
+
+#include <prlock.h>
+
+class PR_IMPLEMENT(RCLock): public RCBase
+{
+public:
+    RCLock();
+    virtual ~RCLock();
+
+    void Acquire();                 /* non-reentrant */
+    void Release();                 /* should be by owning thread */
+
+    friend class RCCondition;
+
+private:
+    RCLock(const RCLock&);          /* can't do that */
+    void operator=(const RCLock&);  /* nor that */
+
+    PRLock *lock;
+};  /* RCLock */
+
+/*
+** Class: RCEnter
+**
+** In scope locks. You can only allocate them on the stack. The language
+** will insure that they get released (by calling the destructor) when
+** the thread leaves scope, even if via an exception.
+*/
+class PR_IMPLEMENT(RCEnter)
+{
+public:
+    ~RCEnter();                     /* releases the lock */
+    RCEnter(RCLock*);               /* acquires the lock */
+
+private:
+    RCLock *lock;
+
+    RCEnter();
+    RCEnter(const RCEnter&);
+    void operator=(const RCEnter&);
+
+    void *operator new(PRSize) { return NULL; }
+    void operator delete(void*) { }
+};  /* RCEnter */
+
+
+inline RCEnter::RCEnter(RCLock* ml) { lock = ml; lock->Acquire(); }
+inline RCEnter::~RCEnter() { lock->Release(); lock = NULL; }
+
+#endif /* defined(_RCLOCK_H) */
+
+/* RCLock.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcmon.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcmon.h
new file mode 100644
index 0000000..75b8ca3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcmon.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Class: RCMonitor (ref prmonitor.h)
+**
+** RCMonitor.h - C++ wrapper around NSPR's monitors
+*/
+#if defined(_RCMONITOR_H)
+#else
+#define _RCMONITOR_H
+
+#include "rcbase.h"
+#include "rcinrval.h"
+
+struct PRMonitor;
+
+class PR_IMPLEMENT(RCMonitor): public RCBase
+{
+public:
+    RCMonitor();                    /* timeout is infinity */
+    virtual ~RCMonitor();
+
+    virtual void Enter();           /* reentrant entry */
+    virtual void Exit();
+
+    virtual void Notify();          /* possibly enable one thread */
+    virtual void NotifyAll();       /* enable all waiters */
+
+    virtual void Wait();            /* applies object's timeout */
+
+    virtual void SetTimeout(const RCInterval& timeout);
+
+private:
+    PRMonitor *monitor;
+    RCInterval timeout;
+
+public:
+    RCInterval GetTimeout() const;  /* get the current value */
+
+};  /* RCMonitor */
+
+#endif /* defined(_RCMONITOR_H) */
+
+/* RCMonitor.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetdb.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetdb.cpp
new file mode 100644
index 0000000..9890c9a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetdb.cpp
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Base class implementation for network access functions (ref: prnetdb.h)
+*/
+
+#include "rclock.h"
+#include "rcnetdb.h"
+
+#include <prmem.h>
+#include <prlog.h>
+#include <string.h>
+
+RCNetAddr::RCNetAddr(const RCNetAddr& his): RCBase()
+    { address = his.address; }
+
+RCNetAddr::RCNetAddr(const RCNetAddr& his, PRUint16 port): RCBase()
+{
+    address = his.address;
+    switch (address.raw.family)
+    {
+        case PR_AF_INET: address.inet.port = port; break;
+        case PR_AF_INET6: address.ipv6.port = port; break;
+        default: break;
+    }
+}  /* RCNetAddr::RCNetAddr */
+
+RCNetAddr::RCNetAddr(RCNetAddr::HostValue host, PRUint16 port): RCBase()
+{
+    PRNetAddrValue how;
+    switch (host)
+    {
+        case RCNetAddr::any: how = PR_IpAddrAny; break;
+        case RCNetAddr::loopback: how = PR_IpAddrLoopback; break;
+        default: PR_ASSERT(!"This can't happen -- and did!");
+    }
+    (void)PR_InitializeNetAddr(how, port, &address);
+}  /* RCNetAddr::RCNetAddr */
+
+RCNetAddr::~RCNetAddr() { }
+
+void RCNetAddr::operator=(const RCNetAddr& his) { address = his.address; }
+
+PRStatus RCNetAddr::FromString(const char* string)
+    { return PR_StringToNetAddr(string, &address); }
+
+void RCNetAddr::operator=(const PRNetAddr* addr) { address = *addr; }
+
+PRBool RCNetAddr::operator==(const RCNetAddr& his) const
+{
+    PRBool rv = EqualHost(his);
+    if (rv)
+    {
+        switch (address.raw.family)
+        {
+            case PR_AF_INET:
+                rv = (address.inet.port == his.address.inet.port); break;
+            case PR_AF_INET6:
+                rv = (address.ipv6.port == his.address.ipv6.port); break;
+            case PR_AF_LOCAL:
+            default: break;
+        }
+    }
+    return rv;
+}  /* RCNetAddr::operator== */
+
+PRBool RCNetAddr::EqualHost(const RCNetAddr& his) const
+{
+    PRBool rv;
+    switch (address.raw.family)
+    {
+        case PR_AF_INET:
+            rv = (address.inet.ip == his.address.inet.ip); break;
+        case PR_AF_INET6:
+            rv = (0 == memcmp(
+                &address.ipv6.ip, &his.address.ipv6.ip,
+                sizeof(address.ipv6.ip)));
+            break;
+#if defined(XP_UNIX)
+        case PR_AF_LOCAL:
+            rv = (0 == strncmp(
+                address.local.path, his.address.local.path,
+                sizeof(address.local.path)));
+            break;
+#endif
+        default: break;
+    }
+    return rv;
+}  /* RCNetAddr::operator== */
+
+PRStatus RCNetAddr::ToString(char *string, PRSize size) const
+    { return PR_NetAddrToString(&address, string, size); }
+
+/*
+** RCHostLookup
+*/
+
+RCHostLookup::~RCHostLookup()
+{
+    if (NULL != address) delete [] address;
+}  /* RCHostLookup::~RCHostLookup */
+
+RCHostLookup::RCHostLookup(): RCBase()
+{
+    address = NULL;
+    max_index = 0;
+}  /* RCHostLookup::RCHostLookup */
+
+PRStatus RCHostLookup::ByName(const char* name)
+{
+    PRStatus rv;
+    PRNetAddr addr;
+    PRHostEnt hostentry;
+    PRIntn index = 0, max;
+    RCNetAddr* vector = NULL;
+    RCNetAddr* old_vector = NULL;
+    void* buffer = PR_Malloc(PR_NETDB_BUF_SIZE);
+    if (NULL == buffer) return PR_FAILURE;
+    rv = PR_GetHostByName(name, (char*)buffer, PR_NETDB_BUF_SIZE, &hostentry);
+    if (PR_SUCCESS == rv)
+    {
+        for (max = 0, index = 0;; ++max)
+        {
+            index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
+            if (0 == index) break;
+        }
+        if (max > 0)
+        {
+            vector = new RCNetAddr[max];
+            while (--max > 0)
+            {
+                index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
+                if (0 == index) break;
+                vector[index] = &addr;
+            }
+            {
+                RCEnter entry(&ml);
+                old_vector = address;
+                address = vector;
+                max_index = max;
+            }
+            if (NULL != old_vector) delete [] old_vector;
+        }
+    }
+    if (NULL != buffer) PR_DELETE(buffer);
+    return PR_SUCCESS;
+}  /* RCHostLookup::ByName */
+
+PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr)
+{
+    PRStatus rv;
+    PRNetAddr addr;
+    PRHostEnt hostentry;
+    PRIntn index = 0, max;
+    RCNetAddr* vector = NULL;
+    RCNetAddr* old_vector = NULL;
+    char *buffer = (char*)PR_Malloc(PR_NETDB_BUF_SIZE);
+    if (NULL == buffer) return PR_FAILURE;
+    rv = PR_GetHostByAddr(host_addr, buffer, PR_NETDB_BUF_SIZE, &hostentry);
+    if (PR_SUCCESS == rv)
+    {
+        for (max = 0, index = 0;; ++max)
+        {
+            index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
+            if (0 == index) break;
+        }
+        if (max > 0)
+        {
+            vector = new RCNetAddr[max];
+            while (--max > 0)
+            {
+                index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
+                if (0 == index) break;
+                vector[index] = &addr;
+            }
+            {
+                RCEnter entry(&ml);
+                old_vector = address;
+                address = vector;
+                max_index = max;
+            }
+            if (NULL != old_vector) delete [] old_vector;
+        }
+    }
+    if (NULL != buffer) PR_DELETE(buffer);
+    return PR_SUCCESS;
+}  /* RCHostLookup::ByAddress */
+
+const RCNetAddr* RCHostLookup::operator[](PRUintn which)
+{
+    RCNetAddr* addr = NULL;
+    if (which < max_index)
+        addr = &address[which];
+    return addr;
+}  /* RCHostLookup::operator[] */
+
+/* RCNetdb.cpp */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetdb.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetdb.h
new file mode 100644
index 0000000..03f5b4f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetdb.h
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Base class definitions for network access functions (ref: prnetdb.h)
+*/
+
+#if defined(_RCNETDB_H)
+#else
+#define _RCNETDB_H
+
+#include "rclock.h"
+#include "rcbase.h"
+
+#include <prnetdb.h>
+
+class PR_IMPLEMENT(RCNetAddr): public RCBase
+{
+public:
+    typedef enum {
+        any = PR_IpAddrAny,             /* assign logical INADDR_ANY */
+        loopback = PR_IpAddrLoopback    /* assign logical INADDR_LOOPBACK */
+    } HostValue;
+
+    RCNetAddr();                        /* default constructor is unit'd object */
+    RCNetAddr(const RCNetAddr&);        /* copy constructor */
+    RCNetAddr(HostValue, PRUint16 port);/* init'd w/ 'special' assignments */
+    RCNetAddr(const RCNetAddr&, PRUint16 port);
+                                        /* copy w/ port reassigment */
+
+    virtual ~RCNetAddr();
+
+    void operator=(const RCNetAddr&);
+
+    virtual PRBool operator==(const RCNetAddr&) const;
+                                        /* compare of all relavent fields */
+    virtual PRBool EqualHost(const RCNetAddr&) const;
+                                        /* compare of just host field */
+
+
+public:
+
+    void operator=(const PRNetAddr*);   /* construction from more primitive data */
+    operator const PRNetAddr*() const;  /* extraction of underlying representation */
+    virtual PRStatus FromString(const char* string);
+                                        /* initialization from an ASCII string */
+    virtual PRStatus ToString(char *string, PRSize size) const;
+                                        /* convert internal fromat to a string */
+
+private:
+
+    PRNetAddr address;
+
+};  /* RCNetAddr */
+
+/*
+** Class: RCHostLookup
+**
+** Abstractions to look up host names and addresses.
+**
+** This is a stateful class. One looks up the host by name or by
+** address, then enumerates over a possibly empty array of network
+** addresses. The storage for the addresses is owned by the class.
+*/
+
+class RCHostLookup: public RCBase
+{
+public:
+    virtual ~RCHostLookup();
+
+    RCHostLookup();
+
+    virtual PRStatus ByName(const char* name);
+    virtual PRStatus ByAddress(const RCNetAddr&);
+
+    virtual const RCNetAddr* operator[](PRUintn);
+
+private:
+    RCLock ml;
+    PRIntn max_index;
+    RCNetAddr* address;
+
+    RCHostLookup(const RCHostLookup&);
+    RCHostLookup& operator=(const RCHostLookup&);
+};
+
+inline RCNetAddr::RCNetAddr(): RCBase() { }
+inline RCNetAddr::operator const PRNetAddr*() const { return &address; }
+
+
+#endif /* defined(_RCNETDB_H) */
+
+/* RCNetdb.h */
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetio.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetio.cpp
new file mode 100644
index 0000000..bdc9430
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetio.cpp
@@ -0,0 +1,195 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Subclass implementation for streamed network I/O (ref: prio.h)
+*/
+
+#include "rcnetio.h"
+
+#include <private/pprio.h>
+
+RCNetStreamIO::~RCNetStreamIO()
+    { PRStatus rv = (fd->methods->close)(fd); fd = NULL; }
+
+RCNetStreamIO::RCNetStreamIO(): RCIO(RCIO::tcp)
+    { fd = PR_NewTCPSocket(); }
+
+RCNetStreamIO::RCNetStreamIO(PRIntn protocol): RCIO(RCIO::tcp)
+    { fd = PR_Socket(PR_AF_INET, PR_SOCK_STREAM, protocol); }
+
+RCIO* RCNetStreamIO::Accept(RCNetAddr* addr, const RCInterval& timeout)
+{
+    PRNetAddr peer;
+    RCNetStreamIO* rcio = NULL;
+    PRFileDesc* newfd = fd->methods->accept(fd, &peer, timeout);
+    if (NULL != newfd)
+    {
+        rcio = new RCNetStreamIO();
+        if (NULL != rcio)
+        {
+            *addr = &peer;
+            rcio->fd = newfd;
+        }
+        else
+            (void)(newfd->methods->close)(newfd);
+    }
+    return rcio;
+}  /* RCNetStreamIO::Accept */
+
+PRInt32 RCNetStreamIO::AcceptRead(
+    RCIO **nd, RCNetAddr **raddr, void *buf,
+    PRSize amount, const RCInterval& timeout)
+{   
+    PRNetAddr *from;
+    PRFileDesc *accepted;
+    PRInt32 rv = (fd->methods->acceptread)(
+        fd, &accepted, &from, buf, amount, timeout);
+    if (rv >= 0)
+    {
+        RCNetStreamIO *ns = new RCNetStreamIO();
+        if (NULL != *nd) ns->fd = accepted;
+        else {PR_Close(accepted); rv = -1; }
+        *nd = ns;
+    }
+    return rv;
+}  /* RCNetStreamIO::AcceptRead */
+
+PRInt64 RCNetStreamIO::Available()
+    { return (fd->methods->available64)(fd); }
+
+PRStatus RCNetStreamIO::Bind(const RCNetAddr& addr)
+    { return (fd->methods->bind)(fd, addr); }
+
+PRStatus RCNetStreamIO::Connect(const RCNetAddr& addr, const RCInterval& timeout)
+    { return (fd->methods->connect)(fd, addr, timeout); }
+
+PRStatus RCNetStreamIO::GetLocalName(RCNetAddr *addr) const
+{
+    PRNetAddr local;
+    PRStatus rv = (fd->methods->getsockname)(fd, &local);
+    if (PR_SUCCESS == rv) *addr = &local;
+    return rv;
+}  /* RCNetStreamIO::GetLocalName */
+
+PRStatus RCNetStreamIO::GetPeerName(RCNetAddr *addr) const
+{
+    PRNetAddr peer;
+    PRStatus rv = (fd->methods->getpeername)(fd, &peer);
+    if (PR_SUCCESS == rv) *addr = &peer;
+    return rv;
+}  /* RCNetStreamIO::GetPeerName */
+
+PRStatus RCNetStreamIO::GetSocketOption(PRSocketOptionData *data) const
+    { return (fd->methods->getsocketoption)(fd, data); }
+
+PRStatus RCNetStreamIO::Listen(PRIntn backlog)
+    { return (fd->methods->listen)(fd, backlog); }
+
+PRInt16 RCNetStreamIO::Poll(PRInt16 in_flags, PRInt16 *out_flags)
+    { return (fd->methods->poll)(fd, in_flags, out_flags); }
+
+PRInt32 RCNetStreamIO::Read(void *buf, PRSize amount)
+    { return (fd->methods->read)(fd, buf, amount); }
+
+PRInt32 RCNetStreamIO::Recv(
+    void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout)
+    { return (fd->methods->recv)(fd, buf, amount, flags, timeout); }
+
+PRInt32 RCNetStreamIO::Recvfrom(
+    void *buf, PRSize amount, PRIntn flags,
+    RCNetAddr* addr, const RCInterval& timeout)
+{
+    PRNetAddr peer;
+    PRInt32 rv = (fd->methods->recvfrom)(
+        fd, buf, amount, flags, &peer, timeout);
+    if (-1 != rv) *addr = &peer;
+    return rv;
+}  /* RCNetStreamIO::Recvfrom */
+
+PRInt32 RCNetStreamIO::Send(
+    const void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout)
+    { return (fd->methods->send)(fd, buf, amount, flags, timeout); }
+
+PRInt32 RCNetStreamIO::Sendto(
+    const void *buf, PRSize amount, PRIntn flags,
+    const RCNetAddr& addr, const RCInterval& timeout)
+    { return (fd->methods->sendto)(fd, buf, amount, flags, addr, timeout); }
+
+PRStatus RCNetStreamIO::SetSocketOption(const PRSocketOptionData *data)
+    { return (fd->methods->setsocketoption)(fd, data); }
+
+PRStatus RCNetStreamIO::Shutdown(RCIO::ShutdownHow how)
+    { return (fd->methods->shutdown)(fd, (PRIntn)how); }
+
+PRInt32 RCNetStreamIO::TransmitFile(
+    RCIO *source, const void *headers, PRSize hlen,
+    RCIO::FileDisposition flags, const RCInterval& timeout)
+{
+    RCNetStreamIO *src = (RCNetStreamIO*)source;
+    return (fd->methods->transmitfile)(
+        fd, src->fd, headers, hlen, (PRTransmitFileFlags)flags, timeout); }
+
+PRInt32 RCNetStreamIO::Write(const void *buf, PRSize amount)
+    { return (fd->methods->write)(fd, buf, amount); }
+
+PRInt32 RCNetStreamIO::Writev(
+    const PRIOVec *iov, PRSize size, const RCInterval& timeout)
+    { return (fd->methods->writev)(fd, iov, size, timeout); }
+    
+/*
+** Invalid functions
+*/
+
+PRStatus RCNetStreamIO::Close()
+    { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCNetStreamIO::FileInfo(RCFileInfo*) const
+    { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCNetStreamIO::Fsync()
+    { return (fd->methods->fsync)(fd); }
+
+PRStatus RCNetStreamIO::Open(const char*, PRIntn, PRIntn)
+    { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRInt64 RCNetStreamIO::Seek(PRInt64, RCIO::Whence)
+    { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+/* RCNetStreamIO.cpp */
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetio.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetio.h
new file mode 100644
index 0000000..54ce695
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcnetio.h
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Subclass definitions for network I/O (ref: prio.h)
+*/
+
+#if defined(_RCNETIO_H)
+#else
+#define _RCNETIO_H
+
+#include "rcbase.h"
+#include "rcinrval.h"
+#include "rcio.h"
+#include "rcnetdb.h"
+
+#include "prio.h"
+
+class RCFileInfo;
+
+/*
+** Class: RCNetStreamIO (ref prio.h)
+**
+** Streamed (reliable) network I/O (e.g., TCP).
+** This class hides (makes private) the functions that are not applicable
+** to network I/O (i.e., those for file I/O).
+*/
+
+class PR_IMPLEMENT(RCNetStreamIO): public RCIO
+{
+
+public:
+    RCNetStreamIO();
+    virtual ~RCNetStreamIO();
+
+    virtual RCIO*       Accept(RCNetAddr* addr, const RCInterval& timeout);
+    virtual PRInt32     AcceptRead(
+                            RCIO **nd, RCNetAddr **raddr, void *buf,
+                            PRSize amount, const RCInterval& timeout);
+    virtual PRInt64     Available();
+    virtual PRStatus    Bind(const RCNetAddr& addr);
+    virtual PRStatus    Connect(
+                            const RCNetAddr& addr, const RCInterval& timeout);
+    virtual PRStatus    GetLocalName(RCNetAddr *addr) const;
+    virtual PRStatus    GetPeerName(RCNetAddr *addr) const;
+    virtual PRStatus    GetSocketOption(PRSocketOptionData *data) const;
+    virtual PRStatus    Listen(PRIntn backlog);
+    virtual PRInt16     Poll(PRInt16 in_flags, PRInt16 *out_flags);
+    virtual PRInt32     Read(void *buf, PRSize amount);
+    virtual PRInt32     Recv(
+                            void *buf, PRSize amount, PRIntn flags,
+                            const RCInterval& timeout);
+    virtual PRInt32     Recvfrom(
+                            void *buf, PRSize amount, PRIntn flags,
+                            RCNetAddr* addr, const RCInterval& timeout);
+    virtual PRInt32     Send(
+                            const void *buf, PRSize amount, PRIntn flags,
+                            const RCInterval& timeout);
+    virtual PRInt32     Sendto(
+                            const void *buf, PRSize amount, PRIntn flags,
+                            const RCNetAddr& addr,
+                            const RCInterval& timeout);
+    virtual PRStatus    SetSocketOption(const PRSocketOptionData *data);
+    virtual PRStatus    Shutdown(ShutdownHow how);
+    virtual PRInt32     TransmitFile(
+                            RCIO *source, const void *headers,
+                            PRSize hlen, RCIO::FileDisposition flags,
+                            const RCInterval& timeout);
+    virtual PRInt32     Write(const void *buf, PRSize amount);
+    virtual PRInt32     Writev(
+                            const PRIOVec *iov, PRSize size,
+                            const RCInterval& timeout);
+
+private:
+    /* functions unavailable to this clients of this class */
+    RCNetStreamIO(const RCNetStreamIO&);
+
+    PRStatus    Close();
+    PRStatus    Open(const char *name, PRIntn flags, PRIntn mode);
+    PRStatus    FileInfo(RCFileInfo *info) const;
+    PRStatus    Fsync();
+    PRInt64     Seek(PRInt64 offset, RCIO::Whence how);
+
+public:
+    RCNetStreamIO(PRIntn protocol);
+};  /* RCNetIO */
+
+#endif /* defined(_RCNETIO_H) */
+
+/* RCNetStreamIO.h */
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcthread.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcthread.cpp
new file mode 100755
index 0000000..25a9810
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcthread.cpp
@@ -0,0 +1,220 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* RCThread.cpp - C++ wrapper on NSPR */
+
+#include "rcthread.h"
+#include "rcinrval.h"
+
+#include <prmem.h>
+#include <prlog.h>
+#include <stdio.h>
+#include <prinit.h>
+
+static RCPrimordialThread *primordial = NULL;
+
+void nas_Root(void *arg)
+{
+    RCThread *him = (RCThread*)arg;
+    while (RCThread::ex_unstarted == him->execution)
+        (void)PR_Sleep(PR_INTERVAL_NO_TIMEOUT);  /* wait for Start() */
+    him->RootFunction();  /* he gets a self reference */
+    if (PR_UNJOINABLE_THREAD == PR_GetThreadState(him->identity))
+        delete him;
+}  /* nas_Root */
+
+RCThread::~RCThread() { }
+
+RCThread::RCThread(): RCBase() { }
+
+RCThread::RCThread(const RCThread&): RCBase()
+{
+    PR_NOT_REACHED("Cannot call thread copy constructor");
+}  /* RCThread::RCThread */
+
+RCThread::RCThread(
+    RCThread::Scope scope, RCThread::State join, PRUint32 stackSize):
+    RCBase()
+{
+    execution = ex_unstarted;
+    identity = PR_CreateThread(
+        PR_USER_THREAD, nas_Root, this,
+        PR_GetThreadPriority(PR_GetCurrentThread()),
+        (PRThreadScope)scope, (PRThreadState)join, stackSize);
+}  /* RCThread::RCThread */
+
+void RCThread::operator=(const RCThread&)
+{
+    PR_NOT_REACHED("Cannot call thread assignment operator");
+}  /* RCThread::operator= */
+
+
+PRStatus RCThread::Start()
+{
+    PRStatus rv;
+    /* This is an unsafe check, but not too critical */
+    if (RCThread::ex_unstarted == execution)
+    {
+        execution = RCThread::ex_started;
+        rv = PR_Interrupt(identity);
+        PR_ASSERT(PR_SUCCESS == rv);
+    }
+    else
+    {
+        rv = PR_FAILURE;
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+    }
+    return rv;
+}  /* RCThread::Start */
+
+PRStatus RCThread::Join()
+{
+    PRStatus rv;
+    if (RCThread::ex_unstarted == execution)
+    {
+        rv = PR_FAILURE;
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+    }
+    else rv = PR_JoinThread(identity);
+    if (PR_SUCCESS == rv) delete this;
+    return rv;
+}  /* RCThread::Join */
+
+PRStatus RCThread::Interrupt()
+{
+    PRStatus rv;
+    if (RCThread::ex_unstarted == execution)
+    {
+        rv = PR_FAILURE;
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+    }
+    else rv = PR_Interrupt(identity);
+    return rv;
+}  /* RCThread::Interrupt */
+
+void RCThread::ClearInterrupt() { PR_ClearInterrupt(); }
+
+void RCThread::SetPriority(RCThread::Priority new_priority)
+    { PR_SetThreadPriority(identity, (PRThreadPriority)new_priority); }
+
+PRThread *RCThread::Self()
+    { return PR_GetCurrentThread(); }
+
+RCThread::Scope RCThread::GetScope() const
+    { return (RCThread::Scope)PR_GetThreadScope(identity); }
+
+RCThread::State RCThread::GetState() const
+    { return (RCThread::State)PR_GetThreadState(identity); }
+
+RCThread::Priority RCThread::GetPriority() const
+    { return (RCThread::Priority)PR_GetThreadPriority(identity); }
+    
+static void _rc_PDDestructor(RCThreadPrivateData* privateData)
+{
+    PR_ASSERT(NULL != privateData);
+    privateData->Release();
+}
+
+static PRThreadPrivateDTOR _tpd_dtor = (PRThreadPrivateDTOR)_rc_PDDestructor;
+
+PRStatus RCThread::NewPrivateIndex(PRUintn* index)
+    { return PR_NewThreadPrivateIndex(index, _tpd_dtor); }
+
+PRStatus RCThread::SetPrivateData(PRUintn index)
+    { return PR_SetThreadPrivate(index, NULL); }
+
+PRStatus RCThread::SetPrivateData(PRUintn index, RCThreadPrivateData* data)
+{
+    return PR_SetThreadPrivate(index, data);
+}
+
+RCThreadPrivateData* RCThread::GetPrivateData(PRUintn index)
+    { return (RCThreadPrivateData*)PR_GetThreadPrivate(index); }
+
+PRStatus RCThread::Sleep(const RCInterval& ticks)
+    { PRIntervalTime tmo = ticks; return PR_Sleep(tmo); }
+
+RCPrimordialThread *RCThread::WrapPrimordialThread()
+{
+    /*
+    ** This needs to take more care in insuring that the thread
+    ** being wrapped is really the primordial thread. This code
+    ** is assuming that the caller is the primordial thread, and
+    ** there's nothing to insure that.
+    */
+    if (NULL == primordial)
+    {
+        /* it doesn't have to be perfect */
+        RCPrimordialThread *me = new RCPrimordialThread();
+        PR_ASSERT(NULL != me);
+        if (NULL == primordial)
+        {
+            primordial = me;
+            me->execution = RCThread::ex_started;
+            me->identity = PR_GetCurrentThread();
+        }
+        else delete me;  /* somebody beat us to it */
+    }
+    return primordial;
+}  /* RCThread::WrapPrimordialThread */
+
+RCPrimordialThread::RCPrimordialThread(): RCThread() { }
+
+RCPrimordialThread::~RCPrimordialThread() { }
+
+void RCPrimordialThread::RootFunction()
+{
+    PR_NOT_REACHED("Primordial thread calling root function"); 
+}  /* RCPrimordialThread::RootFunction */
+ 
+PRStatus RCPrimordialThread::Cleanup() { return PR_Cleanup(); }
+
+PRStatus RCPrimordialThread::SetVirtualProcessors(PRIntn count)
+{
+    PR_SetConcurrency(count);
+    return PR_SUCCESS;
+}  /* SetVirutalProcessors */
+
+RCThreadPrivateData::RCThreadPrivateData() { }
+
+RCThreadPrivateData::RCThreadPrivateData(
+    const RCThreadPrivateData& him) { }
+
+RCThreadPrivateData::~RCThreadPrivateData() { }
+
+/* RCThread.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcthread.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcthread.h
new file mode 100644
index 0000000..2b00056
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rcthread.h
@@ -0,0 +1,227 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* RCThread.h */
+
+#if defined(_RCTHREAD_H)
+#else
+#define _RCTHREAD_H
+
+#include "rcbase.h"
+
+#include <prthread.h>
+
+class RCInterval;
+
+class PR_IMPLEMENT(RCThreadPrivateData)
+{
+public:
+    RCThreadPrivateData();
+    RCThreadPrivateData(const RCThreadPrivateData&);
+
+    virtual ~RCThreadPrivateData();
+
+    virtual void Release() = 0;
+
+};  /* RCThreadPrivateData */
+
+class PR_IMPLEMENT(RCThread): public RCBase
+{
+public:
+
+    typedef enum 
+    {
+        local = PR_LOCAL_THREAD, global = PR_GLOBAL_THREAD
+    } Scope;
+
+    typedef enum
+    {
+        joinable = PR_JOINABLE_THREAD, unjoinable = PR_UNJOINABLE_THREAD
+    } State;
+
+    typedef enum
+    {
+        first = PR_PRIORITY_FIRST,
+        low = PR_PRIORITY_LOW,
+        normal = PR_PRIORITY_NORMAL,
+        high = PR_PRIORITY_HIGH,
+        urgent = PR_PRIORITY_URGENT,
+        last = PR_PRIORITY_LAST
+    } Priority;
+
+    /*
+     * Create a new thread, providing scope and joinability state.
+     */
+    RCThread(Scope scope, State state, PRUint32 stackSize=0);
+
+    /*
+     * New threads are created in a suspended state. It must be 'started"
+     * before it begins execution in the class' defined 'RootFunction()'.
+     */
+    virtual PRStatus Start();
+
+    /*
+     * If a thread is created joinable, then the thread's object exists
+     * until join is called. The thread that calls join will block until
+     * the target thread returns from it's root function.
+     */
+    virtual PRStatus Join();
+    
+    /*
+     * The priority of a newly created thread is the same as the creator.
+     * The priority may be changed either by the new thread itself, by
+     * the creator or any other arbitrary thread.
+     */   
+    virtual void SetPriority(Priority newPriority);
+
+
+    /*
+     * Interrupt another thread, causing it to stop what it
+     * is doing and return with a well known error code.
+     */
+    virtual PRStatus Interrupt();
+    
+    /*
+     * And in case a thread was interrupted and didn't get a chance
+     * to have the notification delivered, a way to cancel the pending
+     * status.
+     */
+    static void ClearInterrupt();
+    
+    /*
+     * Methods to discover the attributes of an existing thread.
+     */
+    static PRThread *Self();
+    Scope GetScope() const;
+    State GetState() const;
+    Priority GetPriority() const;
+
+    /*
+     * Thread private data
+     */
+    static PRStatus NewPrivateIndex(PRUintn* index);
+
+    /*
+     * Getting it - if you want to modify, make a copy
+     */
+    static RCThreadPrivateData* GetPrivateData(PRUintn index);
+
+    /*
+     * Setting it to <empty> - deletes existing data
+     */
+    static PRStatus SetPrivateData(PRUintn index);
+
+    /*
+     * Setting it - runtime will make a copy, freeing old iff necessary
+     */
+    static PRStatus SetPrivateData(PRUintn index, RCThreadPrivateData* data);
+
+    /*
+     * Scheduling control
+     */
+    static PRStatus Sleep(const RCInterval& ticks);
+
+    friend void nas_Root(void*);
+    friend class RCPrimordialThread;
+protected:
+
+    /*
+     * The instantiator of a class must not call the destructor. The base
+     * implementation of Join will, and if the thread is created unjoinable,
+     * then the code that called the RootFunction will call the desctructor.
+     */
+    virtual ~RCThread();
+
+private:
+
+    /*
+     * This is where a newly created thread begins execution. Returning
+     * from this function is equivalent to terminating the thread.
+     */
+    virtual void RootFunction() = 0;
+
+    PRThread *identity;
+
+    /* Threads are unstarted until started - pretty startling */
+    enum {ex_unstarted, ex_started} execution;
+
+    /* There is no public default constructor or copy constructor */
+    RCThread();
+    RCThread(const RCThread&);
+    
+    /* And there is no assignment operator */
+    void operator=(const RCThread&);
+
+public:
+    static RCPrimordialThread *WrapPrimordialThread();    
+
+ };
+ 
+/*
+** class RCPrimordialThread
+*/
+class PR_IMPLEMENT(RCPrimordialThread): public RCThread
+{
+public:
+    /*
+    ** The primordial thread can (optionally) wait for all created
+    ** threads to terminate before allowing the process to exit.
+    ** Not calling Cleanup() before returning from main() will cause
+    ** the immediate termination of the entire process, including
+    ** any running threads.
+    */
+    static PRStatus Cleanup();
+
+    /*
+    ** Only the primordial thread is allowed to adjust the number of
+    ** virtual processors of the runtime. It's a lame security thing.
+    */
+    static PRStatus SetVirtualProcessors(PRIntn count=10);
+
+friend class RCThread;
+private:
+    /*
+    ** None other than the runtime can create of destruct
+    ** a primordial thread. It is fabricated by the runtime
+    ** to wrap the thread that initiated the application.
+    */
+    RCPrimordialThread();
+    ~RCPrimordialThread();
+    void RootFunction();
+};  /* RCPrimordialThread */
+
+ #endif /* defined(_RCTHREAD_H) */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rctime.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rctime.cpp
new file mode 100644
index 0000000..03c6ff3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rctime.cpp
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Class implementation for calendar time routines (ref: prtime.h)
+*/
+
+#include "rctime.h"
+
+RCTime::~RCTime() { }
+
+RCTime::RCTime(PRTime time): RCBase() { gmt = time; }
+RCTime::RCTime(const RCTime& his): RCBase() { gmt = his.gmt; }
+RCTime::RCTime(RCTime::Current): RCBase() { gmt = PR_Now(); }
+RCTime::RCTime(const PRExplodedTime& time): RCBase()
+{ gmt = PR_ImplodeTime(&time); }
+
+void RCTime::operator=(const PRExplodedTime& time)
+{ gmt = PR_ImplodeTime(&time); }
+
+RCTime RCTime::operator+(const RCTime& his)
+{ RCTime sum(gmt + his.gmt); return sum; }
+
+RCTime RCTime::operator-(const RCTime& his)
+{ RCTime difference(gmt - his.gmt); return difference; }
+
+RCTime RCTime::operator/(PRUint64 his)
+{ RCTime quotient(gmt / gmt); return quotient; }
+
+RCTime RCTime::operator*(PRUint64 his)
+{ RCTime product(gmt * his); return product; }
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rctime.h b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rctime.h
new file mode 100644
index 0000000..f0b900a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/rctime.h
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Class definitions for calendar time routines (ref: prtime.h)
+*/
+
+#if defined(_RCTIME_H)
+#else
+#define _RCTIME_H
+
+#include "rcbase.h"
+
+#include <prtime.h>
+
+/*
+** Class: RCTime (ref: prtime.h)
+**
+** RCTimes are objects that are intended to be used to represent calendar
+** times. They maintain units internally as microseconds since the defined
+** epoch (midnight, January 1, 1970, GMT). Conversions to and from external
+** formats (PRExplodedTime) are available.
+**
+** In general, NCTimes possess normal algebretic capabilities.
+*/
+
+class PR_IMPLEMENT(RCTime): public RCBase
+{
+public:
+    typedef enum {now} Current;
+
+    RCTime();                       /* leaves the object unitialized */
+    RCTime(Current);                /* initializes to current system time */
+    RCTime(const RCTime&);          /* copy constructor */
+    RCTime(const PRExplodedTime&);  /* construction from exploded representation */
+
+    virtual ~RCTime();
+
+    /* assignment operators */
+    void operator=(const RCTime&); 
+    void operator=(const PRExplodedTime&);
+
+    /* comparitive operators */
+    PRBool operator<(const RCTime&);
+    PRBool operator>(const RCTime&);
+    PRBool operator<=(const RCTime&);
+    PRBool operator>=(const RCTime&);
+    PRBool operator==(const RCTime&);
+
+    /* associative operators */
+    RCTime operator+(const RCTime&);
+    RCTime operator-(const RCTime&);
+    RCTime& operator+=(const RCTime&);
+    RCTime& operator-=(const RCTime&);
+
+    /* multiply and divide operators */
+    RCTime operator/(PRUint64);
+    RCTime operator*(PRUint64);
+    RCTime& operator/=(PRUint64);
+    RCTime& operator*=(PRUint64);
+
+    void Now();                     /* assign current time to object */
+
+private:
+    PRTime gmt;
+
+public:
+
+    RCTime(PRTime);                 /* construct from raw PRTime */
+    void operator=(PRTime);         /* assign from raw PRTime */
+    operator PRTime() const;        /* extract internal representation */
+};  /* RCTime */
+
+inline RCTime::RCTime(): RCBase() { }
+
+inline void RCTime::Now() { gmt = PR_Now(); }
+inline RCTime::operator PRTime() const { return gmt; }
+
+inline void RCTime::operator=(PRTime his) { gmt = his; }
+inline void RCTime::operator=(const RCTime& his) { gmt = his.gmt; }
+
+inline PRBool RCTime::operator<(const RCTime& his)
+    { return (gmt < his.gmt) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCTime::operator>(const RCTime& his)
+    { return (gmt > his.gmt) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCTime::operator<=(const RCTime& his)
+    { return (gmt <= his.gmt) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCTime::operator>=(const RCTime& his)
+    { return (gmt >= his.gmt) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCTime::operator==(const RCTime& his)
+    { return (gmt == his.gmt) ? PR_TRUE : PR_FALSE; }
+
+inline RCTime& RCTime::operator+=(const RCTime& his)
+    { gmt += his.gmt; return *this; }
+inline RCTime& RCTime::operator-=(const RCTime& his)
+    { gmt -= his.gmt; return *this; }
+inline RCTime& RCTime::operator/=(PRUint64 his)
+    { gmt /= his; return *this; }
+inline RCTime& RCTime::operator*=(PRUint64 his)
+    { gmt *= his; return *this; }
+
+#endif /* defined(_RCTIME_H) */
+
+/* RCTime.h */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/Makefile.in
new file mode 100644
index 0000000..78f1cbe
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/Makefile.in
@@ -0,0 +1,273 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifeq ($(OS_TARGET), WIN16)
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+endif
+
+CXXSRCS =           \
+	ranfile.cpp     \
+	thread.cpp      \
+	interval.cpp    \
+	time.cpp        \
+	fileio.cpp      \
+	switch.cpp      \
+	tpd.cpp         \
+	$(NULL)
+
+OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX)))
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CXXSRCS:.cpp=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS) $(OBJS)
+
+INCLUDES = -I.. -I$(dist_includedir)
+
+# Setting the variables LDOPTS and LIBPR.  We first initialize
+# them to the default values, then adjust them for some platforms.
+LDOPTS = -L$(dist_libdir)
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)
+LIBPL = -lplc$(MOD_MAJOR_VERSION)
+
+ifeq ($(OS_ARCH), IRIX)
+    LDOPTS += -rpath $(PWD)/$(dist_libdir) -rdata_shared
+    # For 6.x machines, include this flag
+    ifeq ($(basename $(OS_RELEASE)),6)
+        ifeq ($(USE_N32),1)
+            LDOPTS += -n32
+        else
+            LDOPTS += -32
+        endif
+
+        ifeq ($(USE_PTHREADS), 1)
+            ifeq ($(OS_RELEASE), 6.2)
+                LDOPTS += -Wl,-woff,85
+            endif
+        endif
+    endif
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+    ifneq ($(OS_RELEASE), 4.1.3_U1)
+        ifdef NS_USE_GCC
+            LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir)
+        else
+            LDOPTS += -R $(PWD)/$(dist_libdir)
+        endif
+    endif
+
+# SunOS 5.5 needs to link with -lpthread, even though we already
+# linked with this system library when we built libnspr.so.
+    ifeq ($(OS_RELEASE), 5.5)
+        ifdef USE_PTHREADS
+            EXTRA_LIBS = -lpthread
+        endif
+    endif
+endif # SunOS
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+  LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib
+  LIBPL = $(dist_libdir)/plc$(MOD_MAJOR_VERSION).lib
+else
+  LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO
+  LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  LIBPL = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+LDOPTS += -Zomf -Zlinker /PM:VIO -lstdcpp
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+    LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir)
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+    LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib
+    ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1)
+        LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr
+        LIBPLC = -lplc$(MOD_MAJOR_VERSION)_shr
+    else
+        LDOPTS += -brtl
+        EXTRA_LIBS = -ldl
+    endif
+endif
+
+ifeq ($(OS_ARCH), Linux)
+    ifeq ($(OS_RELEASE), 1.2)
+        EXTRA_LIBS = -ldl
+    else
+        LDOPTS += -Xlinker -rpath $(PWD)/$(dist_libdir)
+        ifeq ($(USE_PTHREADS),1)
+            EXTRA_LIBS = -lpthread
+        endif
+    endif
+endif
+
+ifeq ($(OS_ARCH), NCR)
+# XXX: We see some strange problems when we link with libnspr.so.
+# So for now we use static libraries on NCR.  The shared library
+# stuff below is commented out.
+LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+LIBPL = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).a
+EXTRA_LIBS = -lsocket -lnsl -ldl
+
+# NCR needs to link against -lsocket -lnsl (and -lc, which is linked
+# implicitly by $(CC)) again even though we already linked with these
+# system libraries when we built libnspr.so.
+#EXTRA_LIBS = -lsocket -lnsl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+#export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), SCO_SV)
+# SCO Unix needs to link against -lsocket again even though we
+# already linked with these system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifneq ($(OS_RELEASE),4.2)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to 
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+	rm -f $@ $(AIX_TMP)
+	$(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+	$(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+	rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET),WIN16)
+	echo system windows         >w16link
+	echo option map             >>w16link
+	echo option stack=10K       >>w16link
+	echo option heapsize=32K    >>w16link
+	echo debug $(DEBUGTYPE) all >>w16link
+	echo name $@                >>w16link
+	echo file                   >>w16link
+	echo $<                     >>w16link
+	echo library                >>w16link
+	echo $(LIBPR),	            >>w16link
+	echo $(LIBPL),	            >>w16link
+	echo winsock.lib            >>w16link
+	wlink @w16link.
+else
+	link $(LDOPTS) $< $(LIBPR) $(LIBPL) wsock32.lib -out:$@
+endif
+else
+ifeq ($(OS_ARCH),OS2)
+	$(LINK) $(LDOPTS) $< $(LIBGC) $(LIBPLC) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS) -o $@
+else
+	$(CCC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPL) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/fileio.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/fileio.cpp
new file mode 100644
index 0000000..a01ea5e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/fileio.cpp
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* fileio.cpp - a test program */
+
+#include "rcfileio.h"
+
+#include <prlog.h>
+#include <prprf.h>
+
+#define DEFAULT_ITERATIONS 100
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    RCFileIO fd;
+    RCFileInfo info;
+    rv = fd.Open("filio.dat", PR_CREATE_FILE, 0666);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = fd.FileInfo(&info);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = fd.Delete("filio.dat");
+    PR_ASSERT(PR_SUCCESS == rv);
+    fd.Close();
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    return 0;
+}  /* main */
+
+/* interval.cpp */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/interval.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/interval.cpp
new file mode 100644
index 0000000..1223d67
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/interval.cpp
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* interval.cpp - a test program */
+
+#include "rclock.h"
+#include "rcthread.h"
+#include "rcinrval.h"
+#include "rccv.h"
+
+#include <prio.h>
+#include <prlog.h>
+#include <prprf.h>
+
+#define DEFAULT_ITERATIONS 100
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    RCLock ml;
+    PRStatus rv;
+    RCCondition cv(&ml);
+
+    RCInterval now, timeout, epoch, elapsed;
+    PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput);
+    PRIntn msecs, seconds, loops, iterations = DEFAULT_ITERATIONS;
+
+    /* slow, agonizing waits */
+    for (seconds = 0; seconds < 10; ++seconds)
+    {
+        timeout = RCInterval::FromSeconds(seconds);
+        cv.SetTimeout(timeout);
+        {
+            RCEnter lock(&ml);
+
+            epoch.SetToNow();
+
+            rv = cv.Wait();
+            PR_ASSERT(PR_SUCCESS == rv);
+
+            now = RCInterval(RCInterval::now);
+            elapsed = now - epoch;
+        }
+
+        PR_fprintf(
+            output, "Waiting %u seconds took %s%u milliseconds\n",
+            seconds, ((elapsed < timeout)? "**" : ""),
+            elapsed.ToMilliseconds());
+    }
+
+    /* more slow, agonizing sleeps */
+    for (seconds = 0; seconds < 10; ++seconds)
+    {
+        timeout = RCInterval::FromSeconds(seconds);
+        {
+            epoch.SetToNow();
+
+            rv = RCThread::Sleep(timeout);
+            PR_ASSERT(PR_SUCCESS == rv);
+
+            now = RCInterval(RCInterval::now);
+            elapsed = now - epoch;
+        }
+
+        PR_fprintf(
+            output, "Sleeping %u seconds took %s%u milliseconds\n",
+            seconds, ((elapsed < timeout)? "**" : ""),
+            elapsed.ToMilliseconds());
+    }
+
+    /* fast, spritely little devils */
+    for (msecs = 10; msecs < 100; msecs += 10)
+    {
+        timeout = RCInterval::FromMilliseconds(msecs);
+        cv.SetTimeout(timeout);
+        {
+            RCEnter lock(&ml);
+
+            epoch.SetToNow();
+
+            for (loops = 0; loops < iterations; ++loops)
+            {
+                rv = cv.Wait();
+                PR_ASSERT(PR_SUCCESS == rv);
+            }
+
+            now = RCInterval(RCInterval::now);
+            elapsed = now - epoch;
+        }
+        elapsed /= iterations;
+
+        PR_fprintf(
+            output, "Waiting %u msecs took %s%u milliseconds average\n",
+            msecs, ((elapsed < timeout)? "**" : ""), elapsed.ToMilliseconds());
+    }
+    return 0;
+}  /* main */
+
+/* interval.cpp */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/ranfile.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/ranfile.cpp
new file mode 100644
index 0000000..b745b15
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/ranfile.cpp
@@ -0,0 +1,432 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Contact:     AOF<mailto:freier@netscape.com>
+**
+** Name: ranfile.c
+**
+** Description: Test to hammer on various components of NSPR
+** Modification History:
+** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include <plgetopt.h>
+#include <prprf.h>
+#include <prio.h>
+
+#include "rccv.h"
+#include "rcthread.h"
+#include "rcfileio.h"
+#include "rclock.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static PRFileDesc *output;
+static PRIntn debug_mode = 0;
+static PRIntn failed_already = 0;
+
+class HammerData
+{
+public:
+    typedef enum {
+        sg_go, sg_stop, sg_done} Action;
+    typedef enum {
+        sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem;
+
+	virtual ~HammerData();
+	HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip);
+    virtual PRUint32 Random();
+
+    Action action;
+    Problem problem;
+    PRUint32 writes;
+    RCInterval timein;
+friend class Hammer;
+private:
+    RCLock *ml;
+    RCCondition *cv;
+    PRUint32 limit;
+
+    PRFloat64 seed;
+};  /* HammerData */
+
+class Hammer: public HammerData, public RCThread
+{
+public:
+    virtual ~Hammer();
+    Hammer(RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip);
+
+private:
+    void RootFunction();
+
+};
+
+static PRInt32 pageSize = 1024;
+static const char* baseName = "./";
+static const char *programName = "Random File";
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Random
+** DESCRIPTION:
+**   Generate a pseudo-random number
+** INPUTS:      None
+** OUTPUTS:     None
+** RETURN:      A pseudo-random unsigned number, 32-bits wide
+** SIDE EFFECTS:
+**      Updates random seed (a static)
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:
+**      Uses the current interval timer value, promoted to a 64 bit
+**      float as a multiplier for a static residue (which begins
+**      as an uninitialized variable). The result is bits [16..48)
+**      of the product. Seed is then updated with the return value
+**      promoted to a float-64.
+***********************************************************************/
+PRUint32 HammerData::Random()
+{
+    PRUint32 rv;
+    PRUint64 shift;
+    RCInterval now = RCInterval(RCInterval::now);
+    PRFloat64 random = seed * (PRFloat64)((PRIntervalTime)now);
+    LL_USHR(shift, *((PRUint64*)&random), 16);
+    LL_L2UI(rv, shift);
+    seed = (PRFloat64)rv;
+    return rv;
+}  /* HammerData::Random */
+
+Hammer::~Hammer() { }
+
+Hammer::Hammer(
+    RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip):
+	HammerData(lock, cond, clip), RCThread(scope, RCThread::joinable, 0) { }
+
+HammerData::~HammerData() { }
+
+HammerData::HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip)
+{
+    ml = lock;
+    cv = cond;
+    writes = 0;
+    limit = clip;
+    seed = 0x58a9382;
+    action = HammerData::sg_go;
+    problem = HammerData::sg_okay;
+    timein = RCInterval(RCInterval::now);
+}  /* HammerData::HammerData */
+
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Hammer::RootFunction
+** DESCRIPTION:
+**   Hammer on the file I/O system
+** INPUTS:      A pointer to the thread's private data
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      Creates, accesses and deletes a file
+** RESTRICTIONS:
+**      (Currently) must have file create permission in "/usr/tmp".
+** MEMORY:      NA
+** ALGORITHM:
+**      This function is a root of a thread
+**      1) Creates a (hopefully) unique file in /usr/tmp/
+**      2) Writes a zero to a random number of sequential pages
+**      3) Closes the file
+**      4) Reopens the file
+**      5) Seeks to a random page within the file
+**      6) Writes a one byte on that page
+**      7) Repeat steps [5..6] for each page in the file
+**      8) Close and delete the file
+**      9) Repeat steps [1..8] until told to stop
+**     10) Notify complete and return
+***********************************************************************/
+void Hammer::RootFunction()
+{
+    PRUint32 index;
+    RCFileIO file;
+    char filename[30];
+    const char zero = 0;
+    PRStatus rv = PR_SUCCESS;
+
+    limit = (Random() % limit) + 1;
+
+    (void)sprintf(filename, "%ssg%04p.dat", baseName, this);
+
+    if (debug_mode) PR_fprintf(output, "Starting work on %s\n", filename);
+
+    while (PR_TRUE)
+    {
+        PRUint64 bytes;
+        PRUint32 minor = (Random() % limit) + 1;
+        PRUint32 random = (Random() % limit) + 1;
+        PRUint32 pages = (Random() % limit) + 10;
+        while (minor-- > 0)
+        {
+            problem = sg_okay;
+            if (action != sg_go) goto finished;
+            problem = sg_open;
+            rv = file.Open(filename, PR_RDWR|PR_CREATE_FILE, 0666);
+            if (PR_FAILURE == rv) goto finished;
+            for (index = 0; index < pages; index++)
+            {
+                problem = sg_okay;
+                if (action != sg_go) goto close;
+                problem = sg_seek;
+                bytes = file.Seek(pageSize * index, RCFileIO::set);
+                if (bytes != pageSize * index) goto close;
+                problem = sg_write;
+                bytes = file.Write(&zero, sizeof(zero));
+                if (bytes <= 0) goto close;
+                writes += 1;
+            }
+            problem = sg_close;
+            rv = file.Close();
+            if (rv != PR_SUCCESS) goto purge;
+
+            problem = sg_okay;
+            if (action != sg_go) goto purge;
+
+            problem = sg_open;
+            rv = file.Open(filename, PR_RDWR, 0666);
+            if (PR_FAILURE == rv) goto finished;
+            for (index = 0; index < pages; index++)
+            {
+                problem = sg_okay;
+                if (action != sg_go) goto close;
+                problem = sg_seek;
+                bytes = file.Seek(pageSize * index, RCFileIO::set);
+                if (bytes != pageSize * index) goto close;
+                problem = sg_write;
+                bytes = file.Write(&zero, sizeof(zero));
+                if (bytes <= 0) goto close;
+                writes += 1;
+                random = (random + 511) % pages;
+            }
+            problem = sg_close;
+            rv = file.Close();
+            if (rv != PR_SUCCESS) goto purge;
+            problem = sg_delete;
+            rv = file.Delete(filename);
+            if (rv != PR_SUCCESS) goto finished;
+       }
+    }
+
+close:
+    (void)file.Close();
+purge:
+    (void)file.Delete(filename);
+finished:
+    RCEnter scope(ml);
+    action = HammerData::sg_done;
+    cv->Notify();
+
+    if (debug_mode) PR_fprintf(output, "Ending work on %s\n", filename);
+
+    return;
+}  /* Hammer::RootFunction */
+
+static Hammer* hammer[100];
+/***********************************************************************
+** PRIVATE FUNCTION:    main
+** DESCRIPTION:
+**   Hammer on the file I/O system
+** INPUTS:      The usual argc and argv
+**              argv[0] - program name (not used)
+**              argv[1] - the number of virtual_procs to execute the major loop
+**              argv[2] - the number of threads to toss into the batch
+**              argv[3] - the clipping number applied to randoms
+**              default values: max_virtual_procs = 2, threads = 10, limit = 57
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      Creates, accesses and deletes lots of files
+** RESTRICTIONS:
+**      (Currently) must have file create permission in "/usr/tmp".
+** MEMORY:      NA
+** ALGORITHM:
+**      1) Fork a "Thread()"
+**      2) Wait for 'interleave' seconds
+**      3) For [0..'threads') repeat [1..2]
+**      4) Mark all objects to stop
+**      5) Collect the threads, accumulating the results
+**      6) For [0..'max_virtual_procs') repeat [1..5]
+**      7) Print accumulated results and exit
+**
+**      Characteristic output (from IRIX)
+**          Random File: Using max_virtual_procs = 2, threads = 10, limit = 57
+**          Random File: [min [avg] max] writes/sec average
+***********************************************************************/
+PRIntn main (PRIntn argc, char *argv[])
+{
+    RCLock ml;
+	PLOptStatus os;
+    RCCondition cv(&ml);
+    PRUint32 writesMax = 0, durationTot = 0;
+    RCThread::Scope thread_scope = RCThread::local;
+    PRUint32 writes, writesMin = 0x7fffffff, writesTot = 0;
+    PRIntn active, poll, limit = 0, max_virtual_procs = 0, threads = 0, virtual_procs;
+    RCInterval interleave(RCInterval::FromMilliseconds(10000)), duration(0);
+
+    const char *where[] = {"okay", "open", "close", "delete", "write", "seek"};
+
+	PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+	case 0:
+		baseName = opt->value;
+		break;
+        case 'G':  /* global threads */
+		thread_scope = RCThread::global;
+            break;
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'l':  /* limiting number */
+			limit = atoi(opt->value);
+            break;
+        case 't':  /* number of threads */
+			threads = atoi(opt->value);
+            break;
+        case 'i':  /* iteration counter */
+			max_virtual_procs = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+    output = PR_GetSpecialFD(PR_StandardOutput);
+
+ /* main test */
+ 
+    cv.SetTimeout(interleave);
+	
+    if (max_virtual_procs == 0) max_virtual_procs = 2;
+    if (limit == 0) limit = 57;
+    if (threads == 0) threads = 10;
+
+    if (debug_mode) PR_fprintf(output,
+        "%s: Using %d virtual processors, %d threads, limit = %d and %s threads\n",
+        programName, max_virtual_procs, threads, limit,
+        (thread_scope == RCThread::local) ? "LOCAL" : "GLOBAL");
+
+    for (virtual_procs = 0; virtual_procs < max_virtual_procs; ++virtual_procs)
+    {
+        if (debug_mode)
+			PR_fprintf(output,
+				"%s: Setting number of virtual processors to %d\n",
+				programName, virtual_procs + 1);
+		RCPrimordialThread::SetVirtualProcessors(virtual_procs + 1);
+        for (active = 0; active < threads; active++)
+        {
+            hammer[active] = new Hammer(thread_scope, &ml, &cv, limit);
+            hammer[active]->Start();  /* then make it roll */
+            RCThread::Sleep(interleave);  /* start them slowly */
+        }
+
+        /*
+         * The last thread started has had the opportunity to run for
+         * 'interleave' seconds. Now gather them all back in.
+         */
+        {
+            RCEnter scope(&ml);
+            for (poll = 0; poll < threads; poll++)
+            {
+                if (hammer[poll]->action == HammerData::sg_go)  /* don't overwrite done */
+                    hammer[poll]->action = HammerData::sg_stop;  /* ask him to stop */
+            }
+        }
+
+        while (active > 0)
+        {
+            for (poll = 0; poll < threads; poll++)
+            {
+                ml.Acquire();
+                while (hammer[poll]->action < HammerData::sg_done) cv.Wait();
+                ml.Release();
+
+                if (hammer[poll]->problem == HammerData::sg_okay)
+                {
+                    duration = RCInterval(RCInterval::now) - hammer[poll]->timein;
+                    writes = hammer[poll]->writes * 1000 / duration;
+                    if (writes < writesMin)  writesMin = writes;
+                    if (writes > writesMax) writesMax = writes;
+                    writesTot += hammer[poll]->writes;
+                    durationTot += duration;
+                }
+                else
+                {
+                    if (debug_mode) PR_fprintf(output,
+                        "%s: test failed %s after %ld seconds\n",
+                        programName, where[hammer[poll]->problem], duration);
+					else failed_already=1;
+                }
+                active -= 1;  /* this is another one down */
+                (void)hammer[poll]->Join();
+                hammer[poll] = NULL;
+            }
+        }
+        if (debug_mode) PR_fprintf(output,
+            "%s: [%ld [%ld] %ld] writes/sec average\n",
+            programName, writesMin,
+            writesTot * 1000 / durationTot, writesMax);
+    }
+
+        failed_already |= (PR_FAILURE == RCPrimordialThread::Cleanup());
+	    PR_fprintf(output, "%s\n", (failed_already) ? "FAIL\n" : "PASS\n");
+		return failed_already;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/switch.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/switch.cpp
new file mode 100644
index 0000000..fddc580
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/switch.cpp
@@ -0,0 +1,266 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:            switch.cpp
+** Description:     trying to time context switches
+*/
+
+#include "rccv.h"
+#include "rcinrval.h"
+#include "rclock.h"
+#include "rcthread.h"
+
+#include <prio.h>
+#include <prlog.h>
+#include <prprf.h>
+#include <plerror.h>
+#include <plgetopt.h>
+
+#include <stdlib.h>
+
+#define INNER_LOOPS 100
+#define DEFAULT_LOOPS 100
+#define DEFAULT_THREADS 10
+
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE;
+
+class Home: public RCCondition
+{
+public:
+    virtual ~Home();
+    Home(Home *link, RCLock* ml);
+
+public:
+    Home *next;
+    RCLock* ml;
+    PRBool twiddle;
+};  /* Home */
+
+Home::~Home() { }
+
+Home::Home(Home *link, RCLock* lock): RCCondition(lock)
+{
+    ml = lock;
+    next = link;
+    twiddle = PR_FALSE;
+}  /* Home::Home */
+
+class Shared: public Home, public RCThread
+{
+public:
+    Shared(RCThread::Scope scope, Home* link, RCLock* ml);
+
+private:
+    ~Shared();
+    void RootFunction();
+};  /* Shared */
+
+Shared::Shared(RCThread::Scope scope, Home* link, RCLock* lock):
+    Home(link, lock), RCThread(scope, RCThread::joinable) { }
+
+Shared::~Shared() { }
+
+void Shared::RootFunction()
+{
+    PRStatus status = PR_SUCCESS;
+    while (PR_SUCCESS == status)
+    {
+        RCEnter entry(ml);
+        while (twiddle && (PR_SUCCESS == status)) status = Wait();
+		if (verbosity) PR_fprintf(debug_out, "+");
+        twiddle = PR_TRUE;
+        next->twiddle = PR_FALSE;
+        next->Notify();
+    }
+}  /* Shared::RootFunction */
+
+static void Help(void)
+{
+    debug_out = PR_STDOUT;
+
+    PR_fprintf(
+		debug_out, "Usage: >./switch [-d] [-c n] [-t n] [-T n] [-G]\n");
+    PR_fprintf(
+		debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
+    PR_fprintf(
+		debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
+    PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-G n\tglobal threads only (default: FALSE)\n");
+    PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
+}  /* Help */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+	PLOptStatus os;
+    PRStatus status;
+    PRBool help = PR_FALSE;
+    PRUintn concurrency = 1;
+    RCThread::Scope thread_scope = RCThread::local;
+    PRUintn thread_count, inner_count, loop_count, average;
+    PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'v':  /* verbose mode */
+			verbosity = PR_TRUE;
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+        case 'c':  /* loop counter */
+			loop_limit = atoi(opt->value);
+            break;
+        case 't':  /* thread limit */
+			thread_limit = atoi(opt->value);
+            break;
+        case 'C':  /* Concurrency limit */
+			concurrency = atoi(opt->value);
+            break;
+        case 'G':  /* global threads only */
+			thread_scope = RCThread::global;
+            break;
+        case 'h':  /* help message */
+			Help();
+			help = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (help) return -1;
+
+	if (PR_TRUE == debug_mode)
+	{
+		debug_out = PR_STDOUT;
+		PR_fprintf(debug_out, "Test parameters\n");
+		PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit);
+		PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit);
+		PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
+		PR_fprintf(
+			debug_out, "\tThread type: %s\n",
+			(PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
+	}
+
+    /*
+    ** The interesting part starts here
+    */
+    RCLock lock;
+    Shared* shared;
+    Home home(NULL, &lock);
+    Home* link = &home;
+    RCInterval timein, timeout = 0;
+
+    /* Build up the string of objects */
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        shared = new Shared(thread_scope, link, &lock);
+        shared->Start();  /* make it run */
+        link = (Home*)shared;
+	}
+
+    /* Pass the message around the horn a few times */
+    for (loop_count = 1; loop_count <= loop_limit; ++loop_count)
+    {
+		timein.SetToNow();
+		for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count)
+		{
+			RCEnter entry(&lock);
+			home.twiddle = PR_TRUE;
+			shared->twiddle = PR_FALSE;
+			shared->Notify();
+			while (home.twiddle)
+            {
+				failed = (PR_FAILURE == home.Wait()) ? PR_TRUE : PR_FALSE;
+            }
+		}
+		timeout += (RCInterval(RCInterval::now) - timein);
+	}
+
+    /* Figure out how well we did */
+	if (debug_mode)
+	{
+		average = timeout.ToMicroseconds()
+			/ (INNER_LOOPS * loop_limit * thread_count);
+		PR_fprintf(
+			debug_out, "Average switch times %d usecs for %d threads\n",
+            average, thread_limit);
+	}
+
+    /* Start reclamation process */
+    link = shared;
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        if (&home == link) break;
+        status = ((Shared*)link)->Interrupt();
+		if (PR_SUCCESS != status)
+        {
+            failed = PR_TRUE;
+            if (debug_mode)
+			    PL_FPrintError(debug_out, "Failed to interrupt");
+        }
+		link = link->next; 
+    }
+
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        link = shared->next;
+        status = shared->Join();
+		if (PR_SUCCESS != status)
+		{
+            failed = PR_TRUE;
+            if (debug_mode)
+			    PL_FPrintError(debug_out, "Failed to join");
+        }
+        if (&home == link) break;
+        shared = (Shared*)link;
+    }
+
+    PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n"));
+
+    failed |= (PR_SUCCESS == RCPrimordialThread::Cleanup());
+
+    return ((failed) ? 1 : 0);
+}  /* main */
+
+/* switch.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/thread.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/thread.cpp
new file mode 100644
index 0000000..801eee0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/thread.cpp
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* thread.cpp - a test program */
+
+#include "rcthread.h"
+
+#include <prlog.h>
+
+#include <stdio.h>
+
+class TestThread: public RCThread
+{
+public:
+    TestThread(RCThread::State state, PRIntn count);
+
+    virtual void RootFunction();
+
+protected:
+    virtual ~TestThread();
+
+private:
+    PRUint32 mydata;
+};
+
+TestThread::~TestThread() { }
+
+TestThread::TestThread(RCThread::State state, PRIntn count):
+    RCThread(RCThread::global, state, 0) { mydata = count; }
+
+void TestThread::RootFunction()
+{
+    SetPriority(RCThread::high);
+    printf("TestThread::RootFunction %d did it\n", mydata);
+}  /* TestThread::RootFunction */
+
+class Foo1
+{
+public:
+    Foo1();
+    virtual ~Foo1();
+
+    TestThread *thread;
+    PRIntn data;
+};
+
+Foo1::Foo1() 
+{
+    data = 0xafaf;
+    thread = new TestThread(RCThread::joinable, 0xafaf);
+    thread->Start();
+}
+
+Foo1::~Foo1()
+{
+    PRStatus rv = thread->Join();
+    PR_ASSERT(PR_SUCCESS == rv);
+}  /* Foo1::~Foo1 */
+
+PRIntn main(PRIntn argc, char **agrv)
+{
+    PRStatus status;
+    PRIntn count = 100;
+    RCThread *thread[10];
+    while (--count > 0)
+    {
+        TestThread *thread = new TestThread(RCThread::joinable, count);
+        status = thread->Start();  /* have to remember to start it */
+        PR_ASSERT(PR_SUCCESS == status);
+        status = thread->Join();  /* this should work */
+        PR_ASSERT(PR_SUCCESS == status);
+    }
+    while (++count < 100)
+    {
+        TestThread *thread = new TestThread(RCThread::unjoinable, count);
+        status = thread->Start();  /* have to remember to start it */
+        PR_ASSERT(PR_SUCCESS == status);
+    }
+
+    {
+        Foo1 *foo1 = new Foo1();
+        PR_ASSERT(NULL != foo1);
+        delete foo1;
+    }
+
+    {
+        for (count = 0; count < 10; ++count)
+        {
+            thread[count] = new TestThread( RCThread::joinable, count);
+            status = thread[count]->Start();  /* have to remember to start it */
+            PR_ASSERT(PR_SUCCESS == status);
+        }
+        for (count = 0; count < 10; ++count)
+        {
+            PRStatus rv = thread[count]->Join();
+            PR_ASSERT(PR_SUCCESS == rv);
+        }
+    }
+
+    (void)RCPrimordialThread::Cleanup();
+
+    return 0;
+}  /* main */
+
+/* thread.cpp */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/time.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/time.cpp
new file mode 100644
index 0000000..c0a9c3e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/time.cpp
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* time.cpp - a test program */
+
+#include "rctime.h"
+
+#include <prlog.h>
+#include <prprf.h>
+
+#define DEFAULT_ITERATIONS 100
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    RCTime unitialized;
+    RCTime now(PR_Now());
+    RCTime current(RCTime::now);
+    PRTime time = current;
+
+    unitialized = now;
+    now.Now();
+
+    return 0;
+}  /* main */
+
+/* time.cpp */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/tpd.cpp b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/tpd.cpp
new file mode 100644
index 0000000..6e3dd95
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/cplus/tests/tpd.cpp
@@ -0,0 +1,368 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        tpd.cpp
+** Description: Exercising the thread private data bailywick.
+*/
+
+#include "prlog.h"
+#include "prprf.h"
+#include "rcthread.h"
+
+#include <string.h>
+
+#include "plgetopt.h"
+
+/*
+** class MyThread
+*/
+class MyThread: public RCThread
+{
+public:
+    MyThread();
+
+private:
+    ~MyThread();
+    void RootFunction();
+};  /* MyThread */
+
+/*
+** class MyPrivateData
+*/
+class MyPrivateData: public RCThreadPrivateData
+{
+public:
+    virtual ~MyPrivateData();
+
+    MyPrivateData();
+    MyPrivateData(char*);
+    MyPrivateData(const MyPrivateData&);
+
+    void Release();
+
+private:
+    char *string;
+};  /* MyPrivateData */
+
+static PRUintn key[128];
+static PRIntn debug = 0;
+static PRBool failed = PR_FALSE;
+static PRBool should = PR_TRUE;
+static PRBool did = PR_TRUE;
+static PRFileDesc *fout = NULL;
+
+static void PrintProgress(PRIntn line)
+{
+    failed = failed || (should && !did);
+    failed = failed || (!should && did);
+    if (debug > 0)
+    {
+        PR_fprintf(
+            fout, "@ line %d destructor should %shave been called and was%s\n",
+            line, ((should) ? "" : "NOT "), ((did) ? "" : " NOT"));
+    }
+}  /* PrintProgress */
+
+static void MyAssert(const char *expr, const char *file, PRIntn line)
+{
+    if (debug > 0)
+        (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
+}  /* MyAssert */
+
+#define MY_ASSERT(_expr) \
+    ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__))
+
+int main(PRIntn argc, char *argv[])
+{
+    PRStatus rv;
+    PRUintn keys;
+    MyThread *thread;
+    const RCThreadPrivateData *pd;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    RCThread *primordial = RCThread::WrapPrimordialThread();
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            debug = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    fout = PR_STDOUT;
+
+    MyPrivateData extension = MyPrivateData("EXTENSION");
+    MyPrivateData key_string[] = {
+        "Key #0", "Key #1", "Key #2", "Key #3",
+        "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
+    
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = RCThread::NewPrivateIndex(&key[keys]);
+        key[keys + 4] = key[keys] + 4;
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* the first four should be bu null, the last four undefined and null */
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 8; ++keys)
+    {
+        pd = RCThread::GetPrivateData(key[keys]);
+        MY_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    /* initially set private data for new keys */
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = RCThread::SetPrivateData(key[keys], &key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* re-assign the private data, albeit the same content */    
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        pd = RCThread::GetPrivateData(key[keys]);
+        PR_ASSERT(NULL != pd);
+        rv = RCThread::SetPrivateData(key[keys], &key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* set private to <empty> */
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = RCThread::SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* should all be null now */
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        pd = RCThread::GetPrivateData(key[keys]);
+        PR_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    /* allocate another batch of keys and assign data to them */
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = RCThread::NewPrivateIndex(&key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+        rv = RCThread::SetPrivateData(key[keys], &extension);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* set all the extended slots to <empty> */
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = RCThread::SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* set all the extended slots to <empty> again (noop) */
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = RCThread::SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+
+    if (debug) PR_fprintf(fout, "Creating thread\n");
+    thread = new MyThread();
+    if (debug) PR_fprintf(fout, "Starting thread\n");
+    thread->Start();
+    if (debug) PR_fprintf(fout, "Joining thread\n");
+    (void)thread->Join();
+    if (debug) PR_fprintf(fout, "Joined thread\n");
+
+    failed |= (PR_FAILURE == RCPrimordialThread::Cleanup());
+
+    (void)PR_fprintf(
+        fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
+
+    return (failed) ? 1 : 0;
+
+}  /* main */
+
+/*
+** class MyPrivateData
+*/
+MyPrivateData::~MyPrivateData()
+{
+    PR_fprintf(
+        fout, "MyPrivateData::~MyPrivateData[%s]\n",
+        (NULL != string) ? string : "NULL");
+}  /* MyPrivateData::~MyPrivateData */
+
+MyPrivateData::MyPrivateData(): RCThreadPrivateData()
+{
+    PR_fprintf(fout, "MyPrivateData::MyPrivateData()\n");
+    string = NULL;
+}  /* MyPrivateData::MyPrivateData */
+
+MyPrivateData::MyPrivateData(char* data): RCThreadPrivateData()
+{
+    PR_fprintf(fout, "MyPrivateData::MyPrivateData(char* data)\n");
+    string = data;
+}  /* MyPrivateData:: MyPrivateData */
+
+MyPrivateData::MyPrivateData(const MyPrivateData& him): RCThreadPrivateData(him)
+{
+    PR_fprintf(fout, "MyPrivateData::MyPrivateData(const MyPrivateData& him)\n");
+    string = him.string;
+}  /* MyPrivateData:: MyPrivateData */
+
+void MyPrivateData::Release()
+{
+    if (should) did = PR_TRUE;
+    else failed = PR_TRUE;
+}  /* MyPrivateData::operator= */
+
+/*
+** class MyThread
+*/
+MyThread::~MyThread() { }
+MyThread::MyThread(): RCThread(RCThread::global, RCThread::joinable) { }
+
+
+void MyThread::RootFunction()
+{
+    PRStatus rv;
+    PRUintn keys;
+    const RCThreadPrivateData *pd;
+    
+    MyPrivateData extension = MyPrivateData("EXTENSION");
+    MyPrivateData key_string[] = {
+        "Key #0", "Key #1", "Key #2", "Key #3",
+        "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
+    
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 8; ++keys)
+    {
+        pd = GetPrivateData(key[keys]);
+        MY_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = SetPrivateData(keys, &key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+#if !defined(DEBUG)
+    did = should = PR_FALSE;
+    for (keys = 4; keys < 8; ++keys)
+    {
+        rv = SetPrivateData(keys, &key_string[keys]);
+        MY_ASSERT(PR_FAILURE == rv);
+    }
+    PrintProgress(__LINE__);
+#endif
+    
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = SetPrivateData(key[keys], &key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = SetPrivateData(key[keys], &extension);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+}  /* MyThread::RootFunction */
+
+/* tpd.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/Makefile.in
new file mode 100644
index 0000000..e7df1f0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/Makefile.in
@@ -0,0 +1,89 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+# Disable optimization of the nspr on SunOS4.1.3
+ifeq ($(OS_ARCH),SunOS)
+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  \
+	$(NULL)
+
+ifndef USE_PTHREADS
+    CSRCS += \
+	    prdir.c \
+	    prfile.c \
+	    prio.c \
+	    prsocket.c \
+	    $(NULL)
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prdir.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prdir.c
new file mode 100644
index 0000000..8679c9d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prdir.c
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Roy Yokoyama <yokoyama@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name)
+{
+    PRDir *dir;
+    PRStatus sts;
+
+    dir = PR_NEW(PRDir);
+    if (dir) {
+        sts = _PR_MD_OPEN_DIR(&dir->md,name);
+        if (sts != PR_SUCCESS) {
+            PR_DELETE(dir);
+            return NULL;
+        }
+    } else {
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	}
+    return dir;
+}
+
+PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags)
+{
+    /* _MD_READ_DIR return a char* to the name; allocation in machine-dependent code */
+    char* name = _PR_MD_READ_DIR(&dir->md, flags);
+    dir->d.name = name;
+    return name ? &dir->d : NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir)
+{
+PRInt32 rv;
+
+    if (dir) {
+        rv = _PR_MD_CLOSE_DIR(&dir->md);
+		PR_DELETE(dir);
+		if (rv < 0) {
+			return PR_FAILURE;
+		} else
+			return PR_SUCCESS;
+    }
+	return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode)
+{
+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
+		return PR_SUCCESS;
+}
+
+#ifdef MOZ_UNICODE
+/*
+ *  UTF16 Interface
+ */
+PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name)
+{ 
+    PRDirUTF16 *dir;
+    PRStatus sts;
+
+    dir = PR_NEW(PRDirUTF16);
+    if (dir) {
+        sts = _PR_MD_OPEN_DIR_UTF16(&dir->md,name);
+        if (sts != PR_SUCCESS) {
+            PR_DELETE(dir);
+            return NULL;
+        }
+    } else {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return dir;
+}  
+ 
+PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags)
+{ 
+    /*
+     * _MD_READ_DIR_UTF16 return a PRUnichar* to the name; allocation in
+     * machine-dependent code
+     */
+    PRUnichar* name = _PR_MD_READ_DIR_UTF16(&dir->md, flags);
+    dir->d.name = name;
+    return name ? &dir->d : NULL;
+} 
+ 
+PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir)
+{ 
+    PRInt32 rv; 
+
+    if (dir) {
+        rv = _PR_MD_CLOSE_DIR_UTF16(&dir->md);
+        PR_DELETE(dir);
+        if (rv < 0)
+	    return PR_FAILURE;
+        else
+	    return PR_SUCCESS;
+    } 
+    return PR_SUCCESS;
+}
+
+#endif /* MOZ_UNICODE */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prfdcach.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prfdcach.c
new file mode 100644
index 0000000..ca09cb4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prfdcach.c
@@ -0,0 +1,324 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+
+/*****************************************************************************/
+/*****************************************************************************/
+/************************** File descriptor caching **************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+/*
+** This code is built into debuggable versions of NSPR to assist in
+** finding misused file descriptors. Since file descritors (PRFileDesc)
+** are identified by a pointer to their structure, they can be the
+** target of dangling references. Furthermore, NSPR caches and tries
+** to aggressively reuse file descriptors, leading to more ambiguity.
+** The following code will allow a debugging client to set environment
+** variables and control the number of file descriptors that will be
+** preserved before they are recycled. The environment variables are
+** NSPR_FD_CACHE_SIZE_LOW and NSPR_FD_CACHE_SIZE_HIGH. The former sets
+** the number of descriptors NSPR will allocate before beginning to
+** recycle. The latter is the maximum number permitted in the cache
+** (exclusive of those in use) at a time.
+*/
+typedef struct _PR_Fd_Cache
+{
+    PRLock *ml;
+    PRIntn count;
+    PRStack *stack;
+    PRFileDesc *head, *tail;
+    PRIntn limit_low, limit_high;
+} _PR_Fd_Cache;
+
+static _PR_Fd_Cache _pr_fd_cache;
+static PRFileDesc **stack2fd = &(((PRFileDesc*)NULL)->higher);
+
+
+/*
+** Get a FileDescriptor from the cache if one exists. If not allocate
+** a new one from the heap.
+*/
+PRFileDesc *_PR_Getfd(void)
+{
+    PRFileDesc *fd;
+    /*
+    ** $$$
+    ** This may look a little wasteful. We'll see. Right now I want to
+    ** be able to toggle between caching and not at runtime to measure
+    ** the differences. If it isn't too annoying, I'll leave it in.
+    ** $$$$
+    **
+    ** The test is against _pr_fd_cache.limit_high. If that's zero,
+    ** we're not doing the extended cache but going for performance.
+    */
+    if (0 == _pr_fd_cache.limit_high)
+    {
+        PRStackElem *pop;
+        PR_ASSERT(NULL != _pr_fd_cache.stack);
+        pop = PR_StackPop(_pr_fd_cache.stack);
+        if (NULL == pop) goto allocate;
+        fd = (PRFileDesc*)((PRPtrdiff)pop - (PRPtrdiff)stack2fd);
+    }
+    else
+    {
+        do
+        {
+            if (NULL == _pr_fd_cache.head) goto allocate;  /* nothing there */
+            if (_pr_fd_cache.count < _pr_fd_cache.limit_low) goto allocate;
+
+            /* we "should" be able to extract an fd from the cache */
+            PR_Lock(_pr_fd_cache.ml);  /* need the lock to do this safely */
+            fd = _pr_fd_cache.head;  /* protected extraction */
+            if (NULL == fd)  /* unexpected, but not fatal */
+            {
+                PR_ASSERT(0 == _pr_fd_cache.count);
+                PR_ASSERT(NULL == _pr_fd_cache.tail);
+            }
+            else
+            {
+                _pr_fd_cache.count -= 1;
+                _pr_fd_cache.head = fd->higher;
+                if (NULL == _pr_fd_cache.head)
+                {
+                    PR_ASSERT(0 == _pr_fd_cache.count);
+                    _pr_fd_cache.tail = NULL;
+                }
+                PR_ASSERT(&_pr_faulty_methods == fd->methods);
+                PR_ASSERT(PR_INVALID_IO_LAYER == fd->identity);
+                PR_ASSERT(_PR_FILEDESC_FREED == fd->secret->state);
+            }
+            PR_Unlock(_pr_fd_cache.ml);
+
+        } 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, sizeof(PRFilePrivate));
+    return fd;
+
+allocate:
+    fd = PR_NEW(PRFileDesc);
+    if (NULL != fd)
+    {
+        fd->secret = PR_NEW(PRFilePrivate);
+        if (NULL == fd->secret) PR_DELETE(fd);
+    }
+    if (NULL != fd) goto finished;
+    else return NULL;
+
+}  /* _PR_Getfd */
+
+/*
+** Return a file descriptor to the cache unless there are too many in
+** there already. If put in cache, clear the fields first.
+*/
+void _PR_Putfd(PRFileDesc *fd)
+{
+    PR_ASSERT(PR_NSPR_IO_LAYER == fd->identity);
+    fd->methods = &_pr_faulty_methods;
+    fd->identity = PR_INVALID_IO_LAYER;
+    fd->secret->state = _PR_FILEDESC_FREED;
+
+    if (0 == _pr_fd_cache.limit_high)
+    {
+        PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher));
+    }
+    else
+    {
+        if (_pr_fd_cache.count > _pr_fd_cache.limit_high)
+        {
+            PR_Free(fd->secret);
+            PR_Free(fd);
+        }
+        else
+        {
+            PR_Lock(_pr_fd_cache.ml);
+            if (NULL == _pr_fd_cache.tail)
+            {
+                PR_ASSERT(0 == _pr_fd_cache.count);
+                PR_ASSERT(NULL == _pr_fd_cache.head);
+                _pr_fd_cache.head = _pr_fd_cache.tail = fd;
+            }
+            else
+            {
+                PR_ASSERT(NULL == _pr_fd_cache.tail->higher);
+                _pr_fd_cache.tail->higher = fd;
+                _pr_fd_cache.tail = fd;  /* new value */
+            }
+            fd->higher = NULL;  /* always so */
+            _pr_fd_cache.count += 1;  /* count the new entry */
+            PR_Unlock(_pr_fd_cache.ml);
+        }
+    }
+}  /* _PR_Putfd */
+
+PR_IMPLEMENT(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high)
+{
+    /*
+    ** This can be called at any time, may adjust the cache sizes,
+    ** turn the caches off, or turn them on. It is not dependent
+    ** on the compilation setting of DEBUG.
+    */
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (low > high) low = high;  /* sanity check the params */
+    
+    PR_Lock(_pr_fd_cache.ml);
+    if (0 == high)  /* shutting down or staying down */
+    {
+        if (0 != _pr_fd_cache.limit_high)  /* shutting down */
+        {
+            _pr_fd_cache.limit_high = 0;  /* stop use */
+            /*
+            ** Hold the lock throughout - nobody's going to want it
+            ** other than another caller to this routine. Just don't
+            ** let that happen.
+            **
+            ** Put all the cached fds onto the new cache.
+            */
+            while (NULL != _pr_fd_cache.head)
+            {
+                PRFileDesc *fd = _pr_fd_cache.head;
+                _pr_fd_cache.head = fd->higher;
+                PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher));
+            }
+            _pr_fd_cache.limit_low = 0;
+            _pr_fd_cache.tail = NULL;
+            _pr_fd_cache.count = 0;
+        }
+    }
+    else  /* starting up or just adjusting parameters */
+    {
+        PRBool was_using_stack = (0 == _pr_fd_cache.limit_high);
+        _pr_fd_cache.limit_low = low;
+        _pr_fd_cache.limit_high = high;
+        if (was_using_stack)  /* was using stack - feed into cache */
+        {
+            PRStackElem *pop;
+            while (NULL != (pop = PR_StackPop(_pr_fd_cache.stack)))
+            {
+                PRFileDesc *fd = (PRFileDesc*)
+                    ((PRPtrdiff)pop - (PRPtrdiff)stack2fd);
+                if (NULL == _pr_fd_cache.tail) _pr_fd_cache.tail = fd;
+                fd->higher = _pr_fd_cache.head;
+                _pr_fd_cache.head = fd;
+                _pr_fd_cache.count += 1;
+            }
+        }
+    }
+    PR_Unlock(_pr_fd_cache.ml);
+    return PR_SUCCESS;
+}  /* PR_SetFDCacheSize */
+
+void _PR_InitFdCache(void)
+{
+    /*
+    ** The fd caching is enabled by default for DEBUG builds,
+    ** disabled by default for OPT builds. That default can
+    ** be overridden at runtime using environment variables
+    ** or a super-wiz-bang API.
+    */
+    const char *low = PR_GetEnv("NSPR_FD_CACHE_SIZE_LOW");
+    const char *high = PR_GetEnv("NSPR_FD_CACHE_SIZE_HIGH");
+
+    /* 
+    ** _low is allowed to be zero, _high is not.
+    ** If _high is zero, we're not doing the caching.
+    */
+
+    _pr_fd_cache.limit_low = 0;
+#if defined(DEBUG)
+    _pr_fd_cache.limit_high = FD_SETSIZE;
+#else
+    _pr_fd_cache.limit_high = 0;
+#endif  /* defined(DEBUG) */
+
+    if (NULL != low) _pr_fd_cache.limit_low = atoi(low);
+    if (NULL != high) _pr_fd_cache.limit_high = atoi(high);
+
+    if (_pr_fd_cache.limit_low < 0)
+        _pr_fd_cache.limit_low = 0;
+    if (_pr_fd_cache.limit_low > FD_SETSIZE)
+        _pr_fd_cache.limit_low = FD_SETSIZE;
+
+    if (_pr_fd_cache.limit_high > FD_SETSIZE)
+        _pr_fd_cache.limit_high = FD_SETSIZE;
+
+    if (_pr_fd_cache.limit_high < _pr_fd_cache.limit_low)
+        _pr_fd_cache.limit_high = _pr_fd_cache.limit_low;
+
+    _pr_fd_cache.ml = PR_NewLock();
+    PR_ASSERT(NULL != _pr_fd_cache.ml);
+    _pr_fd_cache.stack = PR_CreateStack("FD");
+    PR_ASSERT(NULL != _pr_fd_cache.stack);
+
+}  /* _PR_InitFdCache */
+
+void _PR_CleanupFdCache(void)
+{
+    PRFileDesc *fd, *next;
+    PRStackElem *pop;
+
+    for (fd = _pr_fd_cache.head; fd != NULL; fd = next)
+    {
+        next = fd->higher;
+        PR_DELETE(fd->secret);
+        PR_DELETE(fd);
+    }
+    _pr_fd_cache.head = NULL;
+    _pr_fd_cache.tail = NULL;
+    _pr_fd_cache.count = 0;
+    PR_DestroyLock(_pr_fd_cache.ml);
+    _pr_fd_cache.ml = NULL;
+    while ((pop = PR_StackPop(_pr_fd_cache.stack)) != NULL)
+    {
+        fd = (PRFileDesc*)((PRPtrdiff)pop - (PRPtrdiff)stack2fd);
+        PR_DELETE(fd->secret);
+        PR_DELETE(fd);
+    }
+    PR_DestroyStack(_pr_fd_cache.stack);
+    _pr_fd_cache.stack = NULL;
+}  /* _PR_CleanupFdCache */
+
+/* prfdcach.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prfile.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prfile.c
new file mode 100644
index 0000000..00dbb89
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prfile.c
@@ -0,0 +1,815 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+#include <fcntl.h>
+
+#ifdef XP_UNIX
+#if defined(AIX) || defined(QNX)
+/* To pick up sysconf */
+#include <unistd.h>
+#else
+/* To pick up getrlimit, setrlimit */
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+#endif /* XP_UNIX */
+
+extern PRLock *_pr_flock_lock;
+extern PRCondVar *_pr_flock_cv;
+
+static PRInt32 PR_CALLBACK FileRead(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    PRInt32 rv = 0;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+ 		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		rv = -1;
+    }
+    if (_PR_IO_PENDING(me)) {
+        PR_SetError(PR_IO_PENDING_ERROR, 0);
+	rv = -1;
+    }
+    if (rv == -1)
+    	return rv;
+
+	rv = _PR_MD_READ(fd, buf, amount);
+	if (rv < 0) {
+		PR_ASSERT(rv == -1);
+	}
+    PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv));
+    return rv;
+}
+
+static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    PRInt32 rv = 0;
+    PRInt32 temp, count;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+	    rv = -1;
+    }
+    if (_PR_IO_PENDING(me)) {
+        PR_SetError(PR_IO_PENDING_ERROR, 0);
+	    rv = -1;
+    }
+    if (rv != 0)
+    	return rv;
+
+    count = 0;
+#if !defined(_PR_HAVE_O_APPEND)  /* Bugzilla: 4090, 276330 */
+    if (fd->secret->appendMode) {
+        if (PR_Seek64(fd, 0, PR_SEEK_END) == -1) {
+            return -1;
+        }
+    } /* if (fd->secret->appendMode...) */
+#endif /* _PR_HAVE_O_APPEND */
+    while (amount > 0) {
+		temp = _PR_MD_WRITE(fd, buf, amount);
+		if (temp < 0) {
+			count = -1;
+			break;
+		}
+		count += temp;
+		if (fd->secret->nonblocking) {
+			break;
+		}
+		buf = (const void*) ((const char*)buf + temp);
+		amount -= temp;
+    }
+    PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count));
+    return count;
+}
+
+static PROffset32 PR_CALLBACK FileSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
+{
+    PROffset32 result;
+
+    result = _PR_MD_LSEEK(fd, offset, whence);
+    return result;
+}
+
+static PROffset64 PR_CALLBACK FileSeek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
+{
+    PROffset64 result;
+
+    result = _PR_MD_LSEEK64(fd, offset, whence);
+    return result;
+}
+
+static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc *fd)
+{
+    PRInt32 result, cur, end;
+
+    cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);
+
+	if (cur >= 0)
+    	end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
+
+    if ((cur < 0) || (end < 0)) {
+        return -1;
+    }
+
+    result = end - cur;
+    _PR_MD_LSEEK(fd, cur, PR_SEEK_SET);
+
+    return result;
+}
+
+static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd)
+{
+    PRInt64 result, cur, end;
+    PRInt64 minus_one;
+
+    LL_I2L(minus_one, -1);
+    cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);
+
+    if (LL_GE_ZERO(cur))
+    	end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
+
+    if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;
+
+    LL_SUB(result, end, cur);
+    (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);
+
+    return result;
+}
+
+static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd)
+{
+	PRInt32 rv;
+	rv =  _PR_MD_PIPEAVAILABLE(fd);
+	return rv;		
+}
+
+static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd)
+{
+    PRInt64 rv;
+    LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd));
+	return rv;		
+}
+
+static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd)
+{
+	return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info)
+{
+	PRInt32 rv;
+
+    rv = _PR_MD_GETOPENFILEINFO(fd, info);
+    if (rv < 0) {
+	return PR_FAILURE;
+    } else
+	return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info)
+{
+    /* $$$$ NOT YET IMPLEMENTED */
+	PRInt32 rv;
+
+    rv = _PR_MD_GETOPENFILEINFO64(fd, info);
+    if (rv < 0) return PR_FAILURE;
+    else return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd)
+{
+    PRInt32 result;
+    result = _PR_MD_FSYNC(fd);
+    if (result < 0) {
+		return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd)
+{
+    if (!fd || !fd->secret
+            || (fd->secret->state != _PR_FILEDESC_OPEN
+            && fd->secret->state != _PR_FILEDESC_CLOSED)) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    if (fd->secret->state == _PR_FILEDESC_OPEN) {
+        if (_PR_MD_CLOSE_FILE(fd->secret->md.osfd) < 0) {
+            return PR_FAILURE;
+        }
+        fd->secret->state = _PR_FILEDESC_CLOSED;
+    }
+    PR_FreeFileDesc(fd);
+    return PR_SUCCESS;
+}
+
+static PRInt16 PR_CALLBACK FilePoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    *out_flags = 0;
+    return in_flags;
+}  /* FilePoll */
+
+static PRIOMethods _pr_fileMethods = {
+    PR_DESC_FILE,
+    FileClose,
+    FileRead,
+    FileWrite,
+    FileAvailable,
+    FileAvailable64,
+    FileSync,
+    FileSeek,
+    FileSeek64,
+    FileGetInfo,
+    FileGetInfo64,
+    (PRWritevFN)_PR_InvalidInt,		
+    (PRConnectFN)_PR_InvalidStatus,		
+    (PRAcceptFN)_PR_InvalidDesc,		
+    (PRBindFN)_PR_InvalidStatus,		
+    (PRListenFN)_PR_InvalidStatus,		
+    (PRShutdownFN)_PR_InvalidStatus,	
+    (PRRecvFN)_PR_InvalidInt,		
+    (PRSendFN)_PR_InvalidInt,		
+    (PRRecvfromFN)_PR_InvalidInt,	
+    (PRSendtoFN)_PR_InvalidInt,		
+    FilePoll,         
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,	
+    (PRGetpeernameFN)_PR_InvalidStatus,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRGetsocketoptionFN)_PR_InvalidStatus,	
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
+{
+    return &_pr_fileMethods;
+}
+
+static PRIOMethods _pr_pipeMethods = {
+    PR_DESC_PIPE,
+    FileClose,
+    FileRead,
+    FileWrite,
+    PipeAvailable,
+    PipeAvailable64,
+    PipeSync,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,		
+    (PRConnectFN)_PR_InvalidStatus,		
+    (PRAcceptFN)_PR_InvalidDesc,		
+    (PRBindFN)_PR_InvalidStatus,		
+    (PRListenFN)_PR_InvalidStatus,		
+    (PRShutdownFN)_PR_InvalidStatus,	
+    (PRRecvFN)_PR_InvalidInt,		
+    (PRSendFN)_PR_InvalidInt,		
+    (PRRecvfromFN)_PR_InvalidInt,	
+    (PRSendtoFN)_PR_InvalidInt,		
+    FilePoll,         
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,	
+    (PRGetpeernameFN)_PR_InvalidStatus,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRGetsocketoptionFN)_PR_InvalidStatus,	
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void)
+{
+    return &_pr_pipeMethods;
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
+{
+    PROsfd osfd;
+    PRFileDesc *fd = 0;
+#if !defined(_PR_HAVE_O_APPEND)
+    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* Map pr open flags and mode to os specific flags */
+
+    osfd = _PR_MD_OPEN(name, flags, mode);
+    if (osfd != -1) {
+        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+        if (!fd) {
+            (void) _PR_MD_CLOSE_FILE(osfd);
+        } else {
+#if !defined(_PR_HAVE_O_APPEND)
+            fd->secret->appendMode = appendMode;
+#endif
+            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
+        }
+    }
+    return fd;
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode)
+{
+    PROsfd osfd;
+    PRFileDesc *fd = 0;
+#if !defined(_PR_HAVE_O_APPEND)
+    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
+#endif
+
+    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);
+        } else {
+#if !defined(_PR_HAVE_O_APPEND)
+            fd->secret->appendMode = appendMode;
+#endif
+            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
+        }
+    }
+    return fd;
+}
+
+PR_IMPLEMENT(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;
+    }
+
+    return rlim.rlim_max;
+#elif defined(AIX) || defined(NEXTSTEP) || defined(QNX)
+    return sysconf(_SC_OPEN_MAX);
+#elif defined(WIN32)
+    /*
+     * There is a systemwide limit of 65536 user handles.
+     */
+    return 16384;
+#elif defined (WIN16)
+    return FOPEN_MAX;
+#elif defined(XP_OS2)
+    ULONG ulReqCount = 0;
+    ULONG ulCurMaxFH = 0;
+    DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH);
+    return ulCurMaxFH;
+#elif defined(XP_BEOS)
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+   return -1;
+#else
+    write me;
+#endif
+}
+
+PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size)
+{
+#if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX)
+    struct rlimit rlim;
+    PRInt32 tableMax = PR_GetSysfdTableMax();
+
+    if (tableMax < 0) 
+        return -1;
+
+    if (tableMax > FD_SETSIZE)
+        tableMax = FD_SETSIZE;
+
+    rlim.rlim_max = tableMax;
+
+    /* Grow as much as we can; even if too big */
+    if ( rlim.rlim_max < table_size )
+        rlim.rlim_cur = rlim.rlim_max;
+    else
+        rlim.rlim_cur = table_size;
+
+    if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
+        /* XXX need to call PR_SetError() */
+        return -1;
+    }
+
+    return rlim.rlim_cur;
+#elif defined(XP_OS2)
+    PRInt32 tableMax = PR_GetSysfdTableMax();
+    if (table_size > tableMax) {
+      APIRET rc = NO_ERROR;
+      rc = DosSetMaxFH(table_size);
+      if (rc == NO_ERROR)
+        return table_size;
+      else
+        return -1;
+    } 
+    return tableMax;
+#elif defined(AIX) || defined(NEXTSTEP) || defined(QNX) \
+        || defined(WIN32) || defined(WIN16) || defined(XP_BEOS)
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+#else
+    write me;
+#endif
+}
+
+PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
+{
+	PRInt32 rv;
+
+	rv = _PR_MD_DELETE(name);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info)
+{
+	PRInt32 rv;
+
+	rv = _PR_MD_GETFILEINFO(fn, info);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    rv = _PR_MD_GETFILEINFO64(fn, info);
+    if (rv < 0) {
+        return PR_FAILURE;
+    } else {
+        return PR_SUCCESS;
+    }
+}
+
+PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to)
+{
+	PRInt32 rv;
+
+	rv = _PR_MD_RENAME(from, to);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how)
+{
+PRInt32 rv;
+
+	rv = _PR_MD_ACCESS(name, how);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+/*
+** Import an existing OS file to NSPR 
+*/
+PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd)
+{
+    PRFileDesc *fd = NULL;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+    if( !fd ) {
+        (void) _PR_MD_CLOSE_FILE(osfd);
+    } else {
+        _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
+    }
+
+    return fd;
+}
+
+/*
+** Import an existing OS pipe to NSPR 
+*/
+PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd)
+{
+    PRFileDesc *fd = NULL;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    fd = PR_AllocFileDesc(osfd, &_pr_pipeMethods);
+    if( !fd ) {
+        (void) _PR_MD_CLOSE_FILE(osfd);
+    } else {
+        _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
+#ifdef WINNT
+        fd->secret->md.sync_file_io = PR_TRUE;
+#endif
+    }
+
+    return fd;
+}
+
+#ifndef NO_NSPR_10_SUPPORT
+/*
+** PR_Stat() for Win16 is defined in w16io.c
+** it is a hack to circumvent problems in Gromit and Java
+** See also: BugSplat: 98516.
+*/
+#if !defined(WIN16)
+/*
+ * This function is supposed to be for backward compatibility with
+ * nspr 1.0.  Therefore, it still uses the nspr 1.0 error-reporting
+ * mechanism -- returns a PRInt32, which is the error code when the call
+ * fails.
+ * 
+ * If we need this function in nspr 2.0, it should be changed to
+ * return PRStatus, as follows:
+ *
+ * PR_IMPLEMENT(PRStatus) PR_Stat(const char *name, struct stat *buf)
+ * {
+ *     PRInt32 rv;
+ *
+ *     rv = _PR_MD_STAT(name, buf);
+ *     if (rv < 0)
+ *         return PR_FAILURE;
+ *     else
+ *         return PR_SUCCESS;
+ * }
+ *
+ * -- wtc, 2/14/97.
+ */
+PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
+{
+    PRInt32 rv;
+
+    rv = _PR_MD_STAT(name, buf);
+	return rv;
+}
+
+#endif /* !defined(WIN16)  */
+#endif /* ! NO_NSPR_10_SUPPORT */
+
+PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+#ifdef WINNT
+    if (!fd->secret->md.io_model_committed) {
+        PRInt32 rv;
+        rv = _md_Associate((HANDLE)fd->secret->md.osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+#endif
+
+    PR_Lock(_pr_flock_lock);
+    while (fd->secret->lockCount == -1)
+        PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT);
+    if (fd->secret->lockCount == 0) {
+        fd->secret->lockCount = -1;
+        PR_Unlock(_pr_flock_lock);
+        status = _PR_MD_LOCKFILE(fd->secret->md.osfd);
+        PR_Lock(_pr_flock_lock);
+        fd->secret->lockCount = (status == PR_SUCCESS) ? 1 : 0;
+        PR_NotifyAllCondVar(_pr_flock_cv);
+    } else {
+        fd->secret->lockCount++;
+    }
+    PR_Unlock(_pr_flock_lock);
+ 
+    return status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+#ifdef WINNT
+    if (!fd->secret->md.io_model_committed) {
+        PRInt32 rv;
+        rv = _md_Associate((HANDLE)fd->secret->md.osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+#endif
+
+    PR_Lock(_pr_flock_lock);
+    if (fd->secret->lockCount == 0) {
+        status = _PR_MD_TLOCKFILE(fd->secret->md.osfd);
+        PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0);
+        if (status == PR_SUCCESS)
+            fd->secret->lockCount = 1;
+    } else {
+        fd->secret->lockCount++;
+    }
+    PR_Unlock(_pr_flock_lock);
+
+    return status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    PR_Lock(_pr_flock_lock);
+    if (fd->secret->lockCount == 1) {
+        rv = _PR_MD_UNLOCKFILE(fd->secret->md.osfd);
+        if (rv == PR_SUCCESS) 
+            fd->secret->lockCount = 0;
+    } else {
+        fd->secret->lockCount--;
+    }
+    PR_Unlock(_pr_flock_lock);
+
+    return rv;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CreatePipe(
+    PRFileDesc **readPipe,
+    PRFileDesc **writePipe
+)
+{
+#if defined(WIN32) && !defined(WINCE)
+    HANDLE readEnd, writeEnd;
+    SECURITY_ATTRIBUTES pipeAttributes;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    ZeroMemory(&pipeAttributes, sizeof(pipeAttributes));
+    pipeAttributes.nLength = sizeof(pipeAttributes);
+    pipeAttributes.bInheritHandle = TRUE;
+    if (CreatePipe(&readEnd, &writeEnd, &pipeAttributes, 0) == 0) {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+    *readPipe = PR_AllocFileDesc((PROsfd)readEnd, &_pr_pipeMethods);
+    if (NULL == *readPipe) {
+        CloseHandle(readEnd);
+        CloseHandle(writeEnd);
+        return PR_FAILURE;
+    }
+    *writePipe = PR_AllocFileDesc((PROsfd)writeEnd, &_pr_pipeMethods);
+    if (NULL == *writePipe) {
+        PR_Close(*readPipe);
+        CloseHandle(writeEnd);
+        return PR_FAILURE;
+    }
+#ifdef WINNT
+    (*readPipe)->secret->md.sync_file_io = PR_TRUE;
+    (*writePipe)->secret->md.sync_file_io = PR_TRUE;
+#endif
+    (*readPipe)->secret->inheritable = _PR_TRI_TRUE;
+    (*writePipe)->secret->inheritable = _PR_TRI_TRUE;
+    return PR_SUCCESS;
+#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+#ifdef XP_OS2
+    HFILE pipefd[2];
+#else
+    int pipefd[2];
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#ifdef XP_OS2
+    if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) {
+#else
+    if (pipe(pipefd) == -1) {
+#endif
+        /* XXX map pipe error */
+        PR_SetError(PR_UNKNOWN_ERROR, errno);
+        return PR_FAILURE;
+    }
+    *readPipe = PR_AllocFileDesc(pipefd[0], &_pr_pipeMethods);
+    if (NULL == *readPipe) {
+        close(pipefd[0]);
+        close(pipefd[1]);
+        return PR_FAILURE;
+    }
+    *writePipe = PR_AllocFileDesc(pipefd[1], &_pr_pipeMethods);
+    if (NULL == *writePipe) {
+        PR_Close(*readPipe);
+        close(pipefd[1]);
+        return PR_FAILURE;
+    }
+#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
+    _PR_MD_MAKE_NONBLOCK(*readPipe);
+#endif
+    _PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE);
+#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
+    _PR_MD_MAKE_NONBLOCK(*writePipe);
+#endif
+    _PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE);
+    return PR_SUCCESS;
+#else
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+#endif
+}
+
+#ifdef MOZ_UNICODE
+/* ================ UTF16 Interfaces ================================ */
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
+    const PRUnichar *name, PRIntn flags, PRIntn mode)
+{ 
+    PROsfd osfd;
+    PRFileDesc *fd = 0;
+#if !defined(_PR_HAVE_O_APPEND)
+    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
+#endif
+   
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+  
+    /* Map pr open flags and mode to os specific flags */
+    osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode);
+    if (osfd != -1) {
+        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+        if (!fd) {
+            (void) _PR_MD_CLOSE_FILE(osfd);
+        } else {
+#if !defined(_PR_HAVE_O_APPEND)
+            fd->secret->appendMode = appendMode;
+#endif
+            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
+        }
+    }
+    return fd;
+}
+ 
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    rv = _PR_MD_GETFILEINFO64_UTF16(fn, info);
+    if (rv < 0) {
+        return PR_FAILURE;
+    } else {
+        return PR_SUCCESS;
+    }
+}
+
+/* ================ UTF16 Interfaces ================================ */
+#endif /* MOZ_UNICODE */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prio.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prio.c
new file mode 100644
index 0000000..b779b1c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prio.c
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h> /* for memset() */
+
+
+/************************************************************************/
+
+PRLock *_pr_flock_lock;
+PRCondVar *_pr_flock_cv;
+
+#ifdef WINCE
+/*
+ * There are no stdin, stdout, stderr in Windows CE.  INVALID_HANDLE_VALUE
+ * should cause all I/O functions on the handle to fail.
+ */
+#define STD_INPUT_HANDLE  ((DWORD)-10)
+#define STD_OUTPUT_HANDLE ((DWORD)-11)
+#define STD_ERROR_HANDLE  ((DWORD)-12)
+
+static HANDLE GetStdHandle(DWORD nStdHandle)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return INVALID_HANDLE_VALUE;
+}
+#endif
+
+void _PR_InitIO(void)
+{
+    const PRIOMethods *methods = PR_GetFileMethods();
+
+    _PR_InitFdCache();
+
+    _pr_flock_lock = PR_NewLock();
+    _pr_flock_cv = PR_NewCondVar(_pr_flock_lock);
+
+#ifdef WIN32
+    _pr_stdin = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_INPUT_HANDLE),
+            methods);
+    _pr_stdout = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_OUTPUT_HANDLE),
+            methods);
+    _pr_stderr = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_ERROR_HANDLE),
+            methods);
+#ifdef WINNT
+    _pr_stdin->secret->md.sync_file_io = PR_TRUE;
+    _pr_stdout->secret->md.sync_file_io = PR_TRUE;
+    _pr_stderr->secret->md.sync_file_io = PR_TRUE;
+#endif
+#else
+    _pr_stdin = PR_AllocFileDesc(0, methods);
+    _pr_stdout = PR_AllocFileDesc(1, methods);
+    _pr_stderr = PR_AllocFileDesc(2, methods);
+#endif
+    _PR_MD_INIT_FD_INHERITABLE(_pr_stdin, PR_TRUE);
+    _PR_MD_INIT_FD_INHERITABLE(_pr_stdout, PR_TRUE);
+    _PR_MD_INIT_FD_INHERITABLE(_pr_stderr, PR_TRUE);
+
+    _PR_MD_INIT_IO();
+}
+
+void _PR_CleanupIO(void)
+{
+    PR_FreeFileDesc(_pr_stdin);
+    _pr_stdin = NULL;
+    PR_FreeFileDesc(_pr_stdout);
+    _pr_stdout = NULL;
+    PR_FreeFileDesc(_pr_stderr);
+    _pr_stderr = NULL;
+
+    if (_pr_flock_cv) {
+        PR_DestroyCondVar(_pr_flock_cv);
+        _pr_flock_cv = NULL;
+    }
+    if (_pr_flock_lock) {
+        PR_DestroyLock(_pr_flock_lock);
+        _pr_flock_lock = NULL;
+    }
+
+    _PR_CleanupFdCache();
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
+{
+    PRFileDesc *result = NULL;
+    PR_ASSERT((int) osfd >= PR_StandardInput && osfd <= PR_StandardError);
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    
+    switch (osfd)
+    {
+        case PR_StandardInput: result = _pr_stdin; break;
+        case PR_StandardOutput: result = _pr_stdout; break;
+        case PR_StandardError: result = _pr_stderr; break;
+        default:
+            (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    }
+    return result;
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
+    PROsfd osfd, const PRIOMethods *methods)
+{
+    PRFileDesc *fd;
+
+#ifdef XP_UNIX
+	/*
+	 * Assert that the file descriptor is small enough to fit in the
+	 * fd_set passed to select
+	 */
+	PR_ASSERT(osfd < FD_SETSIZE);
+#endif
+    fd = _PR_Getfd();
+    if (fd) {
+        /* Initialize the members of PRFileDesc and PRFilePrivate */
+        fd->methods = methods;
+        fd->secret->state = _PR_FILEDESC_OPEN;
+	fd->secret->md.osfd = osfd;
+        _PR_MD_INIT_FILEDESC(fd);
+    } else {
+	    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+
+    return fd;
+}
+
+PR_IMPLEMENT(void) PR_FreeFileDesc(PRFileDesc *fd)
+{
+    PR_ASSERT(fd);
+    _PR_Putfd(fd);
+}
+
+/*
+** Wait for some i/o to finish on one or more more poll descriptors.
+*/
+PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+	return(_PR_MD_PR_POLL(pds, npds, timeout));
+}
+
+/*
+** Set the inheritance attribute of a file descriptor.
+*/
+PR_IMPLEMENT(PRStatus) PR_SetFDInheritable(
+    PRFileDesc *fd,
+    PRBool inheritable)
+{
+#if defined(XP_UNIX) || defined(WIN32) || defined(XP_OS2) || defined(XP_BEOS)
+    /*
+     * Only a non-layered, NSPR file descriptor can be inherited
+     * by a child process.
+     */
+    if (fd->identity != PR_NSPR_IO_LAYER) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (fd->secret->inheritable != inheritable) {
+        if (_PR_MD_SET_FD_INHERITABLE(fd, inheritable) == PR_FAILURE) {
+            return PR_FAILURE;
+        }
+        fd->secret->inheritable = inheritable;
+    }
+    return PR_SUCCESS;
+#else
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+#endif
+}
+
+/*
+** This function only has a useful implementation in the debug build of
+** the pthreads version.
+*/
+PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
+{
+    /* do nothing */
+}  /* PT_FPrintStats */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/priometh.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/priometh.c
new file mode 100644
index 0000000..1ca474f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/priometh.c
@@ -0,0 +1,628 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "primpl.h"
+
+#include <string.h>
+
+/*****************************************************************************/
+/************************** Invalid I/O method object ************************/
+/*****************************************************************************/
+PRIOMethods _pr_faulty_methods = {
+    (PRDescType)0,
+    (PRCloseFN)_PR_InvalidStatus,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    (PRPollFN)_PR_InvalidInt16,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PRIntn _PR_InvalidInt(void)
+{
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return -1;
+}  /* _PR_InvalidInt */
+
+PRInt16 _PR_InvalidInt16(void)
+{
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return -1;
+}  /* _PR_InvalidInt */
+
+PRInt64 _PR_InvalidInt64(void)
+{
+    PRInt64 rv;
+    LL_I2L(rv, -1);
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return rv;
+}  /* _PR_InvalidInt */
+
+/*
+ * An invalid method that returns PRStatus
+ */
+
+PRStatus _PR_InvalidStatus(void)
+{
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return PR_FAILURE;
+}  /* _PR_InvalidDesc */
+
+/*
+ * An invalid method that returns a pointer
+ */
+
+PRFileDesc *_PR_InvalidDesc(void)
+{
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return NULL;
+}  /* _PR_InvalidDesc */
+
+PR_IMPLEMENT(PRDescType) PR_GetDescType(PRFileDesc *file)
+{
+    return file->methods->file_type;
+}
+
+PR_IMPLEMENT(PRStatus) PR_Close(PRFileDesc *fd)
+{
+    return (fd->methods->close)(fd);
+}
+
+PR_IMPLEMENT(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+	return((fd->methods->read)(fd,buf,amount));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Write(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+	return((fd->methods->write)(fd,buf,amount));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
+{
+	return((fd->methods->seek)(fd, offset, whence));
+}
+
+PR_IMPLEMENT(PRInt64) PR_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
+{
+	return((fd->methods->seek64)(fd, offset, whence));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Available(PRFileDesc *fd)
+{
+	return((fd->methods->available)(fd));
+}
+
+PR_IMPLEMENT(PRInt64) PR_Available64(PRFileDesc *fd)
+{
+	return((fd->methods->available64)(fd));
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info)
+{
+	return((fd->methods->fileInfo)(fd, info));
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
+{
+	return((fd->methods->fileInfo64)(fd, info));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Sync(PRFileDesc *fd)
+{
+	return((fd->methods->fsync)(fd));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Connect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	return((fd->methods->connect)(fd,addr,timeout));
+}
+
+PR_IMPLEMENT(PRStatus) PR_ConnectContinue(
+    PRFileDesc *fd, PRInt16 out_flags)
+{
+	return((fd->methods->connectcontinue)(fd,out_flags));
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_Accept(PRFileDesc *fd, PRNetAddr *addr,
+PRIntervalTime timeout)
+{
+	return((fd->methods->accept)(fd,addr,timeout));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr)
+{
+	return((fd->methods->bind)(fd,addr));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Shutdown(PRFileDesc *fd, PRShutdownHow how)
+{
+	return((fd->methods->shutdown)(fd,how));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog)
+{
+	return((fd->methods->listen)(fd,backlog));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+PRIntn flags, PRIntervalTime timeout)
+{
+	return((fd->methods->recv)(fd,buf,amount,flags,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+PRIntn flags, PRIntervalTime timeout)
+{
+	return((fd->methods->send)(fd,buf,amount,flags,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Writev(PRFileDesc *fd, const PRIOVec *iov,
+PRInt32 iov_size, PRIntervalTime timeout)
+{
+    if (iov_size > PR_MAX_IOVECTOR_SIZE)
+    {
+        PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+        return -1;
+    }
+	return((fd->methods->writev)(fd,iov,iov_size,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
+{
+	return((fd->methods->recvfrom)(fd,buf,amount,flags,addr,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_SendTo(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	return((fd->methods->sendto)(fd,buf,amount,flags,addr,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_TransmitFile(
+    PRFileDesc *sd, PRFileDesc *fd, const void *hdr, PRInt32 hlen,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+	return((sd->methods->transmitfile)(sd,fd,hdr,hlen,flags,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_AcceptRead(
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
+    void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+	return((sd->methods->acceptread)(sd, nd, raddr, buf, amount,timeout));
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
+{
+	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_GetSocketOption(
+    PRFileDesc *fd, PRSocketOptionData *data)
+{
+	return((fd->methods->getsocketoption)(fd, data));
+}
+
+PR_IMPLEMENT(PRStatus) PR_SetSocketOption(
+    PRFileDesc *fd, const PRSocketOptionData *data)
+{
+	return((fd->methods->setsocketoption)(fd, data));
+}
+
+PR_IMPLEMENT(PRInt32) PR_SendFile(
+	PRFileDesc *sd, PRSendFileData *sfd,
+	PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+	return((sd->methods->sendfile)(sd,sfd,flags,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead(
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
+    void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    PRNetAddr remote;
+    PRFileDesc *accepted = NULL;
+
+    /*
+    ** The timeout does not apply to the accept portion of the
+    ** operation - it waits indefinitely.
+    */
+    accepted = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == accepted) return rv;
+
+    rv = PR_Recv(accepted, buf, amount, 0, timeout);
+    if (rv >= 0)
+    {
+        /* copy the new info out where caller can see it */
+#define AMASK ((PRPtrdiff)7)  /* mask for alignment of PRNetAddr */
+        PRPtrdiff aligned = (PRPtrdiff)buf + amount + AMASK;
+        *raddr = (PRNetAddr*)(aligned & ~AMASK);
+        memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote));
+        *nd = accepted;
+        return rv;
+    }
+
+    PR_Close(accepted);
+    return rv;
+}
+
+/*
+ * PR_EmulateSendFile
+ *
+ *    Send file sfd->fd across socket sd. If header/trailer are specified
+ *    they are sent before and after the file, respectively.
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *    
+ *    return number of bytes sent or -1 on error
+ *
+ */
+
+#if defined(XP_UNIX) || defined(WIN32)
+
+/*
+ * An implementation based on memory-mapped files
+ */
+
+#define SENDFILE_MMAP_CHUNK	(256 * 1024)
+
+PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
+    PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    PRInt32 rv, count = 0;
+    PRInt32 len, file_bytes, index = 0;
+    PRFileInfo info;
+    PRIOVec iov[3];
+    PRFileMap *mapHandle = NULL;
+    void *addr = (void*)0; /* initialized to some arbitrary value. Keeps compiler warnings down. */
+    PRUint32 file_mmap_offset, alignment;
+    PRInt64 zero64;
+    PROffset64 file_mmap_offset64;
+    PRUint32 addr_offset, mmap_len;
+
+    /* Get file size */
+    if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) {
+        count = -1;
+        goto done;
+    }
+    if (sfd->file_nbytes &&
+            (info.size < (sfd->file_offset + sfd->file_nbytes))) {
+        /*
+         * there are fewer bytes in file to send than specified
+         */
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        count = -1;
+        goto done;
+    }
+    if (sfd->file_nbytes)
+        file_bytes = sfd->file_nbytes;
+    else
+        file_bytes = info.size - sfd->file_offset;
+
+    alignment = PR_GetMemMapAlignment();
+
+    /* number of initial bytes to skip in mmap'd segment */
+    addr_offset = sfd->file_offset % alignment;
+
+    /* find previous mmap alignment boundary */
+    file_mmap_offset = sfd->file_offset - addr_offset;
+
+    /*
+     * If the file is large, mmap and send the file in chunks so as
+     * to not consume too much virtual address space
+     */
+    mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK);
+    len = mmap_len - addr_offset;
+
+    /*
+     * Map in (part of) file. Take care of zero-length files.
+     */
+    if (len) {
+        LL_I2L(zero64, 0);
+        mapHandle = PR_CreateFileMap(sfd->fd, zero64, PR_PROT_READONLY);
+        if (!mapHandle) {
+            count = -1;
+            goto done;
+        }
+        LL_I2L(file_mmap_offset64, file_mmap_offset);
+        addr = PR_MemMap(mapHandle, file_mmap_offset64, mmap_len);
+        if (!addr) {
+            count = -1;
+            goto done;
+        }
+    }
+    /*
+     * send headers first, followed by the file
+     */
+    if (sfd->hlen) {
+        iov[index].iov_base = (char *) sfd->header;
+        iov[index].iov_len = sfd->hlen;
+        index++;
+    }
+    if (len) {
+        iov[index].iov_base = (char*)addr + addr_offset;
+        iov[index].iov_len = len;
+        index++;
+    }
+    if ((file_bytes == len) && (sfd->tlen)) {
+        /*
+         * all file data is mapped in; send the trailer too
+         */
+        iov[index].iov_base = (char *) sfd->trailer;
+        iov[index].iov_len = sfd->tlen;
+        index++;
+    }
+    rv = PR_Writev(sd, iov, index, timeout);
+    if (len)
+        PR_MemUnmap(addr, mmap_len);
+    if (rv < 0) {
+        count = -1;
+        goto done;
+    }
+
+    PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0));
+
+    file_bytes -= len;
+    count += rv;
+    if (!file_bytes)    /* header, file and trailer are sent */
+        goto done;
+
+    /*
+     * send remaining bytes of the file, if any
+     */
+    len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
+    while (len > 0) {
+        /*
+         * Map in (part of) file
+         */
+        file_mmap_offset = sfd->file_offset + count - sfd->hlen;
+        PR_ASSERT((file_mmap_offset % alignment) == 0);
+
+        LL_I2L(file_mmap_offset64, file_mmap_offset);
+        addr = PR_MemMap(mapHandle, file_mmap_offset64, len);
+        if (!addr) {
+            count = -1;
+            goto done;
+        }
+        rv = PR_Send(sd, addr, len, 0, timeout);
+        PR_MemUnmap(addr, len);
+        if (rv < 0) {
+            count = -1;
+            goto done;
+        }
+
+        PR_ASSERT(rv == len);
+        file_bytes -= rv;
+        count += rv;
+        len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
+    }
+    PR_ASSERT(0 == file_bytes);
+    if (sfd->tlen) {
+        rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout);
+        if (rv >= 0) {
+            PR_ASSERT(rv == sfd->tlen);
+            count += rv;
+        } else
+            count = -1;
+    }
+done:
+    if (mapHandle)
+        PR_CloseFileMap(mapHandle);
+    if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
+        PR_Close(sd);
+    return count;
+}
+
+#else
+
+PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
+    PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    PRInt32 rv, count = 0;
+    PRInt32 rlen;
+    const void * buffer;
+    PRInt32 buflen;
+    PRInt32 sendbytes, readbytes;
+    char *buf;
+
+#define _SENDFILE_BUFSIZE   (16 * 1024)
+
+    buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE);
+    if (buf == NULL) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+
+    /*
+     * send header first
+     */
+    buflen = sfd->hlen;
+    buffer = sfd->header;
+    while (buflen) {
+        rv = PR_Send(sd, buffer, buflen, 0, timeout);
+        if (rv < 0) {
+            /* PR_Send() has invoked PR_SetError(). */
+            rv = -1;
+            goto done;
+        } else {
+            count += rv;
+            buffer = (const void*) ((const char*)buffer + rv);
+            buflen -= rv;
+        }
+    }
+
+    /*
+     * send file next
+     */
+    if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) {
+        rv = -1;
+        goto done;
+    }
+    sendbytes = sfd->file_nbytes;
+    if (sendbytes == 0) {
+        /* send entire file */
+        while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) {
+            while (rlen) {
+                char *bufptr = buf;
+
+                rv =  PR_Send(sd, bufptr, rlen, 0, timeout);
+                if (rv < 0) {
+                    /* PR_Send() has invoked PR_SetError(). */
+                    rv = -1;
+                    goto done;
+                } else {
+                    count += rv;
+                    bufptr = ((char*)bufptr + rv);
+                    rlen -= rv;
+                }
+            }
+        }
+        if (rlen < 0) {
+            /* PR_Read() has invoked PR_SetError(). */
+            rv = -1;
+            goto done;
+        }
+    } else {
+        readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);
+        while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) {
+            while (rlen) {
+                char *bufptr = buf;
+
+                rv =  PR_Send(sd, bufptr, rlen, 0, timeout);
+                if (rv < 0) {
+                    /* PR_Send() has invoked PR_SetError(). */
+                    rv = -1;
+                    goto done;
+                } else {
+                    count += rv;
+                    sendbytes -= rv;
+                    bufptr = ((char*)bufptr + rv);
+                    rlen -= rv;
+                }
+            }
+            readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);
+        }
+        if (rlen < 0) {
+            /* PR_Read() has invoked PR_SetError(). */
+            rv = -1;
+            goto done;
+        } else if (sendbytes != 0) {
+            /*
+             * there are fewer bytes in file to send than specified
+             */
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = -1;
+            goto done;
+        }
+    }
+
+    /*
+     * send trailer last
+     */
+    buflen = sfd->tlen;
+    buffer = sfd->trailer;
+    while (buflen) {
+        rv =  PR_Send(sd, buffer, buflen, 0, timeout);
+        if (rv < 0) {
+            /* PR_Send() has invoked PR_SetError(). */
+            rv = -1;
+            goto done;
+        } else {
+            count += rv;
+            buffer = (const void*) ((const char*)buffer + rv);
+            buflen -= rv;
+        }
+    }
+    rv = count;
+
+done:
+    if (buf)
+        PR_DELETE(buf);
+    if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
+        PR_Close(sd);
+    return rv;
+}
+
+#endif
+
+/* priometh.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/pripv6.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/pripv6.c
new file mode 100644
index 0000000..e4af39c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/pripv6.c
@@ -0,0 +1,396 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** 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;
+    PRNetAddr *addrlower = NULL;
+
+    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 */
+
+    if (addr)
+        addrlower = &tmp_ipv4addr;
+    newfd = (fd->lower->methods->accept)(fd->lower, addrlower, timeout);
+    if (NULL == newfd)
+    {
+        PR_DELETE(newstack);
+        return NULL;
+    }
+    if (addr)
+        _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);
+
+    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->getpeername)(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)
+static PRBool ipv6_is_present;
+extern PRBool _pr_test_ipv6_socket(void);
+
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+extern PRStatus _pr_find_getipnodebyname(void);
+#endif
+
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO)
+extern PRStatus _pr_find_getaddrinfo(void);
+#endif
+
+static PRBool
+_pr_probe_ipv6_presence(void)
+{
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    if (_pr_find_getipnodebyname() != PR_SUCCESS)
+        return PR_FALSE;
+#endif
+
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO)
+    if (_pr_find_getaddrinfo() != PR_SUCCESS)
+        return PR_FALSE;
+#endif
+
+    return _pr_test_ipv6_socket();
+}
+#endif  /* _PR_INET6_PROBE */
+
+static PRCallOnceType _pr_init_ipv6_once;
+
+static PRStatus PR_CALLBACK _pr_init_ipv6(void)
+{
+    const PRIOMethods *stubMethods;
+
+#if defined(_PR_INET6_PROBE)
+    ipv6_is_present = _pr_probe_ipv6_presence();
+    if (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_udpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+	ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+	ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+	ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+	return PR_SUCCESS;
+}
+
+#if defined(_PR_INET6_PROBE)
+PRBool _pr_ipv6_is_present(void)
+{
+    if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS)
+        return PR_FALSE;
+    return ipv6_is_present;
+}
+#endif
+
+PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd)
+{
+	PRFileDesc *ipv6_fd = NULL;
+
+	if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS)
+		return PR_FAILURE;
+
+	/*
+	 * 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) */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prlayer.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prlayer.c
new file mode 100644
index 0000000..cf48d23
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prlayer.c
@@ -0,0 +1,768 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        prlayer.c
+** Description: Routines for handling pushable protocol modules on sockets.
+*/
+
+#include "primpl.h"
+#include "prerror.h"
+#include "prmem.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prio.h"
+
+#include <string.h> /* for memset() */
+static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack);
+
+void PR_CALLBACK pl_FDDestructor(PRFileDesc *fd)
+{
+    PR_ASSERT(fd != NULL);
+    if (NULL != fd->lower) fd->lower->higher = fd->higher;
+    if (NULL != fd->higher) fd->higher->lower = fd->lower;
+    PR_DELETE(fd);
+}
+
+/*
+** Default methods that just call down to the next fd.
+*/
+static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd)
+{
+    PRFileDesc *top, *lower;
+	PRStatus rv;
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+    PR_ASSERT(fd->secret == NULL);
+    PR_ASSERT(fd->methods->file_type == PR_DESC_LAYERED);
+
+	if (PR_IO_LAYER_HEAD == fd->identity) {
+		/*
+		 * new style stack; close all the layers, before deleting the
+		 * stack head
+		 */
+		rv = fd->lower->methods->close(fd->lower);
+		_PR_DestroyIOLayer(fd);
+		return rv;
+	} else if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) {
+		/*
+		 * lower layers of new style stack
+		 */
+		lower = fd->lower;
+		/*
+		 * pop and cleanup current layer
+		 */
+    	top = PR_PopIOLayer(fd->higher, PR_TOP_IO_LAYER);
+		top->dtor(top);
+		/*
+		 * then call lower layer
+		 */
+		return (lower->methods->close(lower));
+	} else {
+		/* old style stack */
+    	top = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
+		top->dtor(top);
+		return (fd->methods->close)(fd);
+	}
+}
+
+static PRInt32 PR_CALLBACK pl_DefRead (PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->read)(fd->lower, buf, amount);
+}
+
+static PRInt32 PR_CALLBACK pl_DefWrite (
+    PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->write)(fd->lower, buf, amount);
+}
+
+static PRInt32 PR_CALLBACK pl_DefAvailable (PRFileDesc *fd)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->available)(fd->lower);
+}
+
+static PRInt64 PR_CALLBACK pl_DefAvailable64 (PRFileDesc *fd)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->available64)(fd->lower);
+}
+
+static PRStatus PR_CALLBACK pl_DefFsync (PRFileDesc *fd)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->fsync)(fd->lower);
+}
+
+static PRInt32 PR_CALLBACK pl_DefSeek (
+    PRFileDesc *fd, PRInt32 offset, PRSeekWhence how)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->seek)(fd->lower, offset, how);
+}
+
+static PRInt64 PR_CALLBACK pl_DefSeek64 (
+    PRFileDesc *fd, PRInt64 offset, PRSeekWhence how)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->seek64)(fd->lower, offset, how);
+}
+
+static PRStatus PR_CALLBACK pl_DefFileInfo (PRFileDesc *fd, PRFileInfo *info)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->fileInfo)(fd->lower, info);
+}
+
+static PRStatus PR_CALLBACK pl_DefFileInfo64 (PRFileDesc *fd, PRFileInfo64 *info)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->fileInfo64)(fd->lower, info);
+}
+
+static PRInt32 PR_CALLBACK pl_DefWritev (PRFileDesc *fd, const PRIOVec *iov,
+    PRInt32 size, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->writev)(fd->lower, iov, size, timeout);
+}
+
+static PRStatus PR_CALLBACK pl_DefConnect (
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->connect)(fd->lower, addr, timeout);
+}
+
+static PRStatus PR_CALLBACK pl_DefConnectcontinue (
+    PRFileDesc *fd, PRInt16 out_flags)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->connectcontinue)(fd->lower, out_flags);
+}
+
+static PRFileDesc* PR_CALLBACK pl_TopAccept (
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRFileDesc *newfd, *layer = fd;
+    PRFileDesc *newstack;
+	PRBool newstyle_stack = PR_FALSE;
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+	/* test for new style stack */
+	while (NULL != layer->higher)
+		layer = layer->higher;
+	newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE;
+    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, addr, timeout);
+    if (NULL == newfd)
+    {
+        PR_DELETE(newstack);
+        return NULL;
+    }
+
+    if (newstyle_stack) {
+		newstack->lower = newfd;
+		newfd->higher = newstack;
+		return newstack;
+	} else {
+		/* this PR_PushIOLayer call cannot fail */
+		rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+		PR_ASSERT(PR_SUCCESS == rv);
+    	return newfd;  /* that's it */
+	}
+}
+
+static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->bind)(fd->lower, addr);
+}
+
+static PRStatus PR_CALLBACK pl_DefListen (PRFileDesc *fd, PRIntn backlog)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->listen)(fd->lower, backlog);
+}
+
+static PRStatus PR_CALLBACK pl_DefShutdown (PRFileDesc *fd, PRIntn how)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->shutdown)(fd->lower, how);
+}
+
+static PRInt32 PR_CALLBACK pl_DefRecv (
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->recv)(
+        fd->lower, buf, amount, flags, timeout);
+}
+
+static PRInt32 PR_CALLBACK pl_DefSend (
+    PRFileDesc *fd, const void *buf,
+    PRInt32 amount, PRIntn flags, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->send)(fd->lower, buf, amount, flags, timeout);
+}
+
+static PRInt32 PR_CALLBACK pl_DefRecvfrom (
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->recvfrom)(
+        fd->lower, buf, amount, flags, addr, timeout);
+}
+
+static PRInt32 PR_CALLBACK pl_DefSendto (
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+    const PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->sendto)(
+        fd->lower, buf, amount, flags, addr, timeout);
+}
+
+static PRInt16 PR_CALLBACK pl_DefPoll (
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags);
+}
+
+static PRInt32 PR_CALLBACK pl_DefAcceptread (
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf,
+    PRInt32 amount, PRIntervalTime t)
+{
+    PRInt32 nbytes;
+    PRStatus rv;
+    PRFileDesc *newstack;
+    PRFileDesc *layer = sd;
+	PRBool newstyle_stack = PR_FALSE;
+
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
+
+	/* test for new style stack */
+	while (NULL != layer->higher)
+		layer = layer->higher;
+	newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE;
+    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, raddr, buf, amount, t);
+    if (-1 == nbytes)
+    {
+        PR_DELETE(newstack);
+        return nbytes;
+    }
+    if (newstyle_stack) {
+		newstack->lower = *nd;
+		(*nd)->higher = newstack;
+		*nd = newstack;
+		return nbytes;
+	} else {
+		/* this PR_PushIOLayer call cannot fail */
+		rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
+		PR_ASSERT(PR_SUCCESS == rv);
+		return nbytes;
+	}
+}
+
+static PRInt32 PR_CALLBACK pl_DefTransmitfile (
+    PRFileDesc *sd, PRFileDesc *fd, const void *headers, PRInt32 hlen,
+    PRTransmitFileFlags flags, PRIntervalTime t)
+{
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
+
+    return sd->lower->methods->transmitfile(
+        sd->lower, fd, headers, hlen, flags, t);
+}
+
+static PRStatus PR_CALLBACK pl_DefGetsockname (PRFileDesc *fd, PRNetAddr *addr)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->getsockname)(fd->lower, addr);
+}
+
+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_DefGetsocketoption (
+    PRFileDesc *fd, PRSocketOptionData *data)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->getsocketoption)(fd->lower, data);
+}
+
+static PRStatus PR_CALLBACK pl_DefSetsocketoption (
+    PRFileDesc *fd, const PRSocketOptionData *data)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->setsocketoption)(fd->lower, data);
+}
+
+static PRInt32 PR_CALLBACK pl_DefSendfile (
+	PRFileDesc *sd, PRSendFileData *sfd,
+	PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
+
+    return sd->lower->methods->sendfile(
+        sd->lower, sfd, flags, timeout);
+}
+
+/* Methods for the top of the stack.  Just call down to the next fd. */
+static PRIOMethods pl_methods = {
+    PR_DESC_LAYERED,
+    pl_TopClose,
+    pl_DefRead,
+    pl_DefWrite,
+    pl_DefAvailable,
+    pl_DefAvailable64,
+    pl_DefFsync,
+    pl_DefSeek,
+    pl_DefSeek64,
+    pl_DefFileInfo,
+    pl_DefFileInfo64,
+    pl_DefWritev,
+    pl_DefConnect,
+    pl_TopAccept,
+    pl_DefBind,
+    pl_DefListen,
+    pl_DefShutdown,
+    pl_DefRecv,
+    pl_DefSend,
+    pl_DefRecvfrom,
+    pl_DefSendto,
+    pl_DefPoll,
+    pl_DefAcceptread,
+    pl_DefTransmitfile,
+    pl_DefGetsockname,
+    pl_DefGetpeername,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    pl_DefGetsocketoption,
+    pl_DefSetsocketoption,
+    pl_DefSendfile,
+    pl_DefConnectcontinue,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods(void)
+{
+    return &pl_methods;
+}  /* PR_GetDefaultIOMethods */
+
+PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub(
+    PRDescIdentity ident, const PRIOMethods *methods)
+{
+    PRFileDesc *fd = NULL;
+    PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident));
+    if ((PR_NSPR_IO_LAYER == ident) || (PR_TOP_IO_LAYER == ident))
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    else
+    {
+        fd = PR_NEWZAP(PRFileDesc);
+        if (NULL == fd)
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        else
+        {
+            fd->methods = methods;
+            fd->dtor = pl_FDDestructor;
+            fd->identity = ident;
+        }
+    }
+    return fd;
+}  /* PR_CreateIOLayerStub */
+
+/*
+ * PR_CreateIOLayer
+ *		Create a new style stack, where the stack top is a dummy header.
+ *		Unlike the old style stacks, the contents of the stack head
+ *		are not modified when a layer is pushed onto or popped from a new
+ *		style stack.
+ */
+
+PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayer(PRFileDesc *top)
+{
+    PRFileDesc *fd = NULL;
+
+	fd = PR_NEWZAP(PRFileDesc);
+	if (NULL == fd)
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	else
+	{
+		fd->methods = &pl_methods;
+		fd->dtor = pl_FDDestructor;
+		fd->identity = PR_IO_LAYER_HEAD;
+		fd->higher = NULL;
+		fd->lower = top;
+		top->higher = fd;
+		top->lower = NULL;
+	}
+    return fd;
+}  /* PR_CreateIOLayer */
+
+/*
+ * _PR_DestroyIOLayer
+ *		Delete the stack head of a new style stack.
+ */
+
+static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack)
+{
+    if (NULL == stack)
+        return PR_FAILURE;
+    else {
+        PR_DELETE(stack);
+    	return PR_SUCCESS;
+    }
+}  /* _PR_DestroyIOLayer */
+
+PR_IMPLEMENT(PRStatus) PR_PushIOLayer(
+    PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd)
+{
+    PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id);
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(stack != NULL);
+    PR_ASSERT(insert != NULL);
+    PR_ASSERT(PR_IO_LAYER_HEAD != id);
+    if ((NULL == stack) || (NULL == fd) || (NULL == insert))
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    if (stack == insert)
+    {
+		/* going on top of the stack */
+		/* old-style stack */	
+		PRFileDesc copy = *stack;
+		*stack = *fd;
+		*fd = copy;
+		fd->higher = stack;
+		stack->lower = fd;
+		stack->higher = NULL;
+	} else {
+        /*
+		 * going somewhere in the middle of the stack for both old and new
+		 * style stacks, or going on top of stack for new style stack
+		 */
+        fd->lower = insert;
+        fd->higher = insert->higher;
+
+        insert->higher->lower = fd;
+        insert->higher = fd;
+    }
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id)
+{
+    PRFileDesc *extract = PR_GetIdentitiesLayer(stack, id);
+
+    PR_ASSERT(0 != id);
+    PR_ASSERT(NULL != stack);
+    PR_ASSERT(NULL != extract);
+    if ((NULL == stack) || (0 == id) || (NULL == extract))
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return NULL;
+    }
+
+    if (extract == stack) {
+        /* popping top layer of the stack */
+		/* old style stack */
+        PRFileDesc copy = *stack;
+        extract = stack->lower;
+        *stack = *extract;
+        *extract = copy;
+        stack->higher = NULL;
+	} else if ((PR_IO_LAYER_HEAD == stack->identity) &&
+					(extract == stack->lower) && (extract->lower == NULL)) {
+			/*
+			 * new style stack
+			 * popping the only layer in the stack; delete the stack too
+			 */
+			stack->lower = NULL;
+			_PR_DestroyIOLayer(stack);
+	} else {
+		/* for both kinds of stacks */
+        extract->lower->higher = extract->higher;
+        extract->higher->lower = extract->lower;
+    }
+    extract->higher = extract->lower = NULL;
+    return extract;
+}  /* PR_PopIOLayer */
+
+#define ID_CACHE_INCREMENT 16
+typedef struct _PRIdentity_cache
+{
+    PRLock *ml;
+    char **name;
+    PRIntn length;
+    PRDescIdentity ident;
+} _PRIdentity_cache;
+
+static _PRIdentity_cache identity_cache;
+
+PR_IMPLEMENT(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name)
+{
+    PRDescIdentity identity, length;
+    char **names = NULL, *name = NULL, **old = NULL;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    PR_ASSERT((PRDescIdentity)0x7fff > identity_cache.ident);
+
+    if (NULL != layer_name)
+    {
+        name = (char*)PR_Malloc(strlen(layer_name) + 1);
+        if (NULL == name)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return PR_INVALID_IO_LAYER;
+        }
+        strcpy(name, layer_name);
+    }
+
+    /* this initial code runs unsafe */
+retry:
+    PR_ASSERT(NULL == names);
+    length = identity_cache.length;
+    if (length < (identity_cache.ident + 1))
+    {
+        length += ID_CACHE_INCREMENT;
+        names = (char**)PR_CALLOC(length * sizeof(char*));
+        if (NULL == names)
+        {
+            if (NULL != name) PR_DELETE(name);
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return PR_INVALID_IO_LAYER;
+        }
+    }
+
+    /* now we get serious about thread safety */
+    PR_Lock(identity_cache.ml);
+    PR_ASSERT(identity_cache.ident <= identity_cache.length);
+    identity = identity_cache.ident + 1;
+    if (identity > identity_cache.length)  /* there's no room */
+    {
+        /* we have to do something - hopefully it's already done */
+        if ((NULL != names) && (length >= identity))
+        {
+            /* what we did is still okay */
+            memcpy(
+                names, identity_cache.name,
+                identity_cache.length * sizeof(char*));
+            old = identity_cache.name;
+            identity_cache.name = names;
+            identity_cache.length = length;
+            names = NULL;
+        }
+        else
+        {
+            PR_ASSERT(identity_cache.ident <= identity_cache.length);
+            PR_Unlock(identity_cache.ml);
+            if (NULL != names) PR_DELETE(names);
+            goto retry;
+        }
+    }
+    if (NULL != name) /* there's a name to be stored */
+    {
+        identity_cache.name[identity] = name;
+    }
+    identity_cache.ident = identity;
+    PR_ASSERT(identity_cache.ident <= identity_cache.length);
+    PR_Unlock(identity_cache.ml);
+
+    if (NULL != old) PR_DELETE(old);
+    if (NULL != names) PR_DELETE(names);
+
+    return identity;
+}  /* PR_GetUniqueIdentity */
+
+PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (PR_TOP_IO_LAYER == ident) return NULL;
+
+    PR_ASSERT(ident <= identity_cache.ident);
+    return (ident > identity_cache.ident) ? NULL : identity_cache.name[ident];
+}  /* PR_GetNameForIdentity */
+
+PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd)
+{
+    PR_ASSERT(NULL != fd);
+    if (PR_IO_LAYER_HEAD == fd->identity) {
+    	PR_ASSERT(NULL != fd->lower);
+    	return fd->lower->identity;
+	} else
+    	return fd->identity;
+}  /* PR_GetLayersIdentity */
+
+PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id)
+{
+    PRFileDesc *layer = fd;
+
+    if (PR_TOP_IO_LAYER == id) {
+    	if (PR_IO_LAYER_HEAD == fd->identity)
+			return fd->lower;
+		else 
+			return fd;
+	}
+
+    for (layer = fd; layer != NULL; layer = layer->lower)
+    {
+        if (id == layer->identity) return layer;
+    }
+    for (layer = fd; layer != NULL; layer = layer->higher)
+    {
+        if (id == layer->identity) return layer;
+    }
+    return NULL;
+}  /* PR_GetIdentitiesLayer */
+
+void _PR_InitLayerCache(void)
+{
+    memset(&identity_cache, 0, sizeof(identity_cache));
+    identity_cache.ml = PR_NewLock();
+    PR_ASSERT(NULL != identity_cache.ml);
+}  /* _PR_InitLayerCache */
+
+void _PR_CleanupLayerCache(void)
+{
+    if (identity_cache.ml)
+    {
+        PR_DestroyLock(identity_cache.ml);
+        identity_cache.ml = NULL;
+    }
+
+    if (identity_cache.name)
+    {
+        PRDescIdentity ident;
+
+        for (ident = 0; ident <= identity_cache.ident; ident++)
+            PR_DELETE(identity_cache.name[ident]);
+
+        PR_DELETE(identity_cache.name);
+    }
+}  /* _PR_CleanupLayerCache */
+
+/* prlayer.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prlog.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prlog.c
new file mode 100644
index 0000000..8a79601
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prlog.c
@@ -0,0 +1,564 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   IBM Corporation
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include "prenv.h"
+#include "prprf.h"
+#include <string.h>
+
+/*
+ * Lock used to lock the log.
+ *
+ * We can't define _PR_LOCK_LOG simply as PR_Lock because PR_Lock may
+ * contain assertions.  We have to avoid assertions in _PR_LOCK_LOG
+ * because PR_ASSERT calls PR_LogPrint, which in turn calls _PR_LOCK_LOG.
+ * This can lead to infinite recursion.
+ */
+static PRLock *_pr_logLock;
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+#define _PR_LOCK_LOG() PR_Lock(_pr_logLock);
+#define _PR_UNLOCK_LOG() PR_Unlock(_pr_logLock);
+#elif defined(_PR_GLOBAL_THREADS_ONLY)
+#define _PR_LOCK_LOG() { _PR_LOCK_LOCK(_pr_logLock)
+#define _PR_UNLOCK_LOG() _PR_LOCK_UNLOCK(_pr_logLock); }
+#else
+
+#define _PR_LOCK_LOG() \
+{ \
+    PRIntn _is; \
+    PRThread *_me = _PR_MD_CURRENT_THREAD(); \
+    if (!_PR_IS_NATIVE_THREAD(_me)) \
+        _PR_INTSOFF(_is); \
+    _PR_LOCK_LOCK(_pr_logLock)
+
+#define _PR_UNLOCK_LOG() \
+    _PR_LOCK_UNLOCK(_pr_logLock); \
+    PR_ASSERT(_me == _PR_MD_CURRENT_THREAD()); \
+    if (!_PR_IS_NATIVE_THREAD(_me)) \
+        _PR_INTSON(_is); \
+}
+
+#endif
+
+#if defined(XP_PC)
+#define strcasecmp stricmp
+#endif
+
+/*
+ * On NT, we can't define _PUT_LOG as PR_Write or _PR_MD_WRITE,
+ * because every asynchronous file io operation leads to a fiber context
+ * switch.  So we define _PUT_LOG as fputs (from stdio.h).  A side
+ * benefit is that fputs handles the LF->CRLF translation.  This
+ * code can also be used on other platforms with file stream io.
+ */
+#if defined(WIN32) || defined(XP_OS2)
+#define _PR_USE_STDIO_FOR_LOGGING
+#endif
+
+/*
+** Coerce Win32 log output to use OutputDebugString() when
+** NSPR_LOG_FILE is set to "WinDebug".
+*/
+#if defined(XP_PC)
+#define WIN32_DEBUG_FILE (FILE*)-2
+#endif
+
+#ifdef WINCE
+static void OutputDebugStringA(const char* msg) {
+    int len = MultiByteToWideChar(CP_ACP, 0, msg, -1, 0, 0);
+    WCHAR *wMsg = (WCHAR *)PR_Malloc(len * sizeof(WCHAR));
+    MultiByteToWideChar(CP_ACP, 0, msg, -1, wMsg, len);
+    OutputDebugStringW(wMsg);
+    PR_Free(wMsg);
+}
+#endif
+
+/* Macros used to reduce #ifdef pollution */
+
+#if defined(_PR_USE_STDIO_FOR_LOGGING) && defined(XP_PC)
+#define _PUT_LOG(fd, buf, nb) \
+    PR_BEGIN_MACRO \
+    if (logFile == WIN32_DEBUG_FILE) { \
+        char savebyte = buf[nb]; \
+        buf[nb] = '\0'; \
+        OutputDebugStringA(buf); \
+        buf[nb] = savebyte; \
+    } else { \
+        fwrite(buf, 1, nb, fd); \
+        fflush(fd); \
+    } \
+    PR_END_MACRO
+#elif defined(_PR_USE_STDIO_FOR_LOGGING)
+#define _PUT_LOG(fd, buf, nb) {fwrite(buf, 1, nb, fd); fflush(fd);}
+#elif defined(_PR_PTHREADS)
+#define _PUT_LOG(fd, buf, nb) PR_Write(fd, buf, nb)
+#else
+#define _PUT_LOG(fd, buf, nb) _PR_MD_WRITE(fd, buf, nb)
+#endif
+
+/************************************************************************/
+
+static PRLogModuleInfo *logModules;
+
+static char *logBuf = NULL;
+static char *logp;
+static char *logEndp;
+#ifdef _PR_USE_STDIO_FOR_LOGGING
+static FILE *logFile = NULL;
+#else
+static PRFileDesc *logFile = 0;
+#endif
+static PRBool outputTimeStamp = PR_FALSE;
+
+#define LINE_BUF_SIZE           512
+#define DEFAULT_BUF_SIZE        16384
+
+#ifdef _PR_NEED_STRCASECMP
+
+/*
+ * strcasecmp is defined in /usr/ucblib/libucb.a on some platforms
+ * such as NCR and Unixware.  Linking with both libc and libucb
+ * may cause some problem, so I just provide our own implementation
+ * of strcasecmp here.
+ */
+
+static const unsigned char uc[] =
+{
+    '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+    '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+    '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+    '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+    ' ',    '!',    '"',    '#',    '$',    '%',    '&',    '\'',
+    '(',    ')',    '*',    '+',    ',',    '-',    '.',    '/',
+    '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',
+    '8',    '9',    ':',    ';',    '<',    '=',    '>',    '?',
+    '@',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
+    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
+    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
+    'X',    'Y',    'Z',    '[',    '\\',   ']',    '^',    '_',
+    '`',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
+    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
+    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
+    'X',    'Y',    'Z',    '{',    '|',    '}',    '~',    '\177'
+};
+
+PRIntn strcasecmp(const char *a, const char *b)
+{
+    const unsigned char *ua = (const unsigned char *)a;
+    const unsigned char *ub = (const unsigned char *)b;
+
+    if( ((const char *)0 == a) || (const char *)0 == b ) 
+        return (PRIntn)(a-b);
+
+    while( (uc[*ua] == uc[*ub]) && ('\0' != *a) )
+    {
+        a++;
+        ua++;
+        ub++;
+    }
+
+    return (PRIntn)(uc[*ua] - uc[*ub]);
+}
+
+#endif /* _PR_NEED_STRCASECMP */
+
+void _PR_InitLog(void)
+{
+    char *ev;
+
+    _pr_logLock = PR_NewLock();
+
+    ev = PR_GetEnv("NSPR_LOG_MODULES");
+    if (ev && ev[0]) {
+        char module[64];  /* Security-Critical: If you change this
+                           * size, you must also change the sscanf
+                           * format string to be size-1.
+                           */
+        PRBool isSync = PR_FALSE;
+        PRIntn evlen = strlen(ev), pos = 0;
+        PRInt32 bufSize = DEFAULT_BUF_SIZE;
+        while (pos < evlen) {
+            PRIntn level = 1, count = 0, delta = 0;
+            count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n",
+                           module, &delta, &level, &delta);
+            pos += delta;
+            if (count == 0) break;
+
+            /*
+            ** If count == 2, then we got module and level. If count
+            ** == 1, then level defaults to 1 (module enabled).
+            */
+            if (strcasecmp(module, "sync") == 0) {
+                isSync = PR_TRUE;
+            } else if (strcasecmp(module, "bufsize") == 0) {
+                if (level >= LINE_BUF_SIZE) {
+                    bufSize = level;
+                }
+            } else if (strcasecmp(module, "timestamp") == 0) {
+                outputTimeStamp = PR_TRUE;
+            } else {
+                PRLogModuleInfo *lm = logModules;
+                PRBool skip_modcheck =
+                    (0 == strcasecmp (module, "all")) ? PR_TRUE : PR_FALSE;
+
+                while (lm != NULL) {
+                    if (skip_modcheck) lm -> level = (PRLogModuleLevel)level;
+                    else if (strcasecmp(module, lm->name) == 0) {
+                        lm->level = (PRLogModuleLevel)level;
+                        break;
+                    }
+                    lm = lm->next;
+                }
+            }
+            /*found:*/
+            count = sscanf(&ev[pos], " , %n", &delta);
+            pos += delta;
+            if (count == EOF) break;
+        }
+        PR_SetLogBuffering(isSync ? 0 : bufSize);
+
+#ifdef XP_UNIX
+        if ((getuid() != geteuid()) || (getgid() != getegid())) {
+            return;
+        }
+#endif /* XP_UNIX */
+
+        ev = PR_GetEnv("NSPR_LOG_FILE");
+        if (ev && ev[0]) {
+            if (!PR_SetLogFile(ev)) {
+#ifdef XP_PC
+                char* str = PR_smprintf("Unable to create nspr log file '%s'\n", ev);
+                if (str) {
+                    OutputDebugStringA(str);
+                    PR_smprintf_free(str);
+                }
+#else
+                fprintf(stderr, "Unable to create nspr log file '%s'\n", ev);
+#endif
+            }
+        } else {
+#ifdef _PR_USE_STDIO_FOR_LOGGING
+            logFile = stderr;
+#else
+            logFile = _pr_stderr;
+#endif
+        }
+    }
+}
+
+void _PR_LogCleanup(void)
+{
+    PRLogModuleInfo *lm = logModules;
+
+    PR_LogFlush();
+
+#ifdef _PR_USE_STDIO_FOR_LOGGING
+    if (logFile
+        && logFile != stdout
+        && logFile != stderr
+#ifdef XP_PC
+        && logFile != WIN32_DEBUG_FILE
+#endif
+        ) {
+        fclose(logFile);
+    }
+#else
+    if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) {
+        PR_Close(logFile);
+    }
+#endif
+    logFile = NULL;
+
+    if (logBuf)
+        PR_DELETE(logBuf);
+
+    while (lm != NULL) {
+        PRLogModuleInfo *next = lm->next;
+        free((/*const*/ char *)lm->name);
+        PR_Free(lm);
+        lm = next;
+    }
+    logModules = NULL;
+
+    if (_pr_logLock) {
+        PR_DestroyLock(_pr_logLock);
+        _pr_logLock = NULL;
+    }
+}
+
+static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm )
+{
+    char *ev;
+
+    ev = PR_GetEnv("NSPR_LOG_MODULES");
+    if (ev && ev[0]) {
+        char module[64];  /* Security-Critical: If you change this
+                           * size, you must also change the sscanf
+                           * format string to be size-1.
+                           */
+        PRIntn evlen = strlen(ev), pos = 0;
+        while (pos < evlen) {
+            PRIntn level = 1, count = 0, delta = 0;
+
+            count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n",
+                           module, &delta, &level, &delta);
+            pos += delta;
+            if (count == 0) break;
+
+            /*
+            ** If count == 2, then we got module and level. If count
+            ** == 1, then level defaults to 1 (module enabled).
+            */
+            if (lm != NULL)
+            {
+                if ((strcasecmp(module, "all") == 0)
+                    || (strcasecmp(module, lm->name) == 0))
+                {
+                    lm->level = (PRLogModuleLevel)level;
+                }
+            }
+            count = sscanf(&ev[pos], " , %n", &delta);
+            pos += delta;
+            if (count == EOF) break;
+        }
+    }
+} /* end _PR_SetLogModuleLevel() */
+
+PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name)
+{
+    PRLogModuleInfo *lm;
+
+        if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    lm = PR_NEWZAP(PRLogModuleInfo);
+    if (lm) {
+        lm->name = strdup(name);
+        lm->level = PR_LOG_NONE;
+        lm->next = logModules;
+        logModules = lm;
+        _PR_SetLogModuleLevel(lm);
+    }
+    return lm;
+}
+
+PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file)
+{
+#ifdef _PR_USE_STDIO_FOR_LOGGING
+    FILE *newLogFile;
+
+#ifdef XP_PC
+    if ( strcmp( file, "WinDebug") == 0)
+    {
+        newLogFile = WIN32_DEBUG_FILE;
+    }
+    else
+#endif
+    {
+        newLogFile = fopen(file, "w");
+        if (!newLogFile)
+            return PR_FALSE;
+
+#ifndef WINCE  /* _IONBF does not exist in the Windows Mobile 6 SDK. */
+        /* We do buffering ourselves. */
+        setvbuf(newLogFile, NULL, _IONBF, 0);
+#endif
+    }
+    if (logFile
+        && logFile != stdout
+        && logFile != stderr
+#ifdef XP_PC
+        && logFile != WIN32_DEBUG_FILE
+#endif
+        ) {
+        fclose(logFile);
+    }
+    logFile = newLogFile;
+    return PR_TRUE;
+#else
+    PRFileDesc *newLogFile;
+
+    newLogFile = PR_Open(file, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0666);
+    if (newLogFile) {
+        if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) {
+            PR_Close(logFile);
+        }
+        logFile = newLogFile;
+    }
+    return (PRBool) (newLogFile != 0);
+#endif /* _PR_USE_STDIO_FOR_LOGGING */
+}
+
+PR_IMPLEMENT(void) PR_SetLogBuffering(PRIntn buffer_size)
+{
+    PR_LogFlush();
+
+    if (logBuf)
+        PR_DELETE(logBuf);
+
+    if (buffer_size >= LINE_BUF_SIZE) {
+        logp = logBuf = (char*) PR_MALLOC(buffer_size);
+        logEndp = logp + buffer_size;
+    }
+}
+
+PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...)
+{
+    va_list ap;
+    char line[LINE_BUF_SIZE];
+    char *line_long = NULL;
+    PRUint32 nb_tid = 0, nb;
+    PRThread *me;
+    PRExplodedTime now;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (!logFile) {
+        return;
+    }
+
+    if (outputTimeStamp) {
+        PR_ExplodeTime(PR_Now(), PR_GMTParameters, &now);
+        nb_tid = PR_snprintf(line, sizeof(line)-1,
+                             "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC - ",
+                             now.tm_year, now.tm_month + 1, now.tm_mday,
+                             now.tm_hour, now.tm_min, now.tm_sec,
+                             now.tm_usec);
+    }
+
+    me = PR_GetCurrentThread();
+    nb_tid += PR_snprintf(line+nb_tid, sizeof(line)-nb_tid-1, "%ld[%p]: ",
+#if defined(_PR_BTHREADS)
+                          me, me);
+#else
+                          me ? me->id : 0L, me);
+#endif
+
+    va_start(ap, fmt);
+    nb = nb_tid + PR_vsnprintf(line+nb_tid, sizeof(line)-nb_tid-1, fmt, ap);
+    va_end(ap);
+
+    /*
+     * Check if we might have run out of buffer space (in case we have a
+     * long line), and malloc a buffer just this once.
+     */
+    if (nb == sizeof(line)-2) {
+        va_start(ap, fmt);
+        line_long = PR_vsmprintf(fmt, ap);
+        va_end(ap);
+        /* If this failed, we'll fall back to writing the truncated line. */
+    }
+
+    if (line_long) {
+        nb = strlen(line_long);
+        _PR_LOCK_LOG();
+        if (logBuf != 0) {
+            _PUT_LOG(logFile, logBuf, logp - logBuf);
+            logp = logBuf;
+        }
+        /*
+         * Write out the thread id (with an optional timestamp) and the
+         * malloc'ed buffer.
+         */
+        _PUT_LOG(logFile, line, nb_tid);
+        _PUT_LOG(logFile, line_long, nb);
+        /* Ensure there is a trailing newline. */
+        if (!nb || (line_long[nb-1] != '\n')) {
+            char eol[2];
+            eol[0] = '\n';
+            eol[1] = '\0';
+            _PUT_LOG(logFile, eol, 1);
+        }
+        _PR_UNLOCK_LOG();
+        PR_smprintf_free(line_long);
+    } else {
+        /* Ensure there is a trailing newline. */
+        if (nb && (line[nb-1] != '\n')) {
+            line[nb++] = '\n';
+            line[nb] = '\0';
+        }
+        _PR_LOCK_LOG();
+        if (logBuf == 0) {
+            _PUT_LOG(logFile, line, nb);
+        } else {
+            /* If nb can't fit into logBuf, write out logBuf first. */
+            if (logp + nb > logEndp) {
+                _PUT_LOG(logFile, logBuf, logp - logBuf);
+                logp = logBuf;
+            }
+            /* nb is guaranteed to fit into logBuf. */
+            memcpy(logp, line, nb);
+            logp += nb;
+        }
+        _PR_UNLOCK_LOG();
+    }
+    PR_LogFlush();
+}
+
+PR_IMPLEMENT(void) PR_LogFlush(void)
+{
+    if (logBuf && logFile) {
+        _PR_LOCK_LOG();
+            if (logp > logBuf) {
+                _PUT_LOG(logFile, logBuf, logp - logBuf);
+                logp = logBuf;
+            }
+        _PR_UNLOCK_LOG();
+    }
+}
+
+PR_IMPLEMENT(void) PR_Abort(void)
+{
+    PR_LogPrint("Aborting");
+    abort();
+}
+
+PR_IMPLEMENT(void) PR_Assert(const char *s, const char *file, PRIntn ln)
+{
+    PR_LogPrint("Assertion failure: %s, at %s:%d\n", s, file, ln);
+#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+    fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
+#endif
+#ifdef WIN32
+    DebugBreak();
+#endif
+#ifdef XP_OS2
+    asm("int $3");
+#endif
+    abort();
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmapopt.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmapopt.c
new file mode 100644
index 0000000..04501b0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmapopt.c
@@ -0,0 +1,495 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This file defines _PR_MapOptionName().  The purpose of putting
+ * _PR_MapOptionName() in a separate file is to work around a Winsock
+ * header file problem on Windows NT.
+ *
+ * On Windows NT, if we define _WIN32_WINNT to be 0x0400 (in order
+ * to use Service Pack 3 extensions), windows.h includes winsock2.h
+ * (instead of winsock.h), which doesn't define many socket options
+ * defined in winsock.h.
+ *
+ * We need the socket options defined in winsock.h.  So this file
+ * includes winsock.h, with _WIN32_WINNT undefined.
+ */
+
+#if defined(WINNT) || defined(__MINGW32__)
+#include <winsock.h>
+#endif
+
+/* MinGW doesn't define these in its winsock.h. */
+#ifdef __MINGW32__
+#ifndef IP_TTL
+#define IP_TTL 7
+#endif
+#ifndef IP_TOS
+#define IP_TOS 8
+#endif
+#endif
+
+#include "primpl.h"
+
+#if defined(NEXTSTEP)
+/* NEXTSTEP is special: this must come before netinet/tcp.h. */
+#include <netinet/in_systm.h>  /* n_short, n_long, n_time */
+#endif
+
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>  /* TCP_NODELAY, TCP_MAXSEG */
+#endif
+
+#ifndef _PR_PTHREADS
+
+PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
+{
+    PRStatus rv;
+    PRInt32 length;
+    PRInt32 level, name;
+
+    /*
+     * PR_SockOpt_Nonblocking is a special case that does not
+     * translate to a getsockopt() call
+     */
+    if (PR_SockOpt_Nonblocking == data->option)
+    {
+        data->value.non_blocking = fd->secret->nonblocking;
+        return PR_SUCCESS;
+    }
+
+    rv = _PR_MapOptionName(data->option, &level, &name);
+    if (PR_SUCCESS == rv)
+    {
+        switch (data->option)
+        {
+            case PR_SockOpt_Linger:
+            {
+#if !defined(XP_BEOS) || defined(BONE_VERSION)
+                struct linger linger;
+                length = sizeof(linger);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char *) &linger, &length);
+                if (PR_SUCCESS == rv)
+                {
+                    PR_ASSERT(sizeof(linger) == length);
+                    data->value.linger.polarity =
+                        (linger.l_onoff) ? PR_TRUE : PR_FALSE;
+                    data->value.linger.linger =
+                        PR_SecondsToInterval(linger.l_linger);
+                }
+                break;
+#else
+                PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+                return PR_FAILURE;
+#endif
+            }
+            case PR_SockOpt_Reuseaddr:
+            case PR_SockOpt_Keepalive:
+            case PR_SockOpt_NoDelay:
+            case PR_SockOpt_Broadcast:
+            {
+#ifdef WIN32 /* Winsock */
+                BOOL value;
+#else
+                PRIntn value;
+#endif
+                length = sizeof(value);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&value, &length);
+                if (PR_SUCCESS == rv)
+                    data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
+                break;
+            }
+            case PR_SockOpt_McastLoopback:
+            {
+#ifdef WIN32 /* Winsock */
+                BOOL bool;
+#else
+                PRUint8 bool;
+#endif
+                length = sizeof(bool);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&bool, &length);
+                if (PR_SUCCESS == rv)
+                    data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE;
+                break;
+            }
+            case PR_SockOpt_RecvBufferSize:
+            case PR_SockOpt_SendBufferSize:
+            case PR_SockOpt_MaxSegment:
+            {
+                PRIntn value;
+                length = sizeof(value);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&value, &length);
+                if (PR_SUCCESS == rv)
+                    data->value.recv_buffer_size = value;
+                break;
+            }
+            case PR_SockOpt_IpTimeToLive:
+            case PR_SockOpt_IpTypeOfService:
+            {
+                /* These options should really be an int (or PRIntn). */
+                length = sizeof(PRUintn);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&data->value.ip_ttl, &length);
+                break;
+            }
+            case PR_SockOpt_McastTimeToLive:
+            {
+#ifdef WIN32 /* Winsock */
+                int ttl;
+#else
+                PRUint8 ttl;
+#endif
+                length = sizeof(ttl);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&ttl, &length);
+                if (PR_SUCCESS == rv)
+                    data->value.mcast_ttl = ttl;
+                break;
+            }
+#ifdef IP_ADD_MEMBERSHIP
+            case PR_SockOpt_AddMember:
+            case PR_SockOpt_DropMember:
+            {
+                struct ip_mreq mreq;
+                length = sizeof(mreq);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&mreq, &length);
+                if (PR_SUCCESS == rv)
+                {
+                    data->value.add_member.mcaddr.inet.ip =
+                        mreq.imr_multiaddr.s_addr;
+                    data->value.add_member.ifaddr.inet.ip =
+                        mreq.imr_interface.s_addr;
+                }
+                break;
+            }
+#endif /* IP_ADD_MEMBERSHIP */
+            case PR_SockOpt_McastInterface:
+            {
+                /* This option is a struct in_addr. */
+                length = sizeof(data->value.mcast_if.inet.ip);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name,
+                    (char*)&data->value.mcast_if.inet.ip, &length);
+                break;
+            }
+            default:
+                PR_NOT_REACHED("Unknown socket option");
+                break;
+        }  
+    }
+    return rv;
+}  /* _PR_SocketGetSocketOption */
+
+PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data)
+{
+    PRStatus rv;
+    PRInt32 level, name;
+
+    /*
+     * PR_SockOpt_Nonblocking is a special case that does not
+     * translate to a setsockopt call.
+     */
+    if (PR_SockOpt_Nonblocking == data->option)
+    {
+#ifdef WINNT
+        PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE)
+            || (fd->secret->nonblocking == data->value.non_blocking));
+        if (fd->secret->md.io_model_committed
+            && (fd->secret->nonblocking != data->value.non_blocking))
+        {
+            /*
+             * 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 = data->value.non_blocking;
+        return PR_SUCCESS;
+    }
+
+    rv = _PR_MapOptionName(data->option, &level, &name);
+    if (PR_SUCCESS == rv)
+    {
+        switch (data->option)
+        {
+            case PR_SockOpt_Linger:
+            {
+#if !defined(XP_BEOS) || defined(BONE_VERSION)
+                struct linger linger;
+                linger.l_onoff = data->value.linger.polarity;
+                linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&linger, sizeof(linger));
+                break;
+#else
+                PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+                return PR_FAILURE;
+#endif
+            }
+            case PR_SockOpt_Reuseaddr:
+            case PR_SockOpt_Keepalive:
+            case PR_SockOpt_NoDelay:
+            case PR_SockOpt_Broadcast:
+            {
+#ifdef WIN32 /* Winsock */
+                BOOL value;
+#else
+                PRIntn value;
+#endif
+                value = (data->value.reuse_addr) ? 1 : 0;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&value, sizeof(value));
+                break;
+            }
+            case PR_SockOpt_McastLoopback:
+            {
+#ifdef WIN32 /* Winsock */
+                BOOL bool;
+#else
+                PRUint8 bool;
+#endif
+                bool = data->value.mcast_loopback ? 1 : 0;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&bool, sizeof(bool));
+                break;
+            }
+            case PR_SockOpt_RecvBufferSize:
+            case PR_SockOpt_SendBufferSize:
+            case PR_SockOpt_MaxSegment:
+            {
+                PRIntn value = data->value.recv_buffer_size;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&value, sizeof(value));
+                break;
+            }
+            case PR_SockOpt_IpTimeToLive:
+            case PR_SockOpt_IpTypeOfService:
+            {
+                /* These options should really be an int (or PRIntn). */
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&data->value.ip_ttl, sizeof(PRUintn));
+                break;
+            }
+            case PR_SockOpt_McastTimeToLive:
+            {
+#ifdef WIN32 /* Winsock */
+                int ttl;
+#else
+                PRUint8 ttl;
+#endif
+                ttl = data->value.mcast_ttl;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&ttl, sizeof(ttl));
+                break;
+            }
+#ifdef IP_ADD_MEMBERSHIP
+            case PR_SockOpt_AddMember:
+            case PR_SockOpt_DropMember:
+            {
+                struct ip_mreq mreq;
+                mreq.imr_multiaddr.s_addr =
+                    data->value.add_member.mcaddr.inet.ip;
+                mreq.imr_interface.s_addr =
+                    data->value.add_member.ifaddr.inet.ip;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&mreq, sizeof(mreq));
+                break;
+            }
+#endif /* IP_ADD_MEMBERSHIP */
+            case PR_SockOpt_McastInterface:
+            {
+                /* This option is a struct in_addr. */
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&data->value.mcast_if.inet.ip,
+                    sizeof(data->value.mcast_if.inet.ip));
+                break;
+            }
+            default:
+                PR_NOT_REACHED("Unknown socket option");
+                break;
+        }  
+    }
+    return rv;
+}  /* _PR_SocketSetSocketOption */
+
+#endif /* ! _PR_PTHREADS */
+
+/*
+ *********************************************************************
+ *********************************************************************
+ **
+ ** Make sure that the following is at the end of this file,
+ ** because we will be playing with macro redefines.
+ **
+ *********************************************************************
+ *********************************************************************
+ */
+
+/*
+ * Not every platform has all the socket options we want to
+ * support.  Some older operating systems such as SunOS 4.1.3
+ * don't have the IP multicast socket options.  Win32 doesn't
+ * have TCP_MAXSEG.
+ *
+ * To deal with this problem, we define the missing socket
+ * options as _PR_NO_SUCH_SOCKOPT.  _PR_MapOptionName() fails with
+ * PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not
+ * available on the platform is requested.
+ */
+
+/*
+ * Sanity check.  SO_LINGER and TCP_NODELAY should be available
+ * on all platforms.  Just to make sure we have included the
+ * appropriate header files.  Then any undefined socket options
+ * are really missing.
+ */
+
+#if !defined(SO_LINGER)
+#error "SO_LINGER is not defined"
+#endif
+
+/*
+ * Some platforms, such as NCR 2.03, don't have TCP_NODELAY defined
+ * in <netinet/tcp.h>
+ */
+#if !defined(NCR)
+#if !defined(TCP_NODELAY)
+#error "TCP_NODELAY is not defined"
+#endif
+#endif
+
+/*
+ * Make sure the value of _PR_NO_SUCH_SOCKOPT is not
+ * a valid socket option.
+ */
+#define _PR_NO_SUCH_SOCKOPT -1
+
+#ifndef SO_KEEPALIVE
+#define SO_KEEPALIVE        _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef SO_SNDBUF
+#define SO_SNDBUF           _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef SO_RCVBUF
+#define SO_RCVBUF           _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_MULTICAST_IF                 /* set/get IP multicast interface   */
+#define IP_MULTICAST_IF     _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_MULTICAST_TTL                /* set/get IP multicast timetolive  */
+#define IP_MULTICAST_TTL    _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_MULTICAST_LOOP               /* set/get IP multicast loopback    */
+#define IP_MULTICAST_LOOP   _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_ADD_MEMBERSHIP               /* add  an IP group membership      */
+#define IP_ADD_MEMBERSHIP   _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_DROP_MEMBERSHIP              /* drop an IP group membership      */
+#define IP_DROP_MEMBERSHIP  _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_TTL                          /* set/get IP Time To Live          */
+#define IP_TTL              _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_TOS                          /* set/get IP Type Of Service       */
+#define IP_TOS              _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef TCP_NODELAY                     /* don't delay to coalesce data     */
+#define TCP_NODELAY         _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef TCP_MAXSEG                      /* maxumum segment size for tcp     */
+#define TCP_MAXSEG          _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef SO_BROADCAST                 /* enable broadcast on udp sockets */
+#define SO_BROADCAST        _PR_NO_SUCH_SOCKOPT
+#endif
+
+PRStatus _PR_MapOptionName(
+    PRSockOption optname, PRInt32 *level, PRInt32 *name)
+{
+    static PRInt32 socketOptions[PR_SockOpt_Last] =
+    {
+        0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF,
+        IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
+        IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP,
+        TCP_NODELAY, TCP_MAXSEG, SO_BROADCAST
+    };
+    static PRInt32 socketLevels[PR_SockOpt_Last] =
+    {
+        0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET,
+        IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
+        IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
+        IPPROTO_TCP, IPPROTO_TCP, SOL_SOCKET
+    };
+
+    if ((optname < PR_SockOpt_Linger)
+    || (optname >= PR_SockOpt_Last))
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT)
+    {
+        PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
+        return PR_FAILURE;
+    }
+    *name = socketOptions[optname];
+    *level = socketLevels[optname];
+    return PR_SUCCESS;
+}  /* _PR_MapOptionName */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmmap.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmmap.c
new file mode 100644
index 0000000..e5c1e5d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmmap.c
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *********************************************************************
+ *
+ * Memory-mapped files
+ *
+ *********************************************************************
+ */
+
+#include "primpl.h"
+
+PR_IMPLEMENT(PRFileMap *) PR_CreateFileMap(
+    PRFileDesc *fd,
+    PRInt64 size,
+    PRFileMapProtect prot)
+{
+    PRFileMap *fmap;
+
+    PR_ASSERT(prot == PR_PROT_READONLY || prot == PR_PROT_READWRITE
+            || prot == PR_PROT_WRITECOPY);
+    fmap = PR_NEWZAP(PRFileMap);
+    if (NULL == fmap) {
+	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	return NULL;
+    }
+    fmap->fd = fd;
+    fmap->prot = prot;
+    if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) {
+	return fmap;
+    } else {
+	PR_DELETE(fmap);
+	return NULL;
+    }
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void)
+{
+    return _PR_MD_GET_MEM_MAP_ALIGNMENT();
+}
+
+PR_IMPLEMENT(void *) PR_MemMap(
+    PRFileMap *fmap,
+    PROffset64 offset,
+    PRUint32 len)
+{
+    return _PR_MD_MEM_MAP(fmap, offset, len);
+}
+
+PR_IMPLEMENT(PRStatus) PR_MemUnmap(void *addr, PRUint32 len)
+{
+    return _PR_MD_MEM_UNMAP(addr, len);
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseFileMap(PRFileMap *fmap)
+{
+    return _PR_MD_CLOSE_FILE_MAP(fmap);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmwait.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmwait.c
new file mode 100644
index 0000000..5b30f69
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prmwait.c
@@ -0,0 +1,1488 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include "pprmwait.h"
+
+#define _MW_REHASH_MAX 11
+
+static PRLock *mw_lock = NULL;
+static _PRGlobalState *mw_state = NULL;
+
+static PRIntervalTime max_polling_interval;
+
+#ifdef WINNT
+
+typedef struct TimerEvent {
+    PRIntervalTime absolute;
+    void (*func)(void *);
+    void *arg;
+    LONG ref_count;
+    PRCList links;
+} TimerEvent;
+
+#define TIMER_EVENT_PTR(_qp) \
+    ((TimerEvent *) ((char *) (_qp) - offsetof(TimerEvent, links)))
+
+struct {
+    PRLock *ml;
+    PRCondVar *new_timer;
+    PRCondVar *cancel_timer;
+    PRThread *manager_thread;
+    PRCList timer_queue;
+} tm_vars;
+
+static PRStatus TimerInit(void);
+static void TimerManager(void *arg);
+static TimerEvent *CreateTimer(PRIntervalTime timeout,
+    void (*func)(void *), void *arg);
+static PRBool CancelTimer(TimerEvent *timer);
+
+static void TimerManager(void *arg)
+{
+    PRIntervalTime now;
+    PRIntervalTime timeout;
+    PRCList *head;
+    TimerEvent *timer;
+
+    PR_Lock(tm_vars.ml);
+    while (1)
+    {
+        if (PR_CLIST_IS_EMPTY(&tm_vars.timer_queue))
+        {
+            PR_WaitCondVar(tm_vars.new_timer, PR_INTERVAL_NO_TIMEOUT);
+        }
+        else
+        {
+            now = PR_IntervalNow();
+            head = PR_LIST_HEAD(&tm_vars.timer_queue);
+            timer = TIMER_EVENT_PTR(head);
+            if ((PRInt32) (now - timer->absolute) >= 0)
+            {
+                PR_REMOVE_LINK(head);
+                /*
+                 * make its prev and next point to itself so that
+                 * it's obvious that it's not on the timer_queue.
+                 */
+                PR_INIT_CLIST(head);
+                PR_ASSERT(2 == timer->ref_count);
+                PR_Unlock(tm_vars.ml);
+                timer->func(timer->arg);
+                PR_Lock(tm_vars.ml);
+                timer->ref_count -= 1;
+                if (0 == timer->ref_count)
+                {
+                    PR_NotifyAllCondVar(tm_vars.cancel_timer);
+                }
+            }
+            else
+            {
+                timeout = (PRIntervalTime)(timer->absolute - now);
+                PR_WaitCondVar(tm_vars.new_timer, timeout);
+            } 
+        }
+    }
+    PR_Unlock(tm_vars.ml);
+}
+
+static TimerEvent *CreateTimer(
+    PRIntervalTime timeout,
+    void (*func)(void *),
+    void *arg)
+{
+    TimerEvent *timer;
+    PRCList *links, *tail;
+    TimerEvent *elem;
+
+    timer = PR_NEW(TimerEvent);
+    if (NULL == timer)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return timer;
+    }
+    timer->absolute = PR_IntervalNow() + timeout;
+    timer->func = func;
+    timer->arg = arg;
+    timer->ref_count = 2;
+    PR_Lock(tm_vars.ml);
+    tail = links = PR_LIST_TAIL(&tm_vars.timer_queue);
+    while (links->prev != tail)
+    {
+        elem = TIMER_EVENT_PTR(links);
+        if ((PRInt32)(timer->absolute - elem->absolute) >= 0)
+        {
+            break;
+        }
+        links = links->prev;
+    }
+    PR_INSERT_AFTER(&timer->links, links);
+    PR_NotifyCondVar(tm_vars.new_timer);
+    PR_Unlock(tm_vars.ml);
+    return timer;
+}
+
+static PRBool CancelTimer(TimerEvent *timer)
+{
+    PRBool canceled = PR_FALSE;
+
+    PR_Lock(tm_vars.ml);
+    timer->ref_count -= 1;
+    if (timer->links.prev == &timer->links)
+    {
+        while (timer->ref_count == 1)
+        {
+            PR_WaitCondVar(tm_vars.cancel_timer, PR_INTERVAL_NO_TIMEOUT);
+        }
+    }
+    else
+    {
+        PR_REMOVE_LINK(&timer->links);
+        canceled = PR_TRUE;
+    }
+    PR_Unlock(tm_vars.ml);
+    PR_DELETE(timer);
+    return canceled; 
+}
+
+static PRStatus TimerInit(void)
+{
+    tm_vars.ml = PR_NewLock();
+    if (NULL == tm_vars.ml)
+    {
+        goto failed;
+    }
+    tm_vars.new_timer = PR_NewCondVar(tm_vars.ml);
+    if (NULL == tm_vars.new_timer)
+    {
+        goto failed;
+    }
+    tm_vars.cancel_timer = PR_NewCondVar(tm_vars.ml);
+    if (NULL == tm_vars.cancel_timer)
+    {
+        goto failed;
+    }
+    PR_INIT_CLIST(&tm_vars.timer_queue);
+    tm_vars.manager_thread = PR_CreateThread(
+        PR_SYSTEM_THREAD, TimerManager, NULL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+    if (NULL == tm_vars.manager_thread)
+    {
+        goto failed;
+    }
+    return PR_SUCCESS;
+
+failed:
+    if (NULL != tm_vars.cancel_timer)
+    {
+        PR_DestroyCondVar(tm_vars.cancel_timer);
+    }
+    if (NULL != tm_vars.new_timer)
+    {
+        PR_DestroyCondVar(tm_vars.new_timer);
+    }
+    if (NULL != tm_vars.ml)
+    {
+        PR_DestroyLock(tm_vars.ml);
+    }
+    return PR_FAILURE;
+}
+
+#endif /* WINNT */
+
+/******************************************************************/
+/******************************************************************/
+/************************ The private portion *********************/
+/******************************************************************/
+/******************************************************************/
+void _PR_InitMW(void)
+{
+#ifdef WINNT
+    /*
+     * We use NT 4's InterlockedCompareExchange() to operate
+     * on PRMWStatus variables.
+     */
+    PR_ASSERT(sizeof(LONG) == sizeof(PRMWStatus));
+    TimerInit();
+#endif
+    mw_lock = PR_NewLock();
+    PR_ASSERT(NULL != mw_lock);
+    mw_state = PR_NEWZAP(_PRGlobalState);
+    PR_ASSERT(NULL != mw_state);
+    PR_INIT_CLIST(&mw_state->group_list);
+    max_polling_interval = PR_MillisecondsToInterval(MAX_POLLING_INTERVAL);
+}  /* _PR_InitMW */
+
+void _PR_CleanupMW(void)
+{
+    PR_DestroyLock(mw_lock);
+    mw_lock = NULL;
+    if (mw_state->group) {
+        PR_DestroyWaitGroup(mw_state->group);
+        /* mw_state->group is set to NULL as a side effect. */
+    }
+    PR_DELETE(mw_state);
+}  /* _PR_CleanupMW */
+
+static PRWaitGroup *MW_Init2(void)
+{
+    PRWaitGroup *group = mw_state->group;  /* it's the null group */
+    if (NULL == group)  /* there is this special case */
+    {
+        group = PR_CreateWaitGroup(_PR_DEFAULT_HASH_LENGTH);
+        if (NULL == group) goto failed_alloc;
+        PR_Lock(mw_lock);
+        if (NULL == mw_state->group)
+        {
+            mw_state->group = group;
+            group = NULL;
+        }
+        PR_Unlock(mw_lock);
+        if (group != NULL) (void)PR_DestroyWaitGroup(group);
+        group = mw_state->group;  /* somebody beat us to it */
+    }
+failed_alloc:
+    return group;  /* whatever */
+}  /* MW_Init2 */
+
+static _PR_HashStory MW_AddHashInternal(PRRecvWait *desc, _PRWaiterHash *hash)
+{
+    /*
+    ** The entries are put in the table using the fd (PRFileDesc*) of
+    ** the receive descriptor as the key. This allows us to locate
+    ** the appropriate entry aqain when the poll operation finishes.
+    **
+    ** The pointer to the file descriptor object is first divided by
+    ** the natural alignment of a pointer in the belief that object
+    ** will have at least that many zeros in the low order bits.
+    ** This may not be a good assuption.
+    **
+    ** We try to put the entry in by rehashing _MW_REHASH_MAX times. After
+    ** that we declare defeat and force the table to be reconstructed.
+    ** Since some fds might be added more than once, won't that cause
+    ** collisions even in an empty table?
+    */
+    PRIntn rehash = _MW_REHASH_MAX;
+    PRRecvWait **waiter;
+    PRUintn hidx = _MW_HASH(desc->fd, hash->length);
+    PRUintn hoffset = 0;
+
+    while (rehash-- > 0)
+    {
+        waiter = &hash->recv_wait;
+        if (NULL == waiter[hidx])
+        {
+            waiter[hidx] = desc;
+            hash->count += 1;
+#if 0
+            printf("Adding 0x%x->0x%x ", desc, desc->fd);
+            printf(
+                "table[%u:%u:*%u]: 0x%x->0x%x\n",
+                hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd);
+#endif
+            return _prmw_success;
+        }
+        if (desc == waiter[hidx])
+        {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);  /* desc already in table */
+            return _prmw_error;
+        }
+#if 0
+        printf("Failing 0x%x->0x%x ", desc, desc->fd);
+        printf(
+            "table[*%u:%u:%u]: 0x%x->0x%x\n",
+            hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd);
+#endif
+        if (0 == hoffset)
+        {
+            hoffset = _MW_HASH2(desc->fd, hash->length);
+            PR_ASSERT(0 != hoffset);
+        }
+        hidx = (hidx + hoffset) % (hash->length);
+    }
+    return _prmw_rehash;    
+}  /* MW_AddHashInternal */
+
+static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group)
+{
+    PRRecvWait **desc;
+    PRUint32 pidx, length;
+    _PRWaiterHash *newHash, *oldHash = group->waiter;
+    PRBool retry;
+    _PR_HashStory hrv;
+
+    static const PRInt32 prime_number[] = {
+        _PR_DEFAULT_HASH_LENGTH, 179, 521, 907, 1427,
+        2711, 3917, 5021, 8219, 11549, 18911, 26711, 33749, 44771};
+    PRUintn primes = (sizeof(prime_number) / sizeof(PRInt32));
+
+    /* look up the next size we'd like to use for the hash table */
+    for (pidx = 0; pidx < primes; ++pidx)
+    {
+        if (prime_number[pidx] == oldHash->length)
+        {
+            break;
+        }
+    }
+    /* table size must be one of the prime numbers */
+    PR_ASSERT(pidx < primes);
+
+    /* if pidx == primes - 1, we can't expand the table any more */
+    while (pidx < primes - 1)
+    {
+        /* next size */
+        ++pidx;
+        length = prime_number[pidx];
+
+        /* allocate the new hash table and fill it in with the old */
+        newHash = (_PRWaiterHash*)PR_CALLOC(
+            sizeof(_PRWaiterHash) + (length * sizeof(PRRecvWait*)));
+        if (NULL == newHash)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return _prmw_error;
+        }
+
+        newHash->length = length;
+        retry = PR_FALSE;
+        for (desc = &oldHash->recv_wait;
+            newHash->count < oldHash->count; ++desc)
+        {
+            PR_ASSERT(desc < &oldHash->recv_wait + oldHash->length);
+            if (NULL != *desc)
+            {
+                hrv = MW_AddHashInternal(*desc, newHash);
+                PR_ASSERT(_prmw_error != hrv);
+                if (_prmw_success != hrv)
+                {
+                    PR_DELETE(newHash);
+                    retry = PR_TRUE;
+                    break;
+                }
+            }
+        }
+        if (retry) continue;
+
+        PR_DELETE(group->waiter);
+        group->waiter = newHash;
+        group->p_timestamp += 1;
+        return _prmw_success;
+    }
+
+    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    return _prmw_error;  /* we're hosed */
+}  /* MW_ExpandHashInternal */
+
+#ifndef WINNT
+static void _MW_DoneInternal(
+    PRWaitGroup *group, PRRecvWait **waiter, PRMWStatus outcome)
+{
+    /*
+    ** Add this receive wait object to the list of finished I/O
+    ** operations for this particular group. If there are other
+    ** threads waiting on the group, notify one. If not, arrange
+    ** for this thread to return.
+    */
+
+#if 0
+    printf("Removing 0x%x->0x%x\n", *waiter, (*waiter)->fd);
+#endif
+    (*waiter)->outcome = outcome;
+    PR_APPEND_LINK(&((*waiter)->internal), &group->io_ready);
+    PR_NotifyCondVar(group->io_complete);
+    PR_ASSERT(0 != group->waiter->count);
+    group->waiter->count -= 1;
+    *waiter = NULL;
+}  /* _MW_DoneInternal */
+#endif /* WINNT */
+
+static PRRecvWait **_MW_LookupInternal(PRWaitGroup *group, PRFileDesc *fd)
+{
+    /*
+    ** Find the receive wait object corresponding to the file descriptor.
+    ** Only search the wait group specified.
+    */
+    PRRecvWait **desc;
+    PRIntn rehash = _MW_REHASH_MAX;
+    _PRWaiterHash *hash = group->waiter;
+    PRUintn hidx = _MW_HASH(fd, hash->length);
+    PRUintn hoffset = 0;
+    
+    while (rehash-- > 0)
+    {
+        desc = (&hash->recv_wait) + hidx;
+        if ((*desc != NULL) && ((*desc)->fd == fd)) return desc;
+        if (0 == hoffset)
+        {
+            hoffset = _MW_HASH2(fd, hash->length);
+            PR_ASSERT(0 != hoffset);
+        }
+        hidx = (hidx + hoffset) % (hash->length);
+    }
+    return NULL;
+}  /* _MW_LookupInternal */
+
+#ifndef WINNT
+static PRStatus _MW_PollInternal(PRWaitGroup *group)
+{
+    PRRecvWait **waiter;
+    PRStatus rv = PR_FAILURE;
+    PRInt32 count, count_ready;
+    PRIntervalTime polling_interval;
+
+    group->poller = PR_GetCurrentThread();
+
+    while (PR_TRUE)
+    {
+        PRIntervalTime now, since_last_poll;
+        PRPollDesc *poll_list;
+
+        while (0 == group->waiter->count)
+        {
+            PRStatus st;
+            st = PR_WaitCondVar(group->new_business, PR_INTERVAL_NO_TIMEOUT);
+            if (_prmw_running != group->state)
+            {
+                PR_SetError(PR_INVALID_STATE_ERROR, 0);
+                goto aborted;
+            }
+            if (_MW_ABORTED(st)) goto aborted;
+        }
+
+        /*
+        ** There's something to do. See if our existing polling list
+        ** is large enough for what we have to do?
+        */
+
+        while (group->polling_count < group->waiter->count)
+        {
+            PRUint32 old_count = group->waiter->count;
+            PRUint32 new_count = PR_ROUNDUP(old_count, _PR_POLL_COUNT_FUDGE);
+            PRSize new_size = sizeof(PRPollDesc) * new_count;
+            PRPollDesc *old_polling_list = group->polling_list;
+
+            PR_Unlock(group->ml);
+            poll_list = (PRPollDesc*)PR_CALLOC(new_size);
+            if (NULL == poll_list)
+            {
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                PR_Lock(group->ml);
+                goto failed_alloc;
+            }
+            if (NULL != old_polling_list)
+                PR_DELETE(old_polling_list);
+            PR_Lock(group->ml);
+            if (_prmw_running != group->state)
+            {
+                PR_SetError(PR_INVALID_STATE_ERROR, 0);
+                goto aborted;
+            }
+            group->polling_list = poll_list;
+            group->polling_count = new_count;
+        }
+
+        now = PR_IntervalNow();
+        polling_interval = max_polling_interval;
+        since_last_poll = now - group->last_poll;
+
+        waiter = &group->waiter->recv_wait;
+        poll_list = group->polling_list;
+        for (count = 0; count < group->waiter->count; ++waiter)
+        {
+            PR_ASSERT(waiter < &group->waiter->recv_wait
+                + group->waiter->length);
+            if (NULL != *waiter)  /* a live one! */
+            {
+                if ((PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout)
+                && (since_last_poll >= (*waiter)->timeout))
+                    _MW_DoneInternal(group, waiter, PR_MW_TIMEOUT);
+                else
+                {
+                    if (PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout)
+                    {
+                        (*waiter)->timeout -= since_last_poll;
+                        if ((*waiter)->timeout < polling_interval)
+                            polling_interval = (*waiter)->timeout;
+                    }
+                    PR_ASSERT(poll_list < group->polling_list
+                        + group->polling_count);
+                    poll_list->fd = (*waiter)->fd;
+                    poll_list->in_flags = PR_POLL_READ;
+                    poll_list->out_flags = 0;
+#if 0
+                    printf(
+                        "Polling 0x%x[%d]: [fd: 0x%x, tmo: %u]\n",
+                        poll_list, count, poll_list->fd, (*waiter)->timeout);
+#endif
+                    poll_list += 1;
+                    count += 1;
+                }
+            }
+        } 
+
+        PR_ASSERT(count == group->waiter->count);
+
+        /*
+        ** If there are no more threads waiting for completion,
+        ** we need to return.
+        */
+        if ((!PR_CLIST_IS_EMPTY(&group->io_ready))
+        && (1 == group->waiting_threads)) break;
+
+        if (0 == count) continue;  /* wait for new business */
+
+        group->last_poll = now;
+
+        PR_Unlock(group->ml);
+
+        count_ready = PR_Poll(group->polling_list, count, polling_interval);
+
+        PR_Lock(group->ml);
+
+        if (_prmw_running != group->state)
+        {
+            PR_SetError(PR_INVALID_STATE_ERROR, 0);
+            goto aborted;
+        }
+        if (-1 == count_ready)
+        {
+            goto failed_poll;  /* that's a shame */
+        }
+        else if (0 < count_ready)
+        {
+            for (poll_list = group->polling_list; count > 0;
+            poll_list++, count--)
+            {
+                PR_ASSERT(
+                    poll_list < group->polling_list + group->polling_count);
+                if (poll_list->out_flags != 0)
+                {
+                    waiter = _MW_LookupInternal(group, poll_list->fd);
+                    /*
+                    ** If 'waiter' is NULL, that means the wait receive
+                    ** descriptor has been canceled.
+                    */
+                    if (NULL != waiter)
+                        _MW_DoneInternal(group, waiter, PR_MW_SUCCESS);
+                }
+            }
+        }
+        /*
+        ** If there are no more threads waiting for completion,
+        ** we need to return.
+        ** This thread was "borrowed" to do the polling, but it really
+        ** belongs to the client.
+        */
+        if ((!PR_CLIST_IS_EMPTY(&group->io_ready))
+        && (1 == group->waiting_threads)) break;
+    }
+
+    rv = PR_SUCCESS;
+
+aborted:
+failed_poll:
+failed_alloc:
+    group->poller = NULL;  /* we were that, not we ain't */
+    if ((_prmw_running == group->state) && (group->waiting_threads > 1))
+    {
+        /* Wake up one thread to become the new poller. */
+        PR_NotifyCondVar(group->io_complete);
+    }
+    return rv;  /* we return with the lock held */
+}  /* _MW_PollInternal */
+#endif /* !WINNT */
+
+static PRMWGroupState MW_TestForShutdownInternal(PRWaitGroup *group)
+{
+    PRMWGroupState rv = group->state;
+    /*
+    ** Looking at the group's fields is safe because
+    ** once the group's state is no longer running, it
+    ** cannot revert and there is a safe check on entry
+    ** to make sure no more threads are made to wait.
+    */
+    if ((_prmw_stopping == rv)
+    && (0 == group->waiting_threads))
+    {
+        rv = group->state = _prmw_stopped;
+        PR_NotifyCondVar(group->mw_manage);
+    }
+    return rv;
+}  /* MW_TestForShutdownInternal */
+
+#ifndef WINNT
+static void _MW_InitialRecv(PRCList *io_ready)
+{
+    PRRecvWait *desc = (PRRecvWait*)io_ready;
+    if ((NULL == desc->buffer.start)
+    || (0 == desc->buffer.length))
+        desc->bytesRecv = 0;
+    else
+    {
+        desc->bytesRecv = (desc->fd->methods->recv)(
+            desc->fd, desc->buffer.start,
+            desc->buffer.length, 0, desc->timeout);
+        if (desc->bytesRecv < 0)  /* SetError should already be there */
+            desc->outcome = PR_MW_FAILURE;
+    }
+}  /* _MW_InitialRecv */
+#endif
+
+#ifdef WINNT
+static void NT_TimeProc(void *arg)
+{
+    _MDOverlapped *overlapped = (_MDOverlapped *)arg;
+    PRRecvWait *desc =  overlapped->data.mw.desc;
+    PRFileDesc *bottom;
+    
+    if (InterlockedCompareExchange((LONG *)&desc->outcome,
+        (LONG)PR_MW_TIMEOUT, (LONG)PR_MW_PENDING) != (LONG)PR_MW_PENDING)
+    {
+        /* This wait recv descriptor has already completed. */
+        return;
+    }
+
+    /* close the osfd to abort the outstanding async io request */
+    /* $$$$
+    ** Little late to be checking if NSPR's on the bottom of stack,
+    ** but if we don't check, we can't assert that the private data
+    ** is what we think it is.
+    ** $$$$
+    */
+    bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER);
+    PR_ASSERT(NULL != bottom);
+    if (NULL != bottom)  /* now what!?!?! */
+    {
+        bottom->secret->state = _PR_FILEDESC_CLOSED;
+        if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR)
+        {
+            fprintf(stderr, "closesocket failed: %d\n", WSAGetLastError());
+            PR_ASSERT(!"What shall I do?");
+        }
+    }
+    return;
+}  /* NT_TimeProc */
+
+static PRStatus NT_HashRemove(PRWaitGroup *group, PRFileDesc *fd)
+{
+    PRRecvWait **waiter;
+
+    _PR_MD_LOCK(&group->mdlock);
+    waiter = _MW_LookupInternal(group, fd);
+    if (NULL != waiter)
+    {
+        group->waiter->count -= 1;
+        *waiter = NULL;
+    }
+    _PR_MD_UNLOCK(&group->mdlock);
+    return (NULL != waiter) ? PR_SUCCESS : PR_FAILURE;
+}
+
+PRStatus NT_HashRemoveInternal(PRWaitGroup *group, PRFileDesc *fd)
+{
+    PRRecvWait **waiter;
+
+    waiter = _MW_LookupInternal(group, fd);
+    if (NULL != waiter)
+    {
+        group->waiter->count -= 1;
+        *waiter = NULL;
+    }
+    return (NULL != waiter) ? PR_SUCCESS : PR_FAILURE;
+}
+#endif /* WINNT */
+
+/******************************************************************/
+/******************************************************************/
+/********************** The public API portion ********************/
+/******************************************************************/
+/******************************************************************/
+PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc(
+    PRWaitGroup *group, PRRecvWait *desc)
+{
+    _PR_HashStory hrv;
+    PRStatus rv = PR_FAILURE;
+#ifdef WINNT
+    _MDOverlapped *overlapped;
+    HANDLE hFile;
+    BOOL bResult;
+    DWORD dwError;
+    PRFileDesc *bottom;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if ((NULL == group) && (NULL == (group = MW_Init2())))
+    {
+        return rv;
+    }
+
+    PR_ASSERT(NULL != desc->fd);
+
+    desc->outcome = PR_MW_PENDING;  /* nice, well known value */
+    desc->bytesRecv = 0;  /* likewise, though this value is ambiguious */
+
+    PR_Lock(group->ml);
+
+    if (_prmw_running != group->state)
+    {
+        /* Not allowed to add after cancelling the group */
+        desc->outcome = PR_MW_INTERRUPT;
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        PR_Unlock(group->ml);
+        return rv;
+    }
+
+#ifdef WINNT
+    _PR_MD_LOCK(&group->mdlock);
+#endif
+
+    /*
+    ** If the waiter count is zero at this point, there's no telling
+    ** how long we've been idle. Therefore, initialize the beginning
+    ** of the timing interval. As long as the list doesn't go empty,
+    ** it will maintain itself.
+    */
+    if (0 == group->waiter->count)
+        group->last_poll = PR_IntervalNow();
+
+    do
+    {
+        hrv = MW_AddHashInternal(desc, group->waiter);
+        if (_prmw_rehash != hrv) break;
+        hrv = MW_ExpandHashInternal(group);  /* gruesome */
+        if (_prmw_success != hrv) break;
+    } while (PR_TRUE);
+
+#ifdef WINNT
+    _PR_MD_UNLOCK(&group->mdlock);
+#endif
+
+    PR_NotifyCondVar(group->new_business);  /* tell the world */
+    rv = (_prmw_success == hrv) ? PR_SUCCESS : PR_FAILURE;
+    PR_Unlock(group->ml);
+
+#ifdef WINNT
+    overlapped = PR_NEWZAP(_MDOverlapped);
+    if (NULL == overlapped)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        NT_HashRemove(group, desc->fd);
+        return rv;
+    }
+    overlapped->ioModel = _MD_MultiWaitIO;
+    overlapped->data.mw.desc = desc;
+    overlapped->data.mw.group = group;
+    if (desc->timeout != PR_INTERVAL_NO_TIMEOUT)
+    {
+        overlapped->data.mw.timer = CreateTimer(
+            desc->timeout,
+            NT_TimeProc,
+            overlapped);
+        if (0 == overlapped->data.mw.timer)
+        {
+            NT_HashRemove(group, desc->fd);
+            PR_DELETE(overlapped);
+            /*
+             * XXX It appears that a maximum of 16 timer events can
+             * be outstanding. GetLastError() returns 0 when I try it.
+             */
+            PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, GetLastError());
+            return PR_FAILURE;
+        }
+    }
+
+    /* Reach to the bottom layer to get the OS fd */
+    bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER);
+    PR_ASSERT(NULL != bottom);
+    if (NULL == bottom)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    hFile = (HANDLE)bottom->secret->md.osfd; 
+    if (!bottom->secret->md.io_model_committed)
+    {
+        PRInt32 st;
+        st = _md_Associate(hFile);
+        PR_ASSERT(0 != st);
+        bottom->secret->md.io_model_committed = PR_TRUE;
+    }
+    bResult = ReadFile(hFile,
+        desc->buffer.start,
+        (DWORD)desc->buffer.length,
+        NULL,
+        &overlapped->overlapped);
+    if (FALSE == bResult && (dwError = GetLastError()) != ERROR_IO_PENDING)
+    {
+        if (desc->timeout != PR_INTERVAL_NO_TIMEOUT)
+        {
+            if (InterlockedCompareExchange((LONG *)&desc->outcome,
+                (LONG)PR_MW_FAILURE, (LONG)PR_MW_PENDING)
+                == (LONG)PR_MW_PENDING)
+            {
+                CancelTimer(overlapped->data.mw.timer);
+            }
+            NT_HashRemove(group, desc->fd);
+            PR_DELETE(overlapped);
+        }
+        _PR_MD_MAP_READ_ERROR(dwError);
+        rv = PR_FAILURE;
+    }
+#endif
+
+    return rv;
+}  /* PR_AddWaitFileDesc */
+
+PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
+{
+    PRCList *io_ready = NULL;
+#ifdef WINNT
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    _MDOverlapped *overlapped;    
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if ((NULL == group) && (NULL == (group = MW_Init2()))) goto failed_init;
+
+    PR_Lock(group->ml);
+
+    if (_prmw_running != group->state)
+    {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        goto invalid_state;
+    }
+
+    group->waiting_threads += 1;  /* the polling thread is counted */
+
+#ifdef WINNT
+    _PR_MD_LOCK(&group->mdlock);
+    while (PR_CLIST_IS_EMPTY(&group->io_ready))
+    {
+        _PR_THREAD_LOCK(me);
+        me->state = _PR_IO_WAIT;
+        PR_APPEND_LINK(&me->waitQLinks, &group->wait_list);
+        if (!_PR_IS_NATIVE_THREAD(me))
+        {
+            _PR_SLEEPQ_LOCK(me->cpu);
+            _PR_ADD_SLEEPQ(me, PR_INTERVAL_NO_TIMEOUT);
+            _PR_SLEEPQ_UNLOCK(me->cpu);
+        }
+        _PR_THREAD_UNLOCK(me);
+        _PR_MD_UNLOCK(&group->mdlock);
+        PR_Unlock(group->ml);
+        _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+        me->state = _PR_RUNNING;
+        PR_Lock(group->ml);
+        _PR_MD_LOCK(&group->mdlock);
+        if (_PR_PENDING_INTERRUPT(me)) {
+            PR_REMOVE_LINK(&me->waitQLinks);
+            _PR_MD_UNLOCK(&group->mdlock);
+            me->flags &= ~_PR_INTERRUPT;
+            me->io_suspended = PR_FALSE;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+            goto aborted;
+        }
+    }
+    io_ready = PR_LIST_HEAD(&group->io_ready);
+    PR_ASSERT(io_ready != NULL);
+    PR_REMOVE_LINK(io_ready);
+    _PR_MD_UNLOCK(&group->mdlock);
+    overlapped = (_MDOverlapped *)
+        ((char *)io_ready - offsetof(_MDOverlapped, data));
+    io_ready = &overlapped->data.mw.desc->internal;
+#else
+    do
+    {
+        /*
+        ** If the I/O ready list isn't empty, have this thread
+        ** return with the first receive wait object that's available.
+        */
+        if (PR_CLIST_IS_EMPTY(&group->io_ready))
+        {
+            /*
+            ** Is there a polling thread yet? If not, grab this thread
+            ** and use it.
+            */
+            if (NULL == group->poller)
+            {
+                /*
+                ** This thread will stay do polling until it becomes the only one
+                ** left to service a completion. Then it will return and there will
+                ** be none left to actually poll or to run completions.
+                **
+                ** The polling function should only return w/ failure or
+                ** with some I/O ready.
+                */
+                if (PR_FAILURE == _MW_PollInternal(group)) goto failed_poll;
+            }
+            else
+            {
+                /*
+                ** There are four reasons a thread can be awakened from
+                ** a wait on the io_complete condition variable.
+                ** 1. Some I/O has completed, i.e., the io_ready list
+                **    is nonempty.
+                ** 2. The wait group is canceled.
+                ** 3. The thread is interrupted.
+                ** 4. The current polling thread has to leave and needs
+                **    a replacement.
+                ** The logic to find a new polling thread is made more
+                ** complicated by all the other possible events.
+                ** I tried my best to write the logic clearly, but
+                ** it is still full of if's with continue and goto.
+                */
+                PRStatus st;
+                do 
+                {
+                    st = PR_WaitCondVar(group->io_complete, PR_INTERVAL_NO_TIMEOUT);
+                    if (_prmw_running != group->state)
+                    {
+                        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+                        goto aborted;
+                    }
+                    if (_MW_ABORTED(st) || (NULL == group->poller)) break;
+                } while (PR_CLIST_IS_EMPTY(&group->io_ready));
+
+                /*
+                ** The thread is interrupted and has to leave.  It might
+                ** have also been awakened to process ready i/o or be the
+                ** new poller.  To be safe, if either condition is true,
+                ** we awaken another thread to take its place.
+                */
+                if (_MW_ABORTED(st))
+                {
+                    if ((NULL == group->poller
+                    || !PR_CLIST_IS_EMPTY(&group->io_ready))
+                    && group->waiting_threads > 1)
+                        PR_NotifyCondVar(group->io_complete);
+                    goto aborted;
+                }
+
+                /*
+                ** A new poller is needed, but can I be the new poller?
+                ** If there is no i/o ready, sure.  But if there is any
+                ** i/o ready, it has a higher priority.  I want to
+                ** process the ready i/o first and wake up another
+                ** thread to be the new poller.
+                */ 
+                if (NULL == group->poller)
+                {
+                    if (PR_CLIST_IS_EMPTY(&group->io_ready))
+                        continue;
+                    if (group->waiting_threads > 1)
+                        PR_NotifyCondVar(group->io_complete);
+                }
+            }
+            PR_ASSERT(!PR_CLIST_IS_EMPTY(&group->io_ready));
+        }
+        io_ready = PR_LIST_HEAD(&group->io_ready);
+        PR_NotifyCondVar(group->io_taken);
+        PR_ASSERT(io_ready != NULL);
+        PR_REMOVE_LINK(io_ready);
+    } while (NULL == io_ready);
+
+failed_poll:
+
+#endif
+
+aborted:
+
+    group->waiting_threads -= 1;
+invalid_state:
+    (void)MW_TestForShutdownInternal(group);
+    PR_Unlock(group->ml);
+
+failed_init:
+    if (NULL != io_ready)
+    {
+        /* If the operation failed, record the reason why */
+        switch (((PRRecvWait*)io_ready)->outcome)
+        {
+            case PR_MW_PENDING:
+                PR_ASSERT(0);
+                break;
+            case PR_MW_SUCCESS:
+#ifndef WINNT
+                _MW_InitialRecv(io_ready);
+#endif
+                break;
+#ifdef WINNT
+            case PR_MW_FAILURE:
+                _PR_MD_MAP_READ_ERROR(overlapped->data.mw.error);
+                break;
+#endif
+            case PR_MW_TIMEOUT:
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                break;
+            case PR_MW_INTERRUPT:
+                PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                break;
+            default: break;
+        }
+#ifdef WINNT
+        if (NULL != overlapped->data.mw.timer)
+        {
+            PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
+                != overlapped->data.mw.desc->timeout);
+            CancelTimer(overlapped->data.mw.timer);
+        }
+        else
+        {
+            PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
+                == overlapped->data.mw.desc->timeout);
+        }
+        PR_DELETE(overlapped);
+#endif
+    }
+    return (PRRecvWait*)io_ready;
+}  /* PR_WaitRecvReady */
+
+PR_IMPLEMENT(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc)
+{
+#if !defined(WINNT)
+    PRRecvWait **recv_wait;
+#endif
+    PRStatus rv = PR_SUCCESS;
+    if (NULL == group) group = mw_state->group;
+    PR_ASSERT(NULL != group);
+    if (NULL == group)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    PR_Lock(group->ml);
+
+    if (_prmw_running != group->state)
+    {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        rv = PR_FAILURE;
+        goto unlock;
+    }
+
+#ifdef WINNT
+    if (InterlockedCompareExchange((LONG *)&desc->outcome,
+        (LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING) == (LONG)PR_MW_PENDING)
+    {
+        PRFileDesc *bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER);
+        PR_ASSERT(NULL != bottom);
+        if (NULL == bottom)
+        {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            goto unlock;
+        }
+        bottom->secret->state = _PR_FILEDESC_CLOSED;
+#if 0
+        fprintf(stderr, "cancel wait recv: closing socket\n");
+#endif
+        if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR)
+        {
+            fprintf(stderr, "closesocket failed: %d\n", WSAGetLastError());
+            exit(1);
+        }
+    }
+#else
+    if (NULL != (recv_wait = _MW_LookupInternal(group, desc->fd)))
+    {
+        /* it was in the wait table */
+        _MW_DoneInternal(group, recv_wait, PR_MW_INTERRUPT);
+        goto unlock;
+    }
+    if (!PR_CLIST_IS_EMPTY(&group->io_ready))
+    {
+        /* is it already complete? */
+        PRCList *head = PR_LIST_HEAD(&group->io_ready);
+        do
+        {
+            PRRecvWait *done = (PRRecvWait*)head;
+            if (done == desc) goto unlock;
+            head = PR_NEXT_LINK(head);
+        } while (head != &group->io_ready);
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    rv = PR_FAILURE;
+
+#endif
+unlock:
+    PR_Unlock(group->ml);
+    return rv;
+}  /* PR_CancelWaitFileDesc */
+
+PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group)
+{
+    PRRecvWait **desc;
+    PRRecvWait *recv_wait = NULL;
+#ifdef WINNT
+    _MDOverlapped *overlapped;
+    PRRecvWait **end;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+#endif
+
+    if (NULL == group) group = mw_state->group;
+    PR_ASSERT(NULL != group);
+    if (NULL == group)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return NULL;
+    }
+
+    PR_Lock(group->ml);
+    if (_prmw_stopped != group->state)
+    {
+        if (_prmw_running == group->state)
+            group->state = _prmw_stopping;  /* so nothing new comes in */
+        if (0 == group->waiting_threads)  /* is there anybody else? */
+            group->state = _prmw_stopped;  /* we can stop right now */
+        else
+        {
+            PR_NotifyAllCondVar(group->new_business);
+            PR_NotifyAllCondVar(group->io_complete);
+        }
+        while (_prmw_stopped != group->state)
+            (void)PR_WaitCondVar(group->mw_manage, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+#ifdef WINNT
+    _PR_MD_LOCK(&group->mdlock);
+#endif
+    /* make all the existing descriptors look done/interrupted */
+#ifdef WINNT
+    end = &group->waiter->recv_wait + group->waiter->length;
+    for (desc = &group->waiter->recv_wait; desc < end; ++desc)
+    {
+        if (NULL != *desc)
+        {
+            if (InterlockedCompareExchange((LONG *)&(*desc)->outcome,
+                (LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING)
+                == (LONG)PR_MW_PENDING)
+            {
+                PRFileDesc *bottom = PR_GetIdentitiesLayer(
+                    (*desc)->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);
+                if (NULL == bottom)
+                {
+                    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+                    goto invalid_arg;
+                }
+                bottom->secret->state = _PR_FILEDESC_CLOSED;
+#if 0
+                fprintf(stderr, "cancel wait group: closing socket\n");
+#endif
+                if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR)
+                {
+                    fprintf(stderr, "closesocket failed: %d\n",
+                        WSAGetLastError());
+                    exit(1);
+                }
+            }
+        }
+    }
+    while (group->waiter->count > 0)
+    {
+        _PR_THREAD_LOCK(me);
+        me->state = _PR_IO_WAIT;
+        PR_APPEND_LINK(&me->waitQLinks, &group->wait_list);
+        if (!_PR_IS_NATIVE_THREAD(me))
+        {
+            _PR_SLEEPQ_LOCK(me->cpu);
+            _PR_ADD_SLEEPQ(me, PR_INTERVAL_NO_TIMEOUT);
+            _PR_SLEEPQ_UNLOCK(me->cpu);
+        }
+        _PR_THREAD_UNLOCK(me);
+        _PR_MD_UNLOCK(&group->mdlock);
+        PR_Unlock(group->ml);
+        _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+        me->state = _PR_RUNNING;
+        PR_Lock(group->ml);
+        _PR_MD_LOCK(&group->mdlock);
+    }
+#else
+    for (desc = &group->waiter->recv_wait; group->waiter->count > 0; ++desc)
+    {
+        PR_ASSERT(desc < &group->waiter->recv_wait + group->waiter->length);
+        if (NULL != *desc)
+            _MW_DoneInternal(group, desc, PR_MW_INTERRUPT);
+    }
+#endif
+
+    /* take first element of finished list and return it or NULL */
+    if (PR_CLIST_IS_EMPTY(&group->io_ready))
+        PR_SetError(PR_GROUP_EMPTY_ERROR, 0);
+    else
+    {
+        PRCList *head = PR_LIST_HEAD(&group->io_ready);
+        PR_REMOVE_AND_INIT_LINK(head);
+#ifdef WINNT
+        overlapped = (_MDOverlapped *)
+            ((char *)head - offsetof(_MDOverlapped, data));
+        head = &overlapped->data.mw.desc->internal;
+        if (NULL != overlapped->data.mw.timer)
+        {
+            PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
+                != overlapped->data.mw.desc->timeout);
+            CancelTimer(overlapped->data.mw.timer);
+        }
+        else
+        {
+            PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
+                == overlapped->data.mw.desc->timeout);
+        }
+        PR_DELETE(overlapped);
+#endif
+        recv_wait = (PRRecvWait*)head;
+    }
+#ifdef WINNT
+invalid_arg:
+    _PR_MD_UNLOCK(&group->mdlock);
+#endif
+    PR_Unlock(group->ml);
+
+    return recv_wait;
+}  /* PR_CancelWaitGroup */
+
+PR_IMPLEMENT(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size /* ignored */)
+{
+    PRWaitGroup *wg;
+
+    if (NULL == (wg = PR_NEWZAP(PRWaitGroup)))
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto failed;
+    }
+    /* the wait group itself */
+    wg->ml = PR_NewLock();
+    if (NULL == wg->ml) goto failed_lock;
+    wg->io_taken = PR_NewCondVar(wg->ml);
+    if (NULL == wg->io_taken) goto failed_cvar0;
+    wg->io_complete = PR_NewCondVar(wg->ml);
+    if (NULL == wg->io_complete) goto failed_cvar1;
+    wg->new_business = PR_NewCondVar(wg->ml);
+    if (NULL == wg->new_business) goto failed_cvar2;
+    wg->mw_manage = PR_NewCondVar(wg->ml);
+    if (NULL == wg->mw_manage) goto failed_cvar3;
+
+    PR_INIT_CLIST(&wg->group_link);
+    PR_INIT_CLIST(&wg->io_ready);
+
+    /* the waiters sequence */
+    wg->waiter = (_PRWaiterHash*)PR_CALLOC(
+        sizeof(_PRWaiterHash) +
+        (_PR_DEFAULT_HASH_LENGTH * sizeof(PRRecvWait*)));
+    if (NULL == wg->waiter)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto failed_waiter;
+    }
+    wg->waiter->count = 0;
+    wg->waiter->length = _PR_DEFAULT_HASH_LENGTH;
+
+#ifdef WINNT
+    _PR_MD_NEW_LOCK(&wg->mdlock);
+    PR_INIT_CLIST(&wg->wait_list);
+#endif /* WINNT */
+
+    PR_Lock(mw_lock);
+    PR_APPEND_LINK(&wg->group_link, &mw_state->group_list);
+    PR_Unlock(mw_lock);
+    return wg;
+
+failed_waiter:
+    PR_DestroyCondVar(wg->mw_manage);
+failed_cvar3:
+    PR_DestroyCondVar(wg->new_business);
+failed_cvar2:
+    PR_DestroyCondVar(wg->io_complete);
+failed_cvar1:
+    PR_DestroyCondVar(wg->io_taken);
+failed_cvar0:
+    PR_DestroyLock(wg->ml);
+failed_lock:
+    PR_DELETE(wg);
+    wg = NULL;
+
+failed:
+    return wg;
+}  /* MW_CreateWaitGroup */
+
+PR_IMPLEMENT(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group)
+{
+    PRStatus rv = PR_SUCCESS;
+    if (NULL == group) group = mw_state->group;
+    PR_ASSERT(NULL != group);
+    if (NULL != group)
+    {
+        PR_Lock(group->ml);
+        if ((group->waiting_threads == 0)
+        && (group->waiter->count == 0)
+        && PR_CLIST_IS_EMPTY(&group->io_ready))
+        {
+            group->state = _prmw_stopped;
+        }
+        else
+        {
+            PR_SetError(PR_INVALID_STATE_ERROR, 0);
+            rv = PR_FAILURE;
+        }
+        PR_Unlock(group->ml);
+        if (PR_FAILURE == rv) return rv;
+
+        PR_Lock(mw_lock);
+        PR_REMOVE_LINK(&group->group_link);
+        PR_Unlock(mw_lock);
+
+#ifdef WINNT
+        /*
+         * XXX make sure wait_list is empty and waiter is empty.
+         * These must be checked while holding mdlock.
+         */
+        _PR_MD_FREE_LOCK(&group->mdlock);
+#endif
+
+        PR_DELETE(group->waiter);
+        PR_DELETE(group->polling_list);
+        PR_DestroyCondVar(group->mw_manage);
+        PR_DestroyCondVar(group->new_business);
+        PR_DestroyCondVar(group->io_complete);
+        PR_DestroyCondVar(group->io_taken);
+        PR_DestroyLock(group->ml);
+        if (group == mw_state->group) mw_state->group = NULL;
+        PR_DELETE(group);
+    }
+    else
+    {
+        /* The default wait group is not created yet. */
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        rv = PR_FAILURE;
+    }
+    return rv;
+}  /* PR_DestroyWaitGroup */
+
+/**********************************************************************
+***********************************************************************
+******************** Wait group enumerations **************************
+***********************************************************************
+**********************************************************************/
+
+PR_IMPLEMENT(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group)
+{
+    PRMWaitEnumerator *enumerator = PR_NEWZAP(PRMWaitEnumerator);
+    if (NULL == enumerator) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    else
+    {
+        enumerator->group = group;
+        enumerator->seal = _PR_ENUM_SEALED;
+    }
+    return enumerator;
+}  /* PR_CreateMWaitEnumerator */
+
+PR_IMPLEMENT(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator)
+{
+    PR_ASSERT(NULL != enumerator);
+    PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal);
+    if ((NULL == enumerator) || (_PR_ENUM_SEALED != enumerator->seal))
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    enumerator->seal = _PR_ENUM_UNSEALED;
+    PR_Free(enumerator);
+    return PR_SUCCESS;
+}  /* PR_DestroyMWaitEnumerator */
+
+PR_IMPLEMENT(PRRecvWait*) PR_EnumerateWaitGroup(
+    PRMWaitEnumerator *enumerator, const PRRecvWait *previous)
+{
+    PRRecvWait *result = NULL;
+    
+    /* entry point sanity checking */
+    PR_ASSERT(NULL != enumerator);
+    PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal);
+    if ((NULL == enumerator)
+    || (_PR_ENUM_SEALED != enumerator->seal)) goto bad_argument;
+
+    /* beginning of enumeration */
+    if (NULL == previous)
+    {
+        if (NULL == enumerator->group)
+        {
+            enumerator->group = mw_state->group;
+            if (NULL == enumerator->group)
+            {
+                PR_SetError(PR_GROUP_EMPTY_ERROR, 0);
+                return NULL;
+            }
+        }
+        enumerator->waiter = &enumerator->group->waiter->recv_wait;
+        enumerator->p_timestamp = enumerator->group->p_timestamp;
+        enumerator->thread = PR_GetCurrentThread();
+        enumerator->index = 0;
+    }
+    /* continuing an enumeration */
+    else
+    {
+        PRThread *me = PR_GetCurrentThread();
+        PR_ASSERT(me == enumerator->thread);
+        if (me != enumerator->thread) goto bad_argument;
+
+        /* need to restart the enumeration */
+        if (enumerator->p_timestamp != enumerator->group->p_timestamp)
+            return PR_EnumerateWaitGroup(enumerator, NULL);
+    }
+
+    /* actually progress the enumeration */
+#if defined(WINNT)
+    _PR_MD_LOCK(&enumerator->group->mdlock);
+#else
+    PR_Lock(enumerator->group->ml);
+#endif
+    while (enumerator->index++ < enumerator->group->waiter->length)
+    {
+        if (NULL != (result = *(enumerator->waiter)++)) break;
+    }
+#if defined(WINNT)
+    _PR_MD_UNLOCK(&enumerator->group->mdlock);
+#else
+    PR_Unlock(enumerator->group->ml);
+#endif
+
+    return result;  /* what we live for */
+
+bad_argument:
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;  /* probably ambiguous */
+}  /* PR_EnumerateWaitGroup */
+
+/* prmwait.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prpolevt.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prpolevt.c
new file mode 100644
index 0000000..f94190d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prpolevt.c
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *********************************************************************
+ *
+ * Pollable events
+ *
+ * Pollable events are implemented using layered I/O.  The only
+ * I/O methods that are implemented for pollable events are poll
+ * and close.  No other methods can be invoked on a pollable
+ * event.
+ *
+ * A pipe or socket pair is created and the pollable event layer
+ * is pushed onto the read end.  A pointer to the write end is
+ * saved in the PRFilePrivate structure of the pollable event.
+ *
+ *********************************************************************
+ */
+
+#include "prinit.h"
+#include "prio.h"
+#include "prmem.h"
+#include "prerror.h"
+#include "prlog.h"
+
+/*
+ * These internal functions are declared in primpl.h,
+ * but we can't include primpl.h because the definition
+ * of struct PRFilePrivate in this file (for the pollable
+ * event layer) will conflict with the definition of
+ * struct PRFilePrivate in primpl.h (for the NSPR layer).
+ */
+extern PRIntn _PR_InvalidInt(void);
+extern PRInt64 _PR_InvalidInt64(void);
+extern PRStatus _PR_InvalidStatus(void);
+extern PRFileDesc *_PR_InvalidDesc(void);
+
+/*
+ * PRFilePrivate structure for the NSPR pollable events layer
+ */
+struct PRFilePrivate {
+    PRFileDesc *writeEnd;  /* the write end of the pipe/socketpair */
+};
+
+static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd);
+
+static PRInt16 PR_CALLBACK _pr_PolEvtPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
+
+static PRIOMethods _pr_polevt_methods = {
+    PR_DESC_LAYERED,
+    _pr_PolEvtClose,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    _pr_PolEvtPoll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRDescIdentity _pr_polevt_id;
+static PRCallOnceType _pr_polevt_once_control;
+static PRStatus PR_CALLBACK _pr_PolEvtInit(void);
+
+static PRInt16 PR_CALLBACK _pr_PolEvtPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags);
+}
+
+static PRStatus PR_CALLBACK _pr_PolEvtInit(void)
+{
+    _pr_polevt_id = PR_GetUniqueIdentity("NSPR pollable events");
+    if (PR_INVALID_IO_LAYER == _pr_polevt_id) {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+#if !defined(XP_UNIX)
+#define USE_TCP_SOCKETPAIR
+#endif
+
+PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
+{
+    PRFileDesc *event;
+    PRFileDesc *fd[2]; /* fd[0] is the read end; fd[1] is the write end */
+#ifdef USE_TCP_SOCKETPAIR
+    PRSocketOptionData socket_opt;
+    PRStatus rv;
+#endif
+
+    fd[0] = fd[1] = NULL;
+
+    if (PR_CallOnce(&_pr_polevt_once_control, _pr_PolEvtInit) == PR_FAILURE) {
+        return NULL;
+    }
+
+    event = PR_CreateIOLayerStub(_pr_polevt_id, &_pr_polevt_methods);
+    if (NULL == event) {
+        goto errorExit;
+    } 
+    event->secret = PR_NEW(PRFilePrivate);
+    if (event->secret == NULL) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+#ifndef USE_TCP_SOCKETPAIR
+    if (PR_CreatePipe(&fd[0], &fd[1]) == PR_FAILURE) {
+        fd[0] = fd[1] = NULL;
+        goto errorExit;
+    }
+#else
+    if (PR_NewTCPSocketPair(fd) == PR_FAILURE) {
+        fd[0] = fd[1] = NULL;
+        goto errorExit;
+    }
+	/*
+	 * set the TCP_NODELAY option to reduce notification latency
+	 */
+    socket_opt.option = PR_SockOpt_NoDelay;
+    socket_opt.value.no_delay = PR_TRUE;
+    rv = PR_SetSocketOption(fd[1], &socket_opt);
+    PR_ASSERT(PR_SUCCESS == rv);
+#endif
+
+    event->secret->writeEnd = fd[1];
+    if (PR_PushIOLayer(fd[0], PR_TOP_IO_LAYER, event) == PR_FAILURE) {
+        goto errorExit;
+    }
+
+    return fd[0];
+
+errorExit:
+    if (fd[0]) {
+        PR_Close(fd[0]);
+        PR_Close(fd[1]);
+    }
+    if (event) {
+        PR_DELETE(event->secret);
+        event->dtor(event);
+    }
+    return NULL;
+}
+
+static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd)
+{
+    PRFileDesc *event;
+
+    event = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
+    PR_ASSERT(NULL == event->higher && NULL == event->lower);
+    PR_Close(fd);
+    PR_Close(event->secret->writeEnd);
+    PR_DELETE(event->secret);
+    event->dtor(event);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
+{
+    return PR_Close(event);
+}
+
+static const char magicChar = '\x38';
+
+PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
+{
+    if (PR_Write(event->secret->writeEnd, &magicChar, 1) != 1) {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
+{
+    char buf[1024];
+    PRInt32 nBytes;
+#ifdef DEBUG
+    PRIntn i;
+#endif
+
+    nBytes = PR_Read(event->lower, buf, sizeof(buf));
+    if (nBytes == -1) {
+        return PR_FAILURE;
+    }
+
+#ifdef DEBUG
+    /*
+     * Make sure people do not write to the pollable event fd
+     * directly.
+     */
+    for (i = 0; i < nBytes; i++) {
+        PR_ASSERT(buf[i] == magicChar);
+    }
+#endif
+
+    return PR_SUCCESS;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prprf.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prprf.c
new file mode 100644
index 0000000..4e7b8d4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prprf.c
@@ -0,0 +1,1252 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Portable safe sprintf code.
+**
+** Author: Kipp E.B. Hickman
+*/
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include "primpl.h"
+#include "prprf.h"
+#include "prlong.h"
+#include "prlog.h"
+#include "prmem.h"
+
+/*
+** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it)
+*/
+
+/*
+** XXX This needs to be internationalized!
+*/
+
+typedef struct SprintfStateStr SprintfState;
+
+struct SprintfStateStr {
+    int (*stuff)(SprintfState *ss, const char *sp, PRUint32 len);
+
+    char *base;
+    char *cur;
+    PRUint32 maxlen;
+
+    int (*func)(void *arg, const char *sp, PRUint32 len);
+    void *arg;
+};
+
+/*
+** Numbered Argument
+*/
+struct NumArg {
+    int type;           /* type of the numbered argument    */
+    union {             /* the numbered argument            */
+	int i;
+	unsigned int ui;
+	PRInt32 i32;
+	PRUint32 ui32;
+	PRInt64 ll;
+	PRUint64 ull;
+	double d;
+	const char *s;
+	int *ip;
+    } u;
+};
+
+#define NAS_DEFAULT_NUM 20  /* default number of NumberedArgument array */
+
+
+#define TYPE_INT16	0
+#define TYPE_UINT16	1
+#define TYPE_INTN	2
+#define TYPE_UINTN	3
+#define TYPE_INT32	4
+#define TYPE_UINT32	5
+#define TYPE_INT64	6
+#define TYPE_UINT64	7
+#define TYPE_STRING	8
+#define TYPE_DOUBLE	9
+#define TYPE_INTSTR	10
+#define TYPE_UNKNOWN	20
+
+#define FLAG_LEFT	0x1
+#define FLAG_SIGNED	0x2
+#define FLAG_SPACED	0x4
+#define FLAG_ZEROS	0x8
+#define FLAG_NEG	0x10
+
+/*
+** Fill into the buffer using the data in src
+*/
+static int fill2(SprintfState *ss, const char *src, int srclen, int width,
+		int flags)
+{
+    char space = ' ';
+    int rv;
+
+    width -= srclen;
+    if ((width > 0) && ((flags & FLAG_LEFT) == 0)) {	/* Right adjusting */
+	if (flags & FLAG_ZEROS) {
+	    space = '0';
+	}
+	while (--width >= 0) {
+	    rv = (*ss->stuff)(ss, &space, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	}
+    }
+
+    /* Copy out the source data */
+    rv = (*ss->stuff)(ss, src, srclen);
+    if (rv < 0) {
+	return rv;
+    }
+
+    if ((width > 0) && ((flags & FLAG_LEFT) != 0)) {	/* Left adjusting */
+	while (--width >= 0) {
+	    rv = (*ss->stuff)(ss, &space, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	}
+    }
+    return 0;
+}
+
+/*
+** Fill a number. The order is: optional-sign zero-filling conversion-digits
+*/
+static int fill_n(SprintfState *ss, const char *src, int srclen, int width,
+		  int prec, int type, int flags)
+{
+    int zerowidth = 0;
+    int precwidth = 0;
+    int signwidth = 0;
+    int leftspaces = 0;
+    int rightspaces = 0;
+    int cvtwidth;
+    int rv;
+    char sign;
+
+    if ((type & 1) == 0) {
+	if (flags & FLAG_NEG) {
+	    sign = '-';
+	    signwidth = 1;
+	} else if (flags & FLAG_SIGNED) {
+	    sign = '+';
+	    signwidth = 1;
+	} else if (flags & FLAG_SPACED) {
+	    sign = ' ';
+	    signwidth = 1;
+	}
+    }
+    cvtwidth = signwidth + srclen;
+
+    if (prec > 0) {
+	if (prec > srclen) {
+	    precwidth = prec - srclen;		/* Need zero filling */
+	    cvtwidth += precwidth;
+	}
+    }
+
+    if ((flags & FLAG_ZEROS) && (prec < 0)) {
+	if (width > cvtwidth) {
+	    zerowidth = width - cvtwidth;	/* Zero filling */
+	    cvtwidth += zerowidth;
+	}
+    }
+
+    if (flags & FLAG_LEFT) {
+	if (width > cvtwidth) {
+	    /* Space filling on the right (i.e. left adjusting) */
+	    rightspaces = width - cvtwidth;
+	}
+    } else {
+	if (width > cvtwidth) {
+	    /* Space filling on the left (i.e. right adjusting) */
+	    leftspaces = width - cvtwidth;
+	}
+    }
+    while (--leftspaces >= 0) {
+	rv = (*ss->stuff)(ss, " ", 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    if (signwidth) {
+	rv = (*ss->stuff)(ss, &sign, 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    while (--precwidth >= 0) {
+	rv = (*ss->stuff)(ss, "0", 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    while (--zerowidth >= 0) {
+	rv = (*ss->stuff)(ss, "0", 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    rv = (*ss->stuff)(ss, src, srclen);
+    if (rv < 0) {
+	return rv;
+    }
+    while (--rightspaces >= 0) {
+	rv = (*ss->stuff)(ss, " ", 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    return 0;
+}
+
+/*
+** Convert a long into its printable form
+*/
+static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix,
+		 int type, int flags, const char *hexp)
+{
+    char cvtbuf[100];
+    char *cvt;
+    int digits;
+
+    /* according to the man page this needs to happen */
+    if ((prec == 0) && (num == 0)) {
+	return 0;
+    }
+
+    /*
+    ** Converting decimal is a little tricky. In the unsigned case we
+    ** need to stop when we hit 10 digits. In the signed case, we can
+    ** stop when the number is zero.
+    */
+    cvt = cvtbuf + sizeof(cvtbuf);
+    digits = 0;
+    while (num) {
+	int digit = (((unsigned long)num) % radix) & 0xF;
+	*--cvt = hexp[digit];
+	digits++;
+	num = (long)(((unsigned long)num) / radix);
+    }
+    if (digits == 0) {
+	*--cvt = '0';
+	digits++;
+    }
+
+    /*
+    ** Now that we have the number converted without its sign, deal with
+    ** the sign and zero padding.
+    */
+    return fill_n(ss, cvt, digits, width, prec, type, flags);
+}
+
+/*
+** Convert a 64-bit integer into its printable form
+*/
+static int cvt_ll(SprintfState *ss, PRInt64 num, int width, int prec, int radix,
+		  int type, int flags, const char *hexp)
+{
+    char cvtbuf[100];
+    char *cvt;
+    int digits;
+    PRInt64 rad;
+
+    /* according to the man page this needs to happen */
+    if ((prec == 0) && (LL_IS_ZERO(num))) {
+	return 0;
+    }
+
+    /*
+    ** Converting decimal is a little tricky. In the unsigned case we
+    ** need to stop when we hit 10 digits. In the signed case, we can
+    ** stop when the number is zero.
+    */
+    LL_I2L(rad, radix);
+    cvt = cvtbuf + sizeof(cvtbuf);
+    digits = 0;
+    while (!LL_IS_ZERO(num)) {
+	PRInt32 digit;
+	PRInt64 quot, rem;
+	LL_UDIVMOD(&quot, &rem, num, rad);
+	LL_L2I(digit, rem);
+	*--cvt = hexp[digit & 0xf];
+	digits++;
+	num = quot;
+    }
+    if (digits == 0) {
+	*--cvt = '0';
+	digits++;
+    }
+
+    /*
+    ** Now that we have the number converted without its sign, deal with
+    ** the sign and zero padding.
+    */
+    return fill_n(ss, cvt, digits, width, prec, type, flags);
+}
+
+/*
+** Convert a double precision floating point number into its printable
+** form.
+**
+** XXX stop using sprintf to convert floating point
+*/
+static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1)
+{
+    char fin[20];
+    char fout[300];
+    int amount = fmt1 - fmt0;
+
+    PR_ASSERT((amount > 0) && (amount < sizeof(fin)));
+    if (amount >= sizeof(fin)) {
+	/* Totally bogus % command to sprintf. Just ignore it */
+	return 0;
+    }
+    memcpy(fin, fmt0, amount);
+    fin[amount] = 0;
+
+    /* Convert floating point using the native sprintf code */
+#ifdef DEBUG
+    {
+        const char *p = fin;
+        while (*p) {
+            PR_ASSERT(*p != 'L');
+            p++;
+        }
+    }
+#endif
+    sprintf(fout, fin, d);
+
+    /*
+    ** This assert will catch overflow's of fout, when building with
+    ** debugging on. At least this way we can track down the evil piece
+    ** of calling code and fix it!
+    */
+    PR_ASSERT(strlen(fout) < sizeof(fout));
+
+    return (*ss->stuff)(ss, fout, strlen(fout));
+}
+
+/*
+** Convert a string into its printable form.  "width" is the output
+** width. "prec" is the maximum number of characters of "s" to output,
+** where -1 means until NUL.
+*/
+static int cvt_s(SprintfState *ss, const char *str, int width, int prec,
+		 int flags)
+{
+    int slen;
+
+    if (prec == 0)
+	return 0;
+
+    /* Limit string length by precision value */
+    if (!str) {
+    	str = "(null)";
+    } 
+    if (prec > 0) {
+	/* this is:  slen = strnlen(str, prec); */
+	register const char *s;
+
+	for(s = str; prec && *s; s++, prec-- )
+	    ;
+	slen = s - str;
+    } else {
+	slen = strlen(str);
+    }
+
+    /* and away we go */
+    return fill2(ss, str, slen, width, flags);
+}
+
+/*
+** BuildArgArray stands for Numbered Argument list Sprintf
+** for example,  
+**	fmp = "%4$i, %2$d, %3s, %1d";
+** the number must start from 1, and no gap among them
+*/
+
+static struct NumArg* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArg* nasArray )
+{
+    int number = 0, cn = 0, i;
+    const char* p;
+    char  c;
+    struct NumArg* nas;
+    
+
+    /*
+    **	first pass:
+    **	determine how many legal % I have got, then allocate space
+    */
+
+    p = fmt;
+    *rv = 0;
+    i = 0;
+    while( ( c = *p++ ) != 0 ){
+	if( c != '%' )
+	    continue;
+	if( ( c = *p++ ) == '%' )	/* skip %% case */
+	    continue;
+
+	while( c != 0 ){
+	    if( c > '9' || c < '0' ){
+		if( c == '$' ){		/* numbered argument case */
+		    if( i > 0 ){
+			*rv = -1;
+			return NULL;
+		    }
+		    number++;
+		} else{			/* non-numbered argument case */
+		    if( number > 0 ){
+			*rv = -1;
+			return NULL;
+		    }
+		    i = 1;
+		}
+		break;
+	    }
+
+	    c = *p++;
+	}
+    }
+
+    if( number == 0 ){
+	return NULL;
+    }
+
+    
+    if( number > NAS_DEFAULT_NUM ){
+	nas = (struct NumArg*)PR_MALLOC( number * sizeof( struct NumArg ) );
+	if( !nas ){
+	    *rv = -1;
+	    return NULL;
+	}
+    } else {
+	nas = nasArray;
+    }
+
+    for( i = 0; i < number; i++ ){
+	nas[i].type = TYPE_UNKNOWN;
+    }
+
+
+    /*
+    ** second pass:
+    ** set nas[].type
+    */
+
+    p = fmt;
+    while( ( c = *p++ ) != 0 ){
+    	if( c != '%' )	continue;
+	    c = *p++;
+	if( c == '%' )	continue;
+
+	cn = 0;
+	while( c && c != '$' ){	    /* should imporve error check later */
+	    cn = cn*10 + c - '0';
+	    c = *p++;
+	}
+
+	if( !c || cn < 1 || cn > number ){
+	    *rv = -1;
+	    break;
+        }
+
+	/* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */
+        cn--;
+	if( nas[cn].type != TYPE_UNKNOWN )
+	    continue;
+
+        c = *p++;
+
+        /* width */
+        if (c == '*') {
+	    /* not supported feature, for the argument is not numbered */
+	    *rv = -1;
+	    break;
+	}
+
+	while ((c >= '0') && (c <= '9')) {
+	    c = *p++;
+	}
+
+	/* precision */
+	if (c == '.') {
+	    c = *p++;
+	    if (c == '*') {
+	        /* not supported feature, for the argument is not numbered */
+	        *rv = -1;
+	        break;
+	    }
+
+	    while ((c >= '0') && (c <= '9')) {
+		c = *p++;
+	    }
+	}
+
+	/* size */
+	nas[cn].type = TYPE_INTN;
+	if (c == 'h') {
+	    nas[cn].type = TYPE_INT16;
+	    c = *p++;
+	} else if (c == 'L') {
+	    /* XXX not quite sure here */
+	    nas[cn].type = TYPE_INT64;
+	    c = *p++;
+	} else if (c == 'l') {
+	    nas[cn].type = TYPE_INT32;
+	    c = *p++;
+	    if (c == 'l') {
+	        nas[cn].type = TYPE_INT64;
+	        c = *p++;
+	    }
+	}
+
+	/* format */
+	switch (c) {
+	case 'd':
+	case 'c':
+	case 'i':
+	case 'o':
+	case 'u':
+	case 'x':
+	case 'X':
+	    break;
+
+	case 'e':
+	case 'f':
+	case 'g':
+	    nas[ cn ].type = TYPE_DOUBLE;
+	    break;
+
+	case 'p':
+	    /* XXX should use cpp */
+	    if (sizeof(void *) == sizeof(PRInt32)) {
+		nas[ cn ].type = TYPE_UINT32;
+	    } else if (sizeof(void *) == sizeof(PRInt64)) {
+	        nas[ cn ].type = TYPE_UINT64;
+	    } else if (sizeof(void *) == sizeof(PRIntn)) {
+	        nas[ cn ].type = TYPE_UINTN;
+	    } else {
+	        nas[ cn ].type = TYPE_UNKNOWN;
+	    }
+	    break;
+
+	case 'C':
+	case 'S':
+	case 'E':
+	case 'G':
+	    /* XXX not supported I suppose */
+	    PR_ASSERT(0);
+	    nas[ cn ].type = TYPE_UNKNOWN;
+	    break;
+
+	case 's':
+	    nas[ cn ].type = TYPE_STRING;
+	    break;
+
+	case 'n':
+	    nas[ cn ].type = TYPE_INTSTR;
+	    break;
+
+	default:
+	    PR_ASSERT(0);
+	    nas[ cn ].type = TYPE_UNKNOWN;
+	    break;
+	}
+
+	/* get a legal para. */
+	if( nas[ cn ].type == TYPE_UNKNOWN ){
+	    *rv = -1;
+	    break;
+	}
+    }
+
+
+    /*
+    ** third pass
+    ** fill the nas[cn].ap
+    */
+
+    if( *rv < 0 ){
+	if( nas != nasArray )
+	    PR_DELETE( nas );
+	return NULL;
+    }
+
+    cn = 0;
+    while( cn < number ){
+	if( nas[cn].type == TYPE_UNKNOWN ){
+	    cn++;
+	    continue;
+	}
+
+	switch( nas[cn].type ){
+	case TYPE_INT16:
+	case TYPE_UINT16:
+	case TYPE_INTN:
+	    nas[cn].u.i = va_arg( ap, int );
+	    break;
+
+	case TYPE_UINTN:
+	    nas[cn].u.ui = va_arg( ap, unsigned int );
+	    break;
+
+	case TYPE_INT32:
+	    nas[cn].u.i32 = va_arg( ap, PRInt32 );
+	    break;
+
+	case TYPE_UINT32:
+	    nas[cn].u.ui32 = va_arg( ap, PRUint32 );
+	    break;
+
+	case TYPE_INT64:
+	    nas[cn].u.ll = va_arg( ap, PRInt64 );
+	    break;
+
+	case TYPE_UINT64:
+	    nas[cn].u.ull = va_arg( ap, PRUint64 );
+	    break;
+
+	case TYPE_STRING:
+	    nas[cn].u.s = va_arg( ap, char* );
+	    break;
+
+	case TYPE_INTSTR:
+	    nas[cn].u.ip = va_arg( ap, int* );
+	    break;
+
+	case TYPE_DOUBLE:
+	    nas[cn].u.d = va_arg( ap, double );
+	    break;
+
+	default:
+	    if( nas != nasArray )
+		PR_DELETE( nas );
+	    *rv = -1;
+	    return NULL;
+	}
+
+	cn++;
+    }
+
+
+    return nas;
+}
+
+/*
+** The workhorse sprintf code.
+*/
+static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
+{
+    char c;
+    int flags, width, prec, radix, type;
+    union {
+	char ch;
+	int i;
+	long l;
+	PRInt64 ll;
+	double d;
+	const char *s;
+	int *ip;
+    } u;
+    const char *fmt0;
+    static char *hex = "0123456789abcdef";
+    static char *HEX = "0123456789ABCDEF";
+    char *hexp;
+    int rv, i;
+    struct NumArg* nas = NULL;
+    struct NumArg* nap;
+    struct NumArg  nasArray[ NAS_DEFAULT_NUM ];
+    char  pattern[20];
+    const char* dolPt = NULL;  /* in "%4$.2f", dolPt will point to . */
+
+
+    /*
+    ** build an argument array, IF the fmt is numbered argument
+    ** list style, to contain the Numbered Argument list pointers
+    */
+
+    nas = BuildArgArray( fmt, ap, &rv, nasArray );
+    if( rv < 0 ){
+	/* the fmt contains error Numbered Argument format, jliu@netscape.com */
+	PR_ASSERT(0);
+	return rv;
+    }
+
+    while ((c = *fmt++) != 0) {
+	if (c != '%') {
+	    rv = (*ss->stuff)(ss, fmt - 1, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	    continue;
+	}
+	fmt0 = fmt - 1;
+
+	/*
+	** Gobble up the % format string. Hopefully we have handled all
+	** of the strange cases!
+	*/
+	flags = 0;
+	c = *fmt++;
+	if (c == '%') {
+	    /* quoting a % with %% */
+	    rv = (*ss->stuff)(ss, fmt - 1, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	    continue;
+	}
+
+	if( nas != NULL ){
+	    /* the fmt contains the Numbered Arguments feature */
+	    i = 0;
+	    while( c && c != '$' ){	    /* should imporve error check later */
+		i = ( i * 10 ) + ( c - '0' );
+		c = *fmt++;
+	    }
+
+	    if( nas[i-1].type == TYPE_UNKNOWN ){
+		if( nas && ( nas != nasArray ) )
+		    PR_DELETE( nas );
+		return -1;
+	    }
+
+	    nap = &nas[i-1];
+	    dolPt = fmt;
+	    c = *fmt++;
+	}
+
+	/*
+	 * Examine optional flags.  Note that we do not implement the
+	 * '#' flag of sprintf().  The ANSI C spec. of the '#' flag is
+	 * somewhat ambiguous and not ideal, which is perhaps why
+	 * the various sprintf() implementations are inconsistent
+	 * on this feature.
+	 */
+	while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) {
+	    if (c == '-') flags |= FLAG_LEFT;
+	    if (c == '+') flags |= FLAG_SIGNED;
+	    if (c == ' ') flags |= FLAG_SPACED;
+	    if (c == '0') flags |= FLAG_ZEROS;
+	    c = *fmt++;
+	}
+	if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED;
+	if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS;
+
+	/* width */
+	if (c == '*') {
+	    c = *fmt++;
+	    width = va_arg(ap, int);
+	} else {
+	    width = 0;
+	    while ((c >= '0') && (c <= '9')) {
+		width = (width * 10) + (c - '0');
+		c = *fmt++;
+	    }
+	}
+
+	/* precision */
+	prec = -1;
+	if (c == '.') {
+	    c = *fmt++;
+	    if (c == '*') {
+		c = *fmt++;
+		prec = va_arg(ap, int);
+	    } else {
+		prec = 0;
+		while ((c >= '0') && (c <= '9')) {
+		    prec = (prec * 10) + (c - '0');
+		    c = *fmt++;
+		}
+	    }
+	}
+
+	/* size */
+	type = TYPE_INTN;
+	if (c == 'h') {
+	    type = TYPE_INT16;
+	    c = *fmt++;
+	} else if (c == 'L') {
+	    /* XXX not quite sure here */
+	    type = TYPE_INT64;
+	    c = *fmt++;
+	} else if (c == 'l') {
+	    type = TYPE_INT32;
+	    c = *fmt++;
+	    if (c == 'l') {
+		type = TYPE_INT64;
+		c = *fmt++;
+	    }
+	} else if (c == 't') {
+		if (sizeof(PRPtrdiff) == sizeof(PRInt32)) {
+		    type = TYPE_UINT32;
+		} else if (sizeof(PRPtrdiff) == sizeof(PRInt64)) {
+		    type = TYPE_UINT64;
+		} else if (sizeof(PRPtrdiff) == sizeof(PRIntn)) {
+		    type = TYPE_UINTN;
+		} else {
+		    PR_ASSERT(0);
+		}
+		c = *fmt++;
+	} else if (c == 'z') {
+		if (sizeof(PRSize) == sizeof(PRInt32)) {
+		    type = TYPE_UINT32;
+		} else if (sizeof(PRSize) == sizeof(PRInt64)) {
+		    type = TYPE_UINT64;
+		} else if (sizeof(PRSize) == sizeof(PRIntn)) {
+		    type = TYPE_UINTN;
+		} else {
+		    PR_ASSERT(0);
+		}
+		c = *fmt++;
+	}
+
+	/* format */
+	hexp = hex;
+	switch (c) {
+	  case 'd': case 'i':			/* decimal/integer */
+	    radix = 10;
+	    goto fetch_and_convert;
+
+	  case 'o':				/* octal */
+	    radix = 8;
+	    type |= 1;
+	    goto fetch_and_convert;
+
+	  case 'u':				/* unsigned decimal */
+	    radix = 10;
+	    type |= 1;
+	    goto fetch_and_convert;
+
+	  case 'x':				/* unsigned hex */
+	    radix = 16;
+	    type |= 1;
+	    goto fetch_and_convert;
+
+	  case 'X':				/* unsigned HEX */
+	    radix = 16;
+	    hexp = HEX;
+	    type |= 1;
+	    goto fetch_and_convert;
+
+	  fetch_and_convert:
+	    switch (type) {
+	      case TYPE_INT16:
+		u.l = nas ? nap->u.i : va_arg(ap, int);
+		if (u.l < 0) {
+		    u.l = -u.l;
+		    flags |= FLAG_NEG;
+		}
+		goto do_long;
+	      case TYPE_UINT16:
+		u.l = (nas ? nap->u.i : va_arg(ap, int)) & 0xffff;
+		goto do_long;
+	      case TYPE_INTN:
+		u.l = nas ? nap->u.i : va_arg(ap, int);
+		if (u.l < 0) {
+		    u.l = -u.l;
+		    flags |= FLAG_NEG;
+		}
+		goto do_long;
+	      case TYPE_UINTN:
+		u.l = (long)(nas ? nap->u.ui : va_arg(ap, unsigned int));
+		goto do_long;
+
+	      case TYPE_INT32:
+		u.l = nas ? nap->u.i32 : va_arg(ap, PRInt32);
+		if (u.l < 0) {
+		    u.l = -u.l;
+		    flags |= FLAG_NEG;
+		}
+		goto do_long;
+	      case TYPE_UINT32:
+		u.l = (long)(nas ? nap->u.ui32 : va_arg(ap, PRUint32));
+	      do_long:
+		rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp);
+		if (rv < 0) {
+		    return rv;
+		}
+		break;
+
+	      case TYPE_INT64:
+		u.ll = nas ? nap->u.ll : va_arg(ap, PRInt64);
+		if (!LL_GE_ZERO(u.ll)) {
+		    LL_NEG(u.ll, u.ll);
+		    flags |= FLAG_NEG;
+		}
+		goto do_longlong;
+	      case TYPE_UINT64:
+		u.ll = nas ? nap->u.ull : va_arg(ap, PRUint64);
+	      do_longlong:
+		rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp);
+		if (rv < 0) {
+		    return rv;
+		}
+		break;
+	    }
+	    break;
+
+	  case 'e':
+	  case 'E':
+	  case 'f':
+	  case 'g':
+	    u.d = nas ? nap->u.d : va_arg(ap, double);
+	    if( nas != NULL ){
+		i = fmt - dolPt;
+		if( i < sizeof( pattern ) ){
+		    pattern[0] = '%';
+		    memcpy( &pattern[1], dolPt, i );
+		    rv = cvt_f(ss, u.d, pattern, &pattern[i+1] );
+		}
+	    } else
+		rv = cvt_f(ss, u.d, fmt0, fmt);
+
+	    if (rv < 0) {
+		return rv;
+	    }
+	    break;
+
+	  case 'c':
+	    u.ch = nas ? nap->u.i : va_arg(ap, int);
+            if ((flags & FLAG_LEFT) == 0) {
+                while (width-- > 1) {
+                    rv = (*ss->stuff)(ss, " ", 1);
+                    if (rv < 0) {
+                        return rv;
+                    }
+                }
+            }
+	    rv = (*ss->stuff)(ss, &u.ch, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+            if (flags & FLAG_LEFT) {
+                while (width-- > 1) {
+                    rv = (*ss->stuff)(ss, " ", 1);
+                    if (rv < 0) {
+                        return rv;
+                    }
+                }
+            }
+	    break;
+
+	  case 'p':
+	    if (sizeof(void *) == sizeof(PRInt32)) {
+	    	type = TYPE_UINT32;
+	    } else if (sizeof(void *) == sizeof(PRInt64)) {
+	    	type = TYPE_UINT64;
+	    } else if (sizeof(void *) == sizeof(int)) {
+		type = TYPE_UINTN;
+	    } else {
+		PR_ASSERT(0);
+		break;
+	    }
+	    radix = 16;
+	    goto fetch_and_convert;
+
+#if 0
+	  case 'C':
+	  case 'S':
+	  case 'E':
+	  case 'G':
+	    /* XXX not supported I suppose */
+	    PR_ASSERT(0);
+	    break;
+#endif
+
+	  case 's':
+	    u.s = nas ? nap->u.s : va_arg(ap, const char*);
+	    rv = cvt_s(ss, u.s, width, prec, flags);
+	    if (rv < 0) {
+		return rv;
+	    }
+	    break;
+
+	  case 'n':
+	    u.ip = nas ? nap->u.ip : va_arg(ap, int*);
+	    if (u.ip) {
+		*u.ip = ss->cur - ss->base;
+	    }
+	    break;
+
+	  default:
+	    /* Not a % token after all... skip it */
+#if 0
+	    PR_ASSERT(0);
+#endif
+	    rv = (*ss->stuff)(ss, "%", 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	    rv = (*ss->stuff)(ss, fmt - 1, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	}
+    }
+
+    /* Stuff trailing NUL */
+    rv = (*ss->stuff)(ss, "\0", 1);
+
+    if( nas && ( nas != nasArray ) ){
+	PR_DELETE( nas );
+    }
+
+    return rv;
+}
+
+/************************************************************************/
+
+static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len)
+{
+    int rv;
+
+    rv = (*ss->func)(ss->arg, sp, len);
+    if (rv < 0) {
+	return rv;
+    }
+    ss->maxlen += len;
+    return 0;
+}
+
+PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, 
+                                 const char *fmt, ...)
+{
+    va_list ap;
+    PRUint32 rv;
+
+    va_start(ap, fmt);
+    rv = PR_vsxprintf(func, arg, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+PR_IMPLEMENT(PRUint32) PR_vsxprintf(PRStuffFunc func, void *arg, 
+                                  const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = FuncStuff;
+    ss.func = func;
+    ss.arg = arg;
+    ss.maxlen = 0;
+    rv = dosprintf(&ss, fmt, ap);
+    return (rv < 0) ? (PRUint32)-1 : ss.maxlen;
+}
+
+/*
+** Stuff routine that automatically grows the malloc'd output buffer
+** before it overflows.
+*/
+static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len)
+{
+    ptrdiff_t off;
+    char *newbase;
+    PRUint32 newlen;
+
+    off = ss->cur - ss->base;
+    if (off + len >= ss->maxlen) {
+	/* Grow the buffer */
+	newlen = ss->maxlen + ((len > 32) ? len : 32);
+	if (ss->base) {
+	    newbase = (char*) PR_REALLOC(ss->base, newlen);
+	} else {
+	    newbase = (char*) PR_MALLOC(newlen);
+	}
+	if (!newbase) {
+	    /* Ran out of memory */
+	    return -1;
+	}
+	ss->base = newbase;
+	ss->maxlen = newlen;
+	ss->cur = ss->base + off;
+    }
+
+    /* Copy data */
+    while (len) {
+	--len;
+	*ss->cur++ = *sp++;
+    }
+    PR_ASSERT((PRUint32)(ss->cur - ss->base) <= ss->maxlen);
+    return 0;
+}
+
+/*
+** sprintf into a malloc'd buffer
+*/
+PR_IMPLEMENT(char *) PR_smprintf(const char *fmt, ...)
+{
+    va_list ap;
+    char *rv;
+
+    va_start(ap, fmt);
+    rv = PR_vsmprintf(fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+/*
+** Free memory allocated, for the caller, by PR_smprintf
+*/
+PR_IMPLEMENT(void) PR_smprintf_free(char *mem)
+{
+	PR_DELETE(mem);
+}
+
+PR_IMPLEMENT(char *) PR_vsmprintf(const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = GrowStuff;
+    ss.base = 0;
+    ss.cur = 0;
+    ss.maxlen = 0;
+    rv = dosprintf(&ss, fmt, ap);
+    if (rv < 0) {
+	if (ss.base) {
+	    PR_DELETE(ss.base);
+	}
+	return 0;
+    }
+    return ss.base;
+}
+
+/*
+** Stuff routine that discards overflow data
+*/
+static int LimitStuff(SprintfState *ss, const char *sp, PRUint32 len)
+{
+    PRUint32 limit = ss->maxlen - (ss->cur - ss->base);
+
+    if (len > limit) {
+	len = limit;
+    }
+    while (len) {
+	--len;
+	*ss->cur++ = *sp++;
+    }
+    return 0;
+}
+
+/*
+** sprintf into a fixed size buffer. Make sure there is a NUL at the end
+** when finished.
+*/
+PR_IMPLEMENT(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...)
+{
+    va_list ap;
+    PRUint32 rv;
+
+    va_start(ap, fmt);
+    rv = PR_vsnprintf(out, outlen, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt,
+                                  va_list ap)
+{
+    SprintfState ss;
+    PRUint32 n;
+
+    PR_ASSERT((PRInt32)outlen > 0);
+    if ((PRInt32)outlen <= 0) {
+	return 0;
+    }
+
+    ss.stuff = LimitStuff;
+    ss.base = out;
+    ss.cur = out;
+    ss.maxlen = outlen;
+    (void) dosprintf(&ss, fmt, ap);
+
+    /* If we added chars, and we didn't append a null, do it now. */
+    if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') )
+        *(ss.cur - 1) = '\0';
+
+    n = ss.cur - ss.base;
+    return n ? n - 1 : n;
+}
+
+PR_IMPLEMENT(char *) PR_sprintf_append(char *last, const char *fmt, ...)
+{
+    va_list ap;
+    char *rv;
+
+    va_start(ap, fmt);
+    rv = PR_vsprintf_append(last, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = GrowStuff;
+    if (last) {
+	int lastlen = strlen(last);
+	ss.base = last;
+	ss.cur = last + lastlen;
+	ss.maxlen = lastlen;
+    } else {
+	ss.base = 0;
+	ss.cur = 0;
+	ss.maxlen = 0;
+    }
+    rv = dosprintf(&ss, fmt, ap);
+    if (rv < 0) {
+	if (ss.base) {
+	    PR_DELETE(ss.base);
+	}
+	return 0;
+    }
+    return ss.base;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prscanf.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prscanf.c
new file mode 100644
index 0000000..618f184
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prscanf.c
@@ -0,0 +1,669 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Scan functions for NSPR types
+ *
+ * Author: Wan-Teh Chang
+ *
+ * Acknowledgment: The implementation is inspired by the source code
+ * in P.J. Plauger's "The Standard C Library," Prentice-Hall, 1992.
+ */
+
+#include <limits.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef SUNOS4
+#include "md/sunos4.h"  /* for strtoul */
+#endif
+#include "prprf.h"
+#include "prdtoa.h"
+#include "prlog.h"
+#include "prerror.h"
+
+/*
+ * A function that reads a character from 'stream'.
+ * Returns the character read, or EOF if end of stream is reached.
+ */
+typedef int (*_PRGetCharFN)(void *stream);
+
+/*
+ * A function that pushes the character 'ch' back to 'stream'.
+ */
+typedef void (*_PRUngetCharFN)(void *stream, int ch); 
+
+/*
+ * The size specifier for the integer and floating point number
+ * conversions in format control strings.
+ */
+typedef enum {
+    _PR_size_none,  /* No size specifier is given */
+    _PR_size_h,     /* The 'h' specifier, suggesting "short" */
+    _PR_size_l,     /* The 'l' specifier, suggesting "long" */
+    _PR_size_L,     /* The 'L' specifier, meaning a 'long double' */
+    _PR_size_ll     /* The 'll' specifier, suggesting "long long" */
+} _PRSizeSpec;
+
+/*
+ * The collection of data that is passed between the scan function
+ * and its subordinate functions.  The fields of this structure
+ * serve as the input or output arguments for these functions.
+ */
+typedef struct {
+    _PRGetCharFN get;        /* get a character from input stream */
+    _PRUngetCharFN unget;    /* unget (push back) a character */
+    void *stream;            /* argument for get and unget */
+    va_list ap;              /* the variable argument list */
+    int nChar;               /* number of characters read from 'stream' */
+
+    PRBool assign;           /* assign, or suppress assignment? */
+    int width;               /* field width */
+    _PRSizeSpec sizeSpec;    /* 'h', 'l', 'L', or 'll' */
+
+    PRBool converted;        /* is the value actually converted? */
+} ScanfState;
+
+#define GET(state) ((state)->nChar++, (state)->get((state)->stream))
+#define UNGET(state, ch) \
+        ((state)->nChar--, (state)->unget((state)->stream, ch))
+
+/*
+ * The following two macros, GET_IF_WITHIN_WIDTH and WITHIN_WIDTH,
+ * are always used together.
+ *
+ * GET_IF_WITHIN_WIDTH calls the GET macro and assigns its return
+ * value to 'ch' only if we have not exceeded the field width of
+ * 'state'.  Therefore, after GET_IF_WITHIN_WIDTH, the value of
+ * 'ch' is valid only if the macro WITHIN_WIDTH evaluates to true.
+ */
+
+#define GET_IF_WITHIN_WIDTH(state, ch) \
+        if (--(state)->width >= 0) { \
+            (ch) = GET(state); \
+        }
+#define WITHIN_WIDTH(state) ((state)->width >= 0)
+
+/*
+ * _pr_strtoull:
+ *     Convert a string to an unsigned 64-bit integer.  The string
+ *     'str' is assumed to be a representation of the integer in
+ *     base 'base'.
+ *
+ * Warning: 
+ *     - Only handle base 8, 10, and 16.
+ *     - No overflow checking.
+ */
+
+static PRUint64
+_pr_strtoull(const char *str, char **endptr, int base)
+{
+    static const int BASE_MAX = 16;
+    static const char digits[] = "0123456789abcdef";
+    char *digitPtr;
+    PRUint64 x;    /* return value */
+    PRInt64 base64;
+    const char *cPtr;
+    PRBool negative;
+    const char *digitStart;
+
+    PR_ASSERT(base == 0 || base == 8 || base == 10 || base == 16);
+    if (base < 0 || base == 1 || base > BASE_MAX) {
+        if (endptr) {
+            *endptr = (char *) str;
+            return LL_ZERO;
+        }
+    }
+
+    cPtr = str;
+    while (isspace(*cPtr)) {
+        ++cPtr;
+    }
+
+    negative = PR_FALSE;
+    if (*cPtr == '-') {
+        negative = PR_TRUE;
+        cPtr++;
+    } else if (*cPtr == '+') {
+        cPtr++;
+    }
+
+    if (base == 16) {
+        if (*cPtr == '0' && (cPtr[1] == 'x' || cPtr[1] == 'X')) {
+            cPtr += 2;
+        }
+    } else if (base == 0) {
+        if (*cPtr != '0') {
+            base = 10;
+        } else if (cPtr[1] == 'x' || cPtr[1] == 'X') {
+            base = 16;
+            cPtr += 2;
+        } else {
+            base = 8;
+        } 
+    }
+    PR_ASSERT(base != 0);
+    LL_I2L(base64, base);
+    digitStart = cPtr;
+
+    /* Skip leading zeros */
+    while (*cPtr == '0') {
+        cPtr++;
+    }
+
+    LL_I2L(x, 0);
+    while ((digitPtr = (char*)memchr(digits, tolower(*cPtr), base)) != NULL) {
+        PRUint64 d;
+
+        LL_I2L(d, (digitPtr - digits));
+        LL_MUL(x, x, base64);
+        LL_ADD(x, x, d);
+        cPtr++;
+    }
+
+    if (cPtr == digitStart) {
+        if (endptr) {
+            *endptr = (char *) str;
+        }
+        return LL_ZERO;
+    }
+
+    if (negative) {
+#ifdef HAVE_LONG_LONG
+        /* The cast to a signed type is to avoid a compiler warning */
+        x = -(PRInt64)x;
+#else
+        LL_NEG(x, x);
+#endif
+    }
+
+    if (endptr) {
+        *endptr = (char *) cPtr;
+    }
+    return x;
+}
+
+/*
+ * The maximum field width (in number of characters) that is enough
+ * (may be more than necessary) to represent a 64-bit integer or
+ * floating point number.
+ */
+#define FMAX 31
+#define DECIMAL_POINT '.'
+
+static PRStatus
+GetInt(ScanfState *state, int code)
+{
+    char buf[FMAX + 1], *p;
+    int ch;
+    static const char digits[] = "0123456789abcdefABCDEF";
+    PRBool seenDigit = PR_FALSE;
+    int base;
+    int dlen;
+
+    switch (code) {
+        case 'd': case 'u':
+            base = 10;
+            break;
+        case 'i':
+            base = 0;
+            break;
+        case 'x': case 'X': case 'p':
+            base = 16;
+            break;
+        case 'o':
+            base = 8;
+            break;
+        default:
+            return PR_FAILURE;
+    }
+    if (state->width == 0 || state->width > FMAX) {
+        state->width = FMAX;
+    }
+    p = buf;
+    GET_IF_WITHIN_WIDTH(state, ch);
+    if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+    }
+    if (WITHIN_WIDTH(state) && ch == '0') {
+        seenDigit = PR_TRUE;
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        if (WITHIN_WIDTH(state)
+                && (ch == 'x' || ch == 'X')
+                && (base == 0 || base == 16)) {
+            base = 16;
+            *p++ = ch;
+            GET_IF_WITHIN_WIDTH(state, ch);
+        } else if (base == 0) {
+            base = 8;
+        }
+    }
+    if (base == 0 || base == 10) {
+        dlen = 10;
+    } else if (base == 8) {
+        dlen = 8;
+    } else {
+        PR_ASSERT(base == 16);
+        dlen = 16 + 6; /* 16 digits, plus 6 in uppercase */
+    }
+    while (WITHIN_WIDTH(state) && memchr(digits, ch, dlen)) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        seenDigit = PR_TRUE;
+    }
+    if (WITHIN_WIDTH(state)) {
+        UNGET(state, ch);
+    }
+    if (!seenDigit) {
+        return PR_FAILURE;
+    }
+    *p = '\0';
+    if (state->assign) {
+        if (code == 'd' || code == 'i') {
+            if (state->sizeSpec == _PR_size_ll) {
+                PRInt64 llval = _pr_strtoull(buf, NULL, base);
+                *va_arg(state->ap, PRInt64 *) = llval;
+            } else {
+                long lval = strtol(buf, NULL, base);
+
+                if (state->sizeSpec == _PR_size_none) {
+                    *va_arg(state->ap, PRIntn *) = lval;
+                } else if (state->sizeSpec == _PR_size_h) {
+                    *va_arg(state->ap, PRInt16 *) = (PRInt16)lval;
+                } else if (state->sizeSpec == _PR_size_l) {
+                    *va_arg(state->ap, PRInt32 *) = lval;
+                } else {
+                    return PR_FAILURE;
+                }
+            }
+        } else {
+            if (state->sizeSpec == _PR_size_ll) {
+                PRUint64 llval = _pr_strtoull(buf, NULL, base);
+                *va_arg(state->ap, PRUint64 *) = llval;
+            } else {
+                unsigned long lval = strtoul(buf, NULL, base);
+
+                if (state->sizeSpec == _PR_size_none) {
+                    *va_arg(state->ap, PRUintn *) = lval;
+                } else if (state->sizeSpec == _PR_size_h) {
+                    *va_arg(state->ap, PRUint16 *) = (PRUint16)lval;
+                } else if (state->sizeSpec == _PR_size_l) {
+                    *va_arg(state->ap, PRUint32 *) = lval;
+                } else {
+                    return PR_FAILURE;
+                }
+            }
+        }
+        state->converted = PR_TRUE;
+    }
+    return PR_SUCCESS;
+}
+
+static PRStatus
+GetFloat(ScanfState *state)
+{
+    char buf[FMAX + 1], *p;
+    int ch;
+    PRBool seenDigit = PR_FALSE;
+
+    if (state->width == 0 || state->width > FMAX) {
+        state->width = FMAX;
+    }
+    p = buf;
+    GET_IF_WITHIN_WIDTH(state, ch);
+    if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+    }
+    while (WITHIN_WIDTH(state) && isdigit(ch)) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        seenDigit = PR_TRUE;
+    }
+    if (WITHIN_WIDTH(state) && ch == DECIMAL_POINT) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        while (WITHIN_WIDTH(state) && isdigit(ch)) {
+            *p++ = ch;
+            GET_IF_WITHIN_WIDTH(state, ch);
+            seenDigit = PR_TRUE;
+        }
+    }
+
+    /*
+     * This is not robust.  For example, "1.2e+" would confuse
+     * the code below to read 'e' and '+', only to realize that
+     * it should have stopped at "1.2".  But we can't push back
+     * more than one character, so there is nothing I can do.
+     */
+
+    /* Parse exponent */
+    if (WITHIN_WIDTH(state) && (ch == 'e' || ch == 'E') && seenDigit) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
+            *p++ = ch;
+            GET_IF_WITHIN_WIDTH(state, ch);
+        }
+        while (WITHIN_WIDTH(state) && isdigit(ch)) {
+            *p++ = ch;
+            GET_IF_WITHIN_WIDTH(state, ch);
+        }
+    }
+    if (WITHIN_WIDTH(state)) {
+        UNGET(state, ch);
+    }
+    if (!seenDigit) {
+        return PR_FAILURE;
+    }
+    *p = '\0';
+    if (state->assign) {
+        PRFloat64 dval = PR_strtod(buf, NULL);
+
+        state->converted = PR_TRUE;
+        if (state->sizeSpec == _PR_size_l) {
+            *va_arg(state->ap, PRFloat64 *) = dval;
+        } else if (state->sizeSpec == _PR_size_L) {
+#if defined(OSF1) || defined(IRIX)
+            *va_arg(state->ap, double *) = dval;
+#else
+            *va_arg(state->ap, long double *) = dval;
+#endif
+        } else {
+            *va_arg(state->ap, float *) = (float) dval;
+        }
+    }
+    return PR_SUCCESS;
+}
+
+/*
+ * Convert, and return the end of the conversion spec.
+ * Return NULL on error.
+ */
+
+static const char *
+Convert(ScanfState *state, const char *fmt)
+{
+    const char *cPtr;
+    int ch;
+    char *cArg = NULL;
+
+    state->converted = PR_FALSE;
+    cPtr = fmt;
+    if (*cPtr != 'c' && *cPtr != 'n' && *cPtr != '[') {
+        do {
+            ch = GET(state);
+        } while (isspace(ch));
+        UNGET(state, ch);
+    }
+    switch (*cPtr) {
+        case 'c':
+            if (state->assign) {
+                cArg = va_arg(state->ap, char *);
+            }
+            if (state->width == 0) {
+                state->width = 1;
+            }
+            for (; state->width > 0; state->width--) {
+                ch = GET(state);
+                if (ch == EOF) {
+                    return NULL;
+                } else if (state->assign) {
+                    *cArg++ = ch;
+                }
+            }
+            if (state->assign) {
+                state->converted = PR_TRUE;
+            }
+            break;
+        case 'p':
+        case 'd': case 'i': case 'o':
+        case 'u': case 'x': case 'X':
+            if (GetInt(state, *cPtr) == PR_FAILURE) {
+                return NULL;
+            }
+            break;
+        case 'e': case 'E': case 'f':
+        case 'g': case 'G':
+            if (GetFloat(state) == PR_FAILURE) {
+                return NULL;
+            }
+            break;
+        case 'n':
+            /* do not consume any input */
+            if (state->assign) {
+                switch (state->sizeSpec) {
+                    case _PR_size_none:
+                        *va_arg(state->ap, PRIntn *) = state->nChar;
+                        break;
+                    case _PR_size_h:
+                        *va_arg(state->ap, PRInt16 *) = state->nChar;
+                        break;
+                    case _PR_size_l:
+                        *va_arg(state->ap, PRInt32 *) = state->nChar;
+                        break;
+                    case _PR_size_ll:
+                        LL_I2L(*va_arg(state->ap, PRInt64 *), state->nChar);
+                        break;
+                    default:
+                        PR_ASSERT(0);
+                }
+            }
+            break;
+        case 's':
+            if (state->width == 0) {
+                state->width = INT_MAX;
+            }
+            if (state->assign) {
+                cArg = va_arg(state->ap, char *);
+            }
+            for (; state->width > 0; state->width--) {
+                ch = GET(state);
+                if ((ch == EOF) || isspace(ch)) {
+                    UNGET(state, ch);
+                    break;
+                }
+                if (state->assign) {
+                    *cArg++ = ch;
+                }
+            }
+            if (state->assign) {
+                *cArg = '\0';
+                state->converted = PR_TRUE;
+            }
+            break;
+        case '%':
+            ch = GET(state);
+            if (ch != '%') {
+                UNGET(state, ch);
+                return NULL;
+            }
+            break;
+        case '[':
+            {
+                PRBool complement = PR_FALSE;
+                const char *closeBracket;
+                size_t n;
+
+                if (*++cPtr == '^') {
+                    complement = PR_TRUE;
+                    cPtr++;
+                }
+                closeBracket = strchr(*cPtr == ']' ? cPtr + 1 : cPtr, ']');
+                if (closeBracket == NULL) {
+                    return NULL;
+                }
+                n = closeBracket - cPtr;
+                if (state->width == 0) {
+                    state->width = INT_MAX;
+                }
+                if (state->assign) {
+                    cArg = va_arg(state->ap, char *);
+                }
+                for (; state->width > 0; state->width--) {
+                    ch = GET(state);
+                    if ((ch == EOF) 
+                            || (!complement && !memchr(cPtr, ch, n))
+                            || (complement && memchr(cPtr, ch, n))) {
+                        UNGET(state, ch);
+                        break;
+                    }
+                    if (state->assign) {
+                        *cArg++ = ch;
+                    }
+                }
+                if (state->assign) {
+                    *cArg = '\0';
+                    state->converted = PR_TRUE;
+                }
+                cPtr = closeBracket;
+            }
+            break;
+        default:
+            return NULL;
+    }
+    return cPtr;
+}
+
+static PRInt32
+DoScanf(ScanfState *state, const char *fmt)
+{
+    PRInt32 nConverted = 0;
+    const char *cPtr;
+    int ch;
+
+    state->nChar = 0;
+    cPtr = fmt;
+    while (1) {
+        if (isspace(*cPtr)) {
+            /* white space: skip */
+            do {
+                cPtr++;
+            } while (isspace(*cPtr));
+            do {
+                ch = GET(state);
+            } while (isspace(ch));
+            UNGET(state, ch);
+        } else if (*cPtr == '%') {
+            /* format spec: convert */
+            cPtr++;
+            state->assign = PR_TRUE;
+            if (*cPtr == '*') {
+                cPtr++;
+                state->assign = PR_FALSE;
+            }
+            for (state->width = 0; isdigit(*cPtr); cPtr++) {
+                state->width = state->width * 10 + *cPtr - '0';
+            }
+            state->sizeSpec = _PR_size_none;
+            if (*cPtr == 'h') {
+                cPtr++;
+                state->sizeSpec = _PR_size_h;
+            } else if (*cPtr == 'l') {
+                cPtr++;
+                if (*cPtr == 'l') {
+                    cPtr++;
+                    state->sizeSpec = _PR_size_ll;
+                } else {
+                    state->sizeSpec = _PR_size_l;
+                }
+            } else if (*cPtr == 'L') {
+                cPtr++;
+                state->sizeSpec = _PR_size_L;
+            }
+            cPtr = Convert(state, cPtr);
+            if (cPtr == NULL) {
+                return (nConverted > 0 ? nConverted : EOF);
+            }
+            if (state->converted) {
+                nConverted++;
+            }
+            cPtr++;
+        } else {
+            /* others: must match */
+            if (*cPtr == '\0') {
+                return nConverted;
+            }
+            ch = GET(state);
+            if (ch != *cPtr) {
+                UNGET(state, ch);
+                return nConverted;
+            }
+            cPtr++;
+        }
+    }
+}
+
+static int
+StringGetChar(void *stream)
+{
+    char *cPtr = *((char **) stream);
+
+    if (*cPtr == '\0') {
+        return EOF;
+    } else {
+        *((char **) stream) = cPtr + 1;
+        return (unsigned char) *cPtr;
+    }
+}
+
+static void
+StringUngetChar(void *stream, int ch)
+{
+    char *cPtr = *((char **) stream);
+
+    if (ch != EOF) {
+        *((char **) stream) = cPtr - 1;
+    }
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_sscanf(const char *buf, const char *fmt, ...)
+{
+    PRInt32 rv;
+    ScanfState state;
+
+    state.get = &StringGetChar;
+    state.unget = &StringUngetChar;
+    state.stream = (void *) &buf;
+    va_start(state.ap, fmt);
+    rv = DoScanf(&state, fmt);
+    va_end(state.ap);
+    return rv;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prsocket.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prsocket.c
new file mode 100644
index 0000000..8b4ef26
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prsocket.c
@@ -0,0 +1,1834 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+
+/************************************************************************/
+
+/* These two functions are only used in assertions. */
+#if defined(DEBUG)
+
+PRBool IsValidNetAddr(const PRNetAddr *addr)
+{
+    if ((addr != NULL)
+#if defined(XP_UNIX) || defined(XP_OS2)
+	    && (addr->raw.family != PR_AF_LOCAL)
+#endif
+	    && (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)
+{
+    /*
+     * The definition of the length of a Unix domain socket address
+     * is not uniform, so we don't check it.
+     */
+    if ((addr != NULL)
+#if defined(XP_UNIX) || defined(XP_OS2)
+            && (addr->raw.family != AF_UNIX)
+#endif
+            && (PR_NETADDR_SIZE(addr) != addr_len)) {
+#if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1
+        /*
+         * In glibc 2.1, struct sockaddr_in6 is 24 bytes.  In glibc 2.2
+         * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id
+         * field and is 28 bytes.  It is possible for socket functions
+         * to return an addr_len greater than sizeof(struct sockaddr_in6).
+         * We need to allow that.  (Bugzilla bug #77264)
+         */
+        if ((PR_AF_INET6 == addr->raw.family)
+                && (sizeof(addr->ipv6) == addr_len)) {
+            return PR_TRUE;
+        }
+#endif
+        /*
+         * The accept(), getsockname(), etc. calls on some platforms
+         * do not set the actual socket address length on return.
+         * In this case, we verifiy addr_len is still the value we
+         * passed in (i.e., sizeof(PRNetAddr)).
+         */
+#if defined(QNX)
+        if (sizeof(PRNetAddr) == addr_len) {
+            return PR_TRUE;
+        }
+#endif
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+
+#endif /* DEBUG */
+
+static PRInt32 PR_CALLBACK SocketWritev(PRFileDesc *fd, const PRIOVec *iov,
+PRInt32 iov_size, PRIntervalTime timeout)
+{
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	int w = 0;
+	const PRIOVec *tmp_iov;
+#define LOCAL_MAXIOV    8
+	PRIOVec local_iov[LOCAL_MAXIOV];
+	PRIOVec *iov_copy = NULL;
+	int tmp_out;
+	int index, iov_cnt;
+	int count=0, sz = 0;    /* 'count' is the return value. */
+
+	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;
+	}
+
+    /*
+     * Assume the first writev will succeed.  Copy iov's only on
+     * failure.
+     */
+    tmp_iov = iov;
+    for (index = 0; index < iov_size; index++)
+        sz += iov[index].iov_len;
+
+	iov_cnt = iov_size;
+
+	while (sz > 0) {
+
+		w = _PR_MD_WRITEV(fd, tmp_iov, iov_cnt, timeout);
+		if (w < 0) {
+			count = -1;
+			break;
+		}
+		count += w;
+		if (fd->secret->nonblocking) {
+			break;
+		}
+		sz -= w;
+
+		if (sz > 0) {
+			/* find the next unwritten vector */
+			for ( index = 0, tmp_out = count;
+				tmp_out >= iov[index].iov_len;
+				tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */
+
+			if (tmp_iov == iov) {
+				/*
+				 * The first writev failed so we
+				 * must copy iov's around.
+				 * Avoid calloc/free if there
+				 * are few enough iov's.
+				 */
+				if (iov_size - index <= LOCAL_MAXIOV)
+					iov_copy = local_iov;
+				else if ((iov_copy = (PRIOVec *) PR_CALLOC((iov_size - index) *
+					sizeof *iov_copy)) == NULL) {
+					PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+					return -1;
+				}
+				tmp_iov = iov_copy;
+			}
+
+			PR_ASSERT(tmp_iov == iov_copy);
+
+			/* fill in the first partial read */
+			iov_copy[0].iov_base = &(((char *)iov[index].iov_base)[tmp_out]);
+			iov_copy[0].iov_len = iov[index].iov_len - tmp_out;
+			index++;
+
+			/* copy the remaining vectors */
+			for (iov_cnt=1; index<iov_size; iov_cnt++, index++) {
+				iov_copy[iov_cnt].iov_base = iov[index].iov_base;
+				iov_copy[iov_cnt].iov_len = iov[index].iov_len;
+			}
+		}
+	}
+
+	if (iov_copy != local_iov)
+		PR_DELETE(iov_copy);
+	return count;
+}
+
+/************************************************************************/
+
+PR_IMPLEMENT(PRFileDesc *) PR_ImportTCPSocket(PROsfd osfd)
+{
+PRFileDesc *fd;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	fd = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
+	if (fd != NULL) {
+		_PR_MD_MAKE_NONBLOCK(fd);
+		_PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
+#ifdef _PR_NEED_SECRET_AF
+		/* this means we can only import IPv4 sockets here.
+		 * but this is what the function in ptio.c does.
+		 * We need a way to import IPv6 sockets, too.
+		 */
+		fd->secret->af = AF_INET;
+#endif
+	} else
+		_PR_MD_CLOSE_SOCKET(osfd);
+	return(fd);
+}
+
+PR_IMPLEMENT(PRFileDesc *) PR_ImportUDPSocket(PROsfd osfd)
+{
+PRFileDesc *fd;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods());
+	if (fd != NULL) {
+		_PR_MD_MAKE_NONBLOCK(fd);
+		_PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
+	} else
+		_PR_MD_CLOSE_SOCKET(osfd);
+	return(fd);
+}
+
+
+static const PRIOMethods* PR_GetSocketPollFdMethods(void);
+
+PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PROsfd osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    fd = _PR_Getfd();
+
+    if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    else
+    {
+        fd->secret->md.osfd = osfd;
+        fd->secret->inheritable = _PR_TRI_FALSE;
+    	fd->secret->state = _PR_FILEDESC_OPEN;
+        fd->methods = PR_GetSocketPollFdMethods();
+    }
+
+    return fd;
+}  /* PR_CreateSocketPollFD */
+
+PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd)
+{
+    if (NULL == fd)
+    {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    fd->secret->state = _PR_FILEDESC_CLOSED;
+    _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, 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;
+}
+
+static PRStatus PR_CALLBACK SocketConnectContinue(
+    PRFileDesc *fd, PRInt16 out_flags)
+{
+    PROsfd osfd;
+    int err;
+
+    if (out_flags & PR_POLL_NVAL) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) {
+        PR_ASSERT(out_flags == 0);
+        PR_SetError(PR_IN_PROGRESS_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    osfd = fd->secret->md.osfd;
+
+#if defined(XP_UNIX)
+
+    err = _MD_unix_get_nonblocking_connect_error(osfd);
+    if (err != 0) {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+
+#elif defined(WIN32) || defined(WIN16)
+
+#if defined(WIN32)
+    /*
+     * The sleep circumvents a bug in Win32 WinSock.
+     * See Microsoft Knowledge Base article ID: Q165989.
+     */
+    Sleep(0);
+#endif /* WIN32 */
+
+    if (out_flags & PR_POLL_EXCEPT) {
+        int len = sizeof(err);
+        if (getsockopt(osfd, (int)SOL_SOCKET, SO_ERROR, (char *) &err, &len)
+                == SOCKET_ERROR) {
+            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+            return PR_FAILURE;
+        }
+        if (err != 0) {
+            _PR_MD_MAP_CONNECT_ERROR(err);
+        } else {
+            PR_SetError(PR_UNKNOWN_ERROR, 0);
+        }
+        return PR_FAILURE;
+    }
+
+    PR_ASSERT(out_flags & PR_POLL_WRITE);
+    return PR_SUCCESS;
+
+#elif defined(XP_OS2)
+
+    err = _MD_os2_get_nonblocking_connect_error(osfd);
+    if (err != 0) {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+
+#elif defined(XP_BEOS)
+
+#ifdef BONE_VERSION  /* bug 122364 */
+    /* temporary workaround until getsockopt(SO_ERROR) works in BONE */
+    if (out_flags & PR_POLL_EXCEPT) {
+        PR_SetError(PR_CONNECT_REFUSED_ERROR, 0);
+        return PR_FAILURE;
+    }
+    PR_ASSERT(out_flags & PR_POLL_WRITE);
+    return PR_SUCCESS;
+#else
+    err = _MD_beos_get_nonblocking_connect_error(fd);
+    if( err != 0 ) {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+        return PR_FAILURE;
+    }
+    else
+        return PR_SUCCESS;
+#endif /* BONE_VERSION */
+
+#else
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+#endif
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
+{
+    /* Find the NSPR layer and invoke its connectcontinue method */
+    PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+
+    if (NULL == bottom) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    return SocketConnectContinue(bottom, pd->out_flags);
+}
+
+static PRFileDesc* PR_CALLBACK SocketAccept(PRFileDesc *fd, PRNetAddr *addr,
+PRIntervalTime timeout)
+{
+	PROsfd osfd;
+	PRFileDesc *fd2;
+	PRUint32 al;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+#ifdef WINNT
+	PRNetAddr addrCopy;
+#endif
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return 0;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return 0;
+	}
+
+#ifdef WINNT
+	if (addr == NULL) {
+		addr = &addrCopy;
+	}
+#endif
+	al = sizeof(PRNetAddr);
+	osfd = _PR_MD_ACCEPT(fd, addr, &al, timeout);
+	if (osfd == -1)
+		return 0;
+
+	fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
+	if (!fd2) {
+		_PR_MD_CLOSE_SOCKET(osfd);
+		return NULL;
+	}
+
+	fd2->secret->nonblocking = fd->secret->nonblocking;
+	fd2->secret->inheritable = fd->secret->inheritable;
+#ifdef WINNT
+	if (!fd2->secret->nonblocking && fd2->secret->inheritable != _PR_TRI_TRUE) {
+		/*
+		 * The new socket has been associated with an I/O
+		 * completion port.  There is no going back.
+		 */
+		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);
+#endif
+
+	/*
+	 * On some platforms, the new socket created by accept()
+	 * inherits the nonblocking (or overlapped io) attribute
+	 * of the listening socket.  As an optimization, these
+	 * platforms can skip the following _PR_MD_MAKE_NONBLOCK
+	 * call.
+	 */
+#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,
+PRIntervalTime timeout)
+{
+	PROsfd osfd;
+	PRFileDesc *fd2;
+	PRIntn al;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	PRNetAddr addrCopy;
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return 0;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return 0;
+	}
+
+		if (addr == NULL) {
+			addr = &addrCopy;
+		}
+		al = PR_NETADDR_SIZE(addr);
+		osfd = _PR_MD_FAST_ACCEPT(fd, addr, &al, timeout, PR_TRUE, NULL, NULL);
+		if (osfd == -1) {
+			return 0;
+		}
+
+	fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
+	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
+#ifdef _PR_NEED_SECRET_AF
+		fd2->secret->af = fd->secret->af;
+#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 */
+
+#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)
+{
+	PRInt32 result;
+
+	result = _PR_MD_LISTEN(fd, backlog);
+	if (result < 0) {
+		return PR_FAILURE;
+	}
+	return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK SocketShutdown(PRFileDesc *fd, PRIntn how)
+{
+	PRInt32 result;
+
+	result = _PR_MD_SHUTDOWN(fd, how);
+	if (result < 0) {
+		return PR_FAILURE;
+	}
+	return PR_SUCCESS;
+}
+
+static PRInt32 PR_CALLBACK SocketRecv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if ((flags != 0) && (flags != PR_MSG_PEEK)) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+	}
+	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_LOG(_pr_io_lm, PR_LOG_MAX,
+		("recv: fd=%p osfd=%" PR_PRIdOSFD " buf=%p amount=%d flags=%d",
+		fd, fd->secret->md.osfd, buf, amount, flags));
+
+#ifdef _PR_HAVE_PEEK_BUFFER
+	if (fd->secret->peekBytes != 0) {
+		rv = (amount < fd->secret->peekBytes) ?
+			amount : fd->secret->peekBytes;
+		memcpy(buf, fd->secret->peekBuffer, rv);
+		if (flags == 0) {
+			/* consume the bytes in the peek buffer */
+			fd->secret->peekBytes -= rv;
+			if (fd->secret->peekBytes != 0) {
+				memmove(fd->secret->peekBuffer,
+					fd->secret->peekBuffer + rv,
+					fd->secret->peekBytes);
+			}
+		}
+		return rv;
+	}
+
+	/* allocate peek buffer, if necessary */
+	if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) {
+		PR_ASSERT(0 == fd->secret->peekBytes);
+		/* impose a max size on the peek buffer */
+		if (amount > _PR_PEEK_BUFFER_MAX) {
+			amount = _PR_PEEK_BUFFER_MAX;
+		}
+		if (fd->secret->peekBufSize < amount) {
+			if (fd->secret->peekBuffer) {
+				PR_Free(fd->secret->peekBuffer);
+			}
+			fd->secret->peekBufSize = amount;
+			fd->secret->peekBuffer = PR_Malloc(amount);
+			if (NULL == fd->secret->peekBuffer) {
+				fd->secret->peekBufSize = 0;
+				PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+				return -1;
+			}
+		}
+	}
+#endif
+
+	rv = _PR_MD_RECV(fd, buf, amount, flags, timeout);
+	PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv -> %d, error = %d, os error = %d",
+		rv, PR_GetError(), PR_GetOSError()));
+
+#ifdef _PR_HAVE_PEEK_BUFFER
+	if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) {
+		if (rv > 0) {
+			memcpy(fd->secret->peekBuffer, buf, rv);
+			fd->secret->peekBytes = rv;
+		}
+	}
+#endif
+
+	return rv;
+}
+
+static PRInt32 PR_CALLBACK SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+	return SocketRecv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}
+
+static PRInt32 PR_CALLBACK SocketSend(PRFileDesc *fd, const void *buf, PRInt32 amount,
+PRIntn flags, PRIntervalTime timeout)
+{
+	PRInt32 temp, count;
+	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;
+	}
+
+	count = 0;
+	while (amount > 0) {
+		PR_LOG(_pr_io_lm, PR_LOG_MAX,
+		    ("send: fd=%p osfd=%" PR_PRIdOSFD " buf=%p amount=%d",
+		    fd, fd->secret->md.osfd, buf, amount));
+		temp = _PR_MD_SEND(fd, buf, amount, flags, timeout);
+		if (temp < 0) {
+					count = -1;
+					break;
+				}
+
+		count += temp;
+		if (fd->secret->nonblocking) {
+			break;
+		}
+		buf = (const void*) ((const char*)buf + temp);
+
+		amount -= temp;
+	}
+	PR_LOG(_pr_io_lm, PR_LOG_MAX, ("send -> %d", count));
+	return count;
+}
+
+static PRInt32 PR_CALLBACK SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+	return SocketSend(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}
+
+static PRStatus PR_CALLBACK SocketClose(PRFileDesc *fd)
+{
+	if (!fd || !fd->secret
+			|| (fd->secret->state != _PR_FILEDESC_OPEN
+			&& fd->secret->state != _PR_FILEDESC_CLOSED)) {
+		PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+		return PR_FAILURE;
+	}
+
+	if (fd->secret->state == _PR_FILEDESC_OPEN) {
+		if (_PR_MD_CLOSE_SOCKET(fd->secret->md.osfd) < 0) {
+			return PR_FAILURE;
+		}
+		fd->secret->state = _PR_FILEDESC_CLOSED;
+	}
+
+#ifdef _PR_HAVE_PEEK_BUFFER
+	if (fd->secret->peekBuffer) {
+		PR_ASSERT(fd->secret->peekBufSize > 0);
+		PR_DELETE(fd->secret->peekBuffer);
+		fd->secret->peekBufSize = 0;
+		fd->secret->peekBytes = 0;
+	}
+#endif
+
+	PR_FreeFileDesc(fd);
+	return PR_SUCCESS;
+}
+
+static PRInt32 PR_CALLBACK SocketAvailable(PRFileDesc *fd)
+{
+	PRInt32 rv;
+#ifdef _PR_HAVE_PEEK_BUFFER
+	if (fd->secret->peekBytes != 0) {
+		return fd->secret->peekBytes;
+	}
+#endif
+	rv =  _PR_MD_SOCKETAVAILABLE(fd);
+	return rv;		
+}
+
+static PRInt64 PR_CALLBACK SocketAvailable64(PRFileDesc *fd)
+{
+    PRInt64 rv;
+#ifdef _PR_HAVE_PEEK_BUFFER
+    if (fd->secret->peekBytes != 0) {
+        LL_I2L(rv, fd->secret->peekBytes);
+        return rv;
+    }
+#endif
+    LL_I2L(rv, _PR_MD_SOCKETAVAILABLE(fd));
+	return rv;		
+}
+
+static PRStatus PR_CALLBACK SocketSync(PRFileDesc *fd)
+{
+	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,
+		    addrp, PR_NETADDR_SIZE(addr), timeout);
+		if (temp < 0) {
+					count = -1;
+					break;
+				}
+		count += temp;
+		if (fd->secret->nonblocking) {
+			break;
+		}
+		buf = (const void*) ((const char*)buf + temp);
+		amount -= temp;
+	}
+	return count;
+}
+
+static PRInt32 PR_CALLBACK SocketRecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	PRUint32 al;
+	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;
+	}
+
+	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;
+	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;
+	}
+	/* The socket must be in blocking mode. */
+	if (sd->secret->nonblocking) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+	}
+	*nd = NULL;
+
+#if defined(WINNT)
+	{
+	PROsfd newSock;
+	PRNetAddr *raddrCopy;
+
+	if (raddr == NULL) {
+		raddr = &raddrCopy;
+	}
+	rv = _PR_MD_ACCEPT_READ(sd, &newSock, raddr, buf, amount, timeout);
+	if (rv < 0) {
+		rv = -1;
+	} else {
+		/* Successfully accepted and read; create the new PRFileDesc */
+		*nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods());
+		if (*nd == 0) {
+			_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;
+}
+
+#ifdef WINNT
+PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, 
+PRNetAddr **raddr, void *buf, PRInt32 amount,
+PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	PROsfd newSock;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	PRNetAddr *raddrCopy;
+
+	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;
+	}
+	*nd = NULL;
+
+	if (raddr == NULL) {
+		raddr = &raddrCopy;
+	}
+	rv = _PR_MD_FAST_ACCEPT_READ(sd, &newSock, raddr, buf, amount, 
+	    timeout, PR_TRUE, NULL, NULL);
+	if (rv < 0) {
+		rv = -1;
+	} else {
+		/* Successfully accepted and read; create the new PRFileDesc */
+		*nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods());
+		if (*nd == 0) {
+			_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
+#ifdef _PR_NEED_SECRET_AF
+			(*nd)->secret->af = sd->secret->af;
+#endif
+		}
+	}
+	return rv;
+}
+
+PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback(
+PRFileDesc *sd, PRFileDesc **nd, 
+PRNetAddr **raddr, void *buf, PRInt32 amount,
+PRIntervalTime timeout,
+_PR_AcceptTimeoutCallback callback,
+void *callbackArg)
+{
+	PRInt32 rv;
+	PROsfd newSock;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	PRNetAddr *raddrCopy;
+
+	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;
+	}
+	*nd = NULL;
+
+	if (raddr == NULL) {
+		raddr = &raddrCopy;
+	}
+	rv = _PR_MD_FAST_ACCEPT_READ(sd, &newSock, raddr, buf, amount,
+	    timeout, PR_TRUE, callback, callbackArg);
+	if (rv < 0) {
+		rv = -1;
+	} else {
+		/* Successfully accepted and read; create the new PRFileDesc */
+		*nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods());
+		if (*nd == 0) {
+			_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
+#ifdef _PR_NEED_SECRET_AF
+			(*nd)->secret->af = sd->secret->af;
+#endif
+		}
+	}
+	return rv;
+}
+#endif /* WINNT */
+
+#ifdef WINNT
+PR_IMPLEMENT(void)
+PR_NTFast_UpdateAcceptContext(PRFileDesc *socket, PRFileDesc *acceptSocket)
+{
+	_PR_MD_UPDATE_ACCEPT_CONTEXT(
+		socket->secret->md.osfd, acceptSocket->secret->md.osfd);
+}
+#endif /* WINNT */
+
+static PRInt32 PR_CALLBACK SocketSendFile(
+    PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	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;
+	}
+	/* The socket must be in blocking mode. */
+	if (sd->secret->nonblocking) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+	}
+#if defined(WINNT)
+	rv = _PR_MD_SENDFILE(sd, sfd, flags, timeout);
+	if ((rv >= 0) && (flags == PR_TRANSMITFILE_CLOSE_SOCKET)) {
+		/*
+		 * This should be kept the same as SocketClose, except
+		 * that _PR_MD_CLOSE_SOCKET(sd->secret->md.osfd) should
+		 * not be called because the socket will be recycled.
+		 */
+		PR_FreeFileDesc(sd);
+	}
+#else
+	rv = PR_EmulateSendFile(sd, sfd, flags, timeout);
+#endif	/* WINNT */
+
+	return rv;
+}
+
+static PRInt32 PR_CALLBACK SocketTransmitFile(PRFileDesc *sd, PRFileDesc *fd, 
+const void *headers, PRInt32 hlen, PRTransmitFileFlags flags,
+PRIntervalTime timeout)
+{
+	PRSendFileData sfd;
+
+	sfd.fd = fd;
+	sfd.file_offset = 0;
+	sfd.file_nbytes = 0;
+	sfd.header = headers;
+	sfd.hlen = hlen;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+
+	return(SocketSendFile(sd, &sfd, flags, timeout));
+}
+
+static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr)
+{
+	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 PRInt16 PR_CALLBACK SocketPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    *out_flags = 0;
+    return in_flags;
+}  /* SocketPoll */
+
+static PRIOMethods tcpMethods = {
+	PR_DESC_SOCKET_TCP,
+	SocketClose,
+	SocketRead,
+	SocketWrite,
+	SocketAvailable,
+	SocketAvailable64,
+	SocketSync,
+	(PRSeekFN)_PR_InvalidInt,
+	(PRSeek64FN)_PR_InvalidInt64,
+	(PRFileInfoFN)_PR_InvalidStatus,
+	(PRFileInfo64FN)_PR_InvalidStatus,
+	SocketWritev,
+	SocketConnect,
+	SocketAccept,
+	SocketBind,
+	SocketListen,
+	SocketShutdown,
+	SocketRecv,
+	SocketSend,
+	(PRRecvfromFN)_PR_InvalidInt,
+	(PRSendtoFN)_PR_InvalidInt,
+	SocketPoll,
+	SocketAcceptRead,
+	SocketTransmitFile,
+	SocketGetName,
+	SocketGetPeerName,
+	(PRReservedFN)_PR_InvalidInt,
+	(PRReservedFN)_PR_InvalidInt,
+	_PR_SocketGetSocketOption,
+	_PR_SocketSetSocketOption,
+    SocketSendFile, 
+    SocketConnectContinue,
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods udpMethods = {
+	PR_DESC_SOCKET_UDP,
+	SocketClose,
+	SocketRead,
+	SocketWrite,
+	SocketAvailable,
+	SocketAvailable64,
+	SocketSync,
+	(PRSeekFN)_PR_InvalidInt,
+	(PRSeek64FN)_PR_InvalidInt64,
+	(PRFileInfoFN)_PR_InvalidStatus,
+	(PRFileInfo64FN)_PR_InvalidStatus,
+	SocketWritev,
+	SocketConnect,
+	(PRAcceptFN)_PR_InvalidDesc,
+	SocketBind,
+	SocketListen,
+	SocketShutdown,
+	SocketRecv,
+	SocketSend,
+	SocketRecvFrom,
+	SocketSendTo,
+	SocketPoll,
+	(PRAcceptreadFN)_PR_InvalidInt,
+	(PRTransmitfileFN)_PR_InvalidInt,
+	SocketGetName,
+	SocketGetPeerName,
+	(PRReservedFN)_PR_InvalidInt,
+	(PRReservedFN)_PR_InvalidInt,
+	_PR_SocketGetSocketOption,
+	_PR_SocketSetSocketOption,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+
+static PRIOMethods socketpollfdMethods = {
+    (PRDescType) 0,
+    (PRCloseFN)_PR_InvalidStatus,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+	SocketPoll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods()
+{
+	return &tcpMethods;
+}
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods()
+{
+	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)
+
+extern PRBool _pr_ipv6_is_present(void);
+
+PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket()
+{
+	PROsfd 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)
+{
+	PROsfd osfd;
+	PRFileDesc *fd;
+	PRInt32 tmp_domain = domain;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	if (PR_AF_INET != domain
+			&& PR_AF_INET6 != domain
+#if defined(XP_UNIX) || defined(XP_OS2)
+			&& PR_AF_LOCAL != domain
+#endif
+			) {
+		PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return NULL;
+	}
+
+#if defined(_PR_INET6_PROBE)
+	if (PR_AF_INET6 == domain)
+		domain = _pr_ipv6_is_present() ? AF_INET6 : AF_INET;
+#elif defined(_PR_INET6)
+	if (PR_AF_INET6 == domain)
+		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) {
+		_PR_MD_MAKE_NONBLOCK(fd);
+		_PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
+#ifdef _PR_NEED_SECRET_AF
+		fd->secret->af = domain;
+#endif
+#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6)
+		/*
+		 * 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;
+
+	return PR_Socket(domain, SOCK_STREAM, 0);
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void)
+{
+	PRInt32 domain = AF_INET;
+
+	return PR_Socket(domain, SOCK_DGRAM, 0);
+}
+
+PR_IMPLEMENT(PRFileDesc *) PR_OpenTCPSocket(PRIntn af)
+{
+	return PR_Socket(af, SOCK_STREAM, 0);
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenUDPSocket(PRIntn af)
+{
+	return PR_Socket(af, SOCK_DGRAM, 0);
+}
+
+PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[])
+{
+#ifdef XP_UNIX
+	PRInt32 rv, osfd[2];
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	rv = _PR_MD_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, osfd);
+	if (rv == -1) {
+		return PR_FAILURE;
+	}
+
+	f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());
+	if (!f[0]) {
+		_PR_MD_CLOSE_SOCKET(osfd[0]);
+		_PR_MD_CLOSE_SOCKET(osfd[1]);
+		/* PR_AllocFileDesc() has invoked PR_SetError(). */
+		return PR_FAILURE;
+	}
+	f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());
+	if (!f[1]) {
+		PR_Close(f[0]);
+		_PR_MD_CLOSE_SOCKET(osfd[1]);
+		/* PR_AllocFileDesc() has invoked PR_SetError(). */
+		return PR_FAILURE;
+	}
+	_PR_MD_MAKE_NONBLOCK(f[0]);
+	_PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);
+	_PR_MD_MAKE_NONBLOCK(f[1]);
+	_PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);
+	return PR_SUCCESS;
+#elif defined(WINNT)
+    /*
+     * A socket pair is often used for interprocess communication,
+     * so we need to make sure neither socket is associated with
+     * the I/O completion port; otherwise it can't be used by a
+     * child process.
+     *
+     * The default implementation below cannot be used for NT
+     * because PR_Accept would have associated the I/O completion
+     * port with the listening and accepted sockets.
+     */
+    SOCKET listenSock;
+    SOCKET osfd[2];
+    struct sockaddr_in selfAddr, peerAddr;
+    int addrLen;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    osfd[0] = osfd[1] = INVALID_SOCKET;
+    listenSock = socket(AF_INET, SOCK_STREAM, 0);
+    if (listenSock == INVALID_SOCKET) {
+        goto failed;
+    }
+    selfAddr.sin_family = AF_INET;
+    selfAddr.sin_port = 0;
+    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* BugZilla: 35408 */
+    addrLen = sizeof(selfAddr);
+    if (bind(listenSock, (struct sockaddr *) &selfAddr,
+            addrLen) == SOCKET_ERROR) {
+        goto failed;
+    }
+    if (getsockname(listenSock, (struct sockaddr *) &selfAddr,
+            &addrLen) == SOCKET_ERROR) {
+        goto failed;
+    }
+    if (listen(listenSock, 5) == SOCKET_ERROR) {
+        goto failed;
+    }
+    osfd[0] = socket(AF_INET, SOCK_STREAM, 0);
+    if (osfd[0] == INVALID_SOCKET) {
+        goto failed;
+    }
+    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+    /*
+     * Only a thread is used to do the connect and accept.
+     * I am relying on the fact that connect returns
+     * successfully as soon as the connect request is put
+     * into the listen queue (but before accept is called).
+     * This is the behavior of the BSD socket code.  If
+     * connect does not return until accept is called, we
+     * will need to create another thread to call connect.
+     */
+    if (connect(osfd[0], (struct sockaddr *) &selfAddr,
+            addrLen) == SOCKET_ERROR) {
+        goto failed;
+    }
+    /*
+     * A malicious local process may connect to the listening
+     * socket, so we need to verify that the accepted connection
+     * is made from our own socket osfd[0].
+     */
+    if (getsockname(osfd[0], (struct sockaddr *) &selfAddr,
+            &addrLen) == SOCKET_ERROR) {
+        goto failed;
+    }
+    osfd[1] = accept(listenSock, (struct sockaddr *) &peerAddr, &addrLen);
+    if (osfd[1] == INVALID_SOCKET) {
+        goto failed;
+    }
+    if (peerAddr.sin_port != selfAddr.sin_port) {
+        /* the connection we accepted is not from osfd[0] */
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        goto failed;
+    }
+    closesocket(listenSock);
+
+    f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());
+    if (!f[0]) {
+        closesocket(osfd[0]);
+        closesocket(osfd[1]);
+        /* PR_AllocFileDesc() has invoked PR_SetError(). */
+        return PR_FAILURE;
+    }
+    f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());
+    if (!f[1]) {
+        PR_Close(f[0]);
+        closesocket(osfd[1]);
+        /* PR_AllocFileDesc() has invoked PR_SetError(). */
+        return PR_FAILURE;
+    }
+    _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);
+    _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);
+    return PR_SUCCESS;
+
+failed:
+    if (listenSock != INVALID_SOCKET) {
+        closesocket(listenSock);
+    }
+    if (osfd[0] != INVALID_SOCKET) {
+        closesocket(osfd[0]);
+    }
+    if (osfd[1] != INVALID_SOCKET) {
+        closesocket(osfd[1]);
+    }
+    return PR_FAILURE;
+#else /* not Unix or NT */
+    /*
+     * default implementation
+     */
+    PRFileDesc *listenSock;
+    PRNetAddr selfAddr, peerAddr;
+    PRUint16 port;
+
+    f[0] = f[1] = NULL;
+    listenSock = PR_NewTCPSocket();
+    if (listenSock == NULL) {
+        goto failed;
+    }
+    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */
+    if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    port = ntohs(selfAddr.inet.port);
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        goto failed;
+    }
+    f[0] = PR_NewTCPSocket();
+    if (f[0] == NULL) {
+        goto failed;
+    }
+#ifdef _PR_CONNECT_DOES_NOT_BIND
+    /*
+     * If connect does not implicitly bind the socket (e.g., on
+     * BeOS), we have to bind the socket so that we can get its
+     * port with getsockname later.
+     */
+    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr);
+    if (PR_Bind(f[0], &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+#endif
+    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr);
+
+    /*
+     * Only a thread is used to do the connect and accept.
+     * I am relying on the fact that PR_Connect returns
+     * successfully as soon as the connect request is put
+     * into the listen queue (but before PR_Accept is called).
+     * This is the behavior of the BSD socket code.  If
+     * connect does not return until accept is called, we
+     * will need to create another thread to call connect.
+     */
+    if (PR_Connect(f[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT)
+            == PR_FAILURE) {
+        goto failed;
+    }
+    /*
+     * A malicious local process may connect to the listening
+     * socket, so we need to verify that the accepted connection
+     * is made from our own socket f[0].
+     */
+    if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT);
+    if (f[1] == NULL) {
+        goto failed;
+    }
+    if (peerAddr.inet.port != selfAddr.inet.port) {
+        /* the connection we accepted is not from f[0] */
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        goto failed;
+    }
+    PR_Close(listenSock);
+    return PR_SUCCESS;
+
+failed:
+    if (listenSock) {
+        PR_Close(listenSock);
+    }
+    if (f[0]) {
+        PR_Close(f[0]);
+    }
+    if (f[1]) {
+        PR_Close(f[1]);
+    }
+    return PR_FAILURE;
+#endif
+}
+
+PR_IMPLEMENT(PROsfd)
+PR_FileDesc2NativeHandle(PRFileDesc *fd)
+{
+    if (fd) {
+        fd = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER);
+    }
+    if (!fd) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+    return fd->secret->md.osfd;
+}
+
+PR_IMPLEMENT(void)
+PR_ChangeFileDescNativeHandle(PRFileDesc *fd, PROsfd handle)
+{
+	if (fd)
+		fd->secret->md.osfd = handle;
+}
+
+/*
+** Select compatibility
+**
+*/
+
+PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set)
+{
+	memset(set, 0, sizeof(PR_fd_set));
+}
+
+PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set)
+{
+	PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC );
+
+	set->harray[set->hsize++] = fh;
+}
+
+PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set)
+{
+	PRUint32 index, index2;
+
+	for (index = 0; index<set->hsize; index++)
+		if (set->harray[index] == fh) {
+			for (index2=index; index2 < (set->hsize-1); index2++) {
+				set->harray[index2] = set->harray[index2+1];
+			}
+			set->hsize--;
+			break;
+		}
+}
+
+PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set)
+{
+	PRUint32 index;
+	for (index = 0; index<set->hsize; index++)
+		if (set->harray[index] == fh) {
+			return 1;
+		}
+	return 0;
+}
+
+PR_IMPLEMENT(void) PR_FD_NSET(PROsfd fd, PR_fd_set *set)
+{
+	PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC );
+
+	set->narray[set->nsize++] = fd;
+}
+
+PR_IMPLEMENT(void) PR_FD_NCLR(PROsfd fd, PR_fd_set *set)
+{
+	PRUint32 index, index2;
+
+	for (index = 0; index<set->nsize; index++)
+		if (set->narray[index] == fd) {
+			for (index2=index; index2 < (set->nsize-1); index2++) {
+				set->narray[index2] = set->narray[index2+1];
+			}
+			set->nsize--;
+			break;
+		}
+}
+
+PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PROsfd fd, PR_fd_set *set)
+{
+	PRUint32 index;
+	for (index = 0; index<set->nsize; index++)
+		if (set->narray[index] == fd) {
+			return 1;
+		}
+	return 0;
+}
+
+
+#if !defined(NEED_SELECT)
+#include "obsolete/probslet.h"
+
+#define PD_INCR 20
+
+static PRPollDesc *_pr_setfd(
+    PR_fd_set *set, PRInt16 flags, PRPollDesc *polldesc)
+{
+    PRUintn fsidx, pdidx;
+    PRPollDesc *poll = polldesc;
+
+    if (NULL == set) return poll;
+
+	/* First set the pr file handle osfds */
+	for (fsidx = 0; fsidx < set->hsize; fsidx++)
+	{
+	    for (pdidx = 0; 1; pdidx++)
+        {
+            if ((PRFileDesc*)-1 == poll[pdidx].fd)
+            {
+                /* our vector is full - extend and condition it */
+                poll = (PRPollDesc*)PR_Realloc(
+                    poll, (pdidx + 1 + PD_INCR) * sizeof(PRPollDesc));
+                if (NULL == poll) goto out_of_memory;
+                memset(
+                    poll + pdidx * sizeof(PRPollDesc),
+                    0, PD_INCR * sizeof(PRPollDesc));
+                poll[pdidx + PD_INCR].fd = (PRFileDesc*)-1;
+            }
+            if ((NULL == poll[pdidx].fd)
+            || (poll[pdidx].fd == set->harray[fsidx]))
+            {
+                /* PR_ASSERT(0 == (poll[pdidx].in_flags & flags)); */
+                /* either empty or prevously defined */
+                poll[pdidx].fd = set->harray[fsidx];  /* possibly redundant */
+                poll[pdidx].in_flags |= flags;  /* possibly redundant */
+                break;
+            }
+        }
+	}
+
+#if 0
+	/* Second set the native osfds */
+	for (fsidx = 0; fsidx < set->nsize; fsidx++)
+	{
+	    for (pdidx = 0; ((PRFileDesc*)-1 != poll[pdidx].fd); pdidx++)
+        {
+            if ((PRFileDesc*)-1 == poll[pdidx].fd)
+            {
+                /* our vector is full - extend and condition it */
+                poll = PR_Realloc(
+                    poll, (pdidx + PD_INCR) * sizeof(PRPollDesc));
+                if (NULL == poll) goto out_of_memory;
+                memset(
+                    poll + pdidx * sizeof(PRPollDesc),
+                    0, PD_INCR * sizeof(PRPollDesc));
+                poll[(pdidx + PD_INCR)].fd = (PRFileDesc*)-1;
+            }
+            if ((NULL == poll[pdidx].fd)
+            || (poll[pdidx].fd == set->narray[fsidx]))
+            {
+                /* either empty or prevously defined */
+                poll[pdidx].fd = set->narray[fsidx];
+                PR_ASSERT(0 == (poll[pdidx].in_flags & flags));
+                poll[pdidx].in_flags |= flags;
+                break;
+            }
+        }
+	}
+#endif /* 0 */
+
+	return poll;
+
+out_of_memory:
+    if (NULL != polldesc) PR_DELETE(polldesc);
+    return NULL;
+}  /* _pr_setfd */
+
+#endif /* !defined(NEED_SELECT) */
+
+PR_IMPLEMENT(PRInt32) PR_Select(
+    PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, 
+    PR_fd_set *pr_ex, PRIntervalTime timeout)
+{
+
+#if !defined(NEED_SELECT)
+    PRInt32 npds = 0; 
+    /*
+    ** Find out how many fds are represented in the three lists.
+    ** Then allocate a polling descriptor for the logical union
+    ** (there can't be any overlapping) and call PR_Poll().
+    */
+
+    PRPollDesc *copy, *poll;
+
+    static PRBool warning = PR_TRUE;
+    if (warning) warning = _PR_Obsolete( "PR_Select()", "PR_Poll()");
+
+    /* try to get an initial guesss at how much space we need */
+    npds = 0;
+    if ((NULL != pr_rd) && ((pr_rd->hsize + pr_rd->nsize - npds) > 0))
+        npds = pr_rd->hsize + pr_rd->nsize;
+    if ((NULL != pr_wr) && ((pr_wr->hsize + pr_wr->nsize - npds) > 0))
+        npds = pr_wr->hsize + pr_wr->nsize;
+    if ((NULL != pr_ex) && ((pr_ex->hsize + pr_ex->nsize - npds) > 0))
+        npds = pr_ex->hsize + pr_ex->nsize;
+
+    if (0 == npds)
+    {
+        PR_Sleep(timeout);
+        return 0;
+    }
+
+    copy = poll = (PRPollDesc*)PR_Calloc(npds + PD_INCR, sizeof(PRPollDesc));
+    if (NULL == poll) goto out_of_memory;
+    poll[npds + PD_INCR - 1].fd = (PRFileDesc*)-1;
+
+    poll = _pr_setfd(pr_rd, PR_POLL_READ, poll);
+    if (NULL == poll) goto out_of_memory;
+    poll = _pr_setfd(pr_wr, PR_POLL_WRITE, poll);
+    if (NULL == poll) goto out_of_memory;
+    poll = _pr_setfd(pr_ex, PR_POLL_EXCEPT, poll);
+    if (NULL == poll) goto out_of_memory;
+    unused = 0;
+    while (NULL != poll[unused].fd && (PRFileDesc*)-1 != poll[unused].fd)
+    {
+        ++unused;
+    }
+
+    PR_ASSERT(unused > 0);
+    npds = PR_Poll(poll, unused, timeout);
+
+    if (npds > 0)
+    {
+        /* Copy the results back into the fd sets */
+        if (NULL != pr_rd) pr_rd->nsize = pr_rd->hsize = 0;
+        if (NULL != pr_wr) pr_wr->nsize = pr_wr->hsize = 0;
+        if (NULL != pr_ex) pr_ex->nsize = pr_ex->hsize = 0;
+        for (copy = &poll[unused - 1]; copy >= poll; --copy)
+        {
+            if (copy->out_flags & PR_POLL_NVAL)
+            {
+                PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+                npds = -1;
+                break;
+            }
+            if (copy->out_flags & PR_POLL_READ)
+                if (NULL != pr_rd) pr_rd->harray[pr_rd->hsize++] = copy->fd;
+            if (copy->out_flags & PR_POLL_WRITE)
+                if (NULL != pr_wr) pr_wr->harray[pr_wr->hsize++] = copy->fd;
+            if (copy->out_flags & PR_POLL_EXCEPT)
+                if (NULL != pr_ex) pr_ex->harray[pr_ex->hsize++] = copy->fd;
+        }
+    }
+    PR_DELETE(poll);
+
+    return npds;
+out_of_memory:
+    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    return -1;    
+
+#endif /* !defined(NEED_SELECT) */
+    
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prstdio.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prstdio.c
new file mode 100644
index 0000000..b8a091f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/io/prstdio.c
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+
+/*
+** fprintf to a PRFileDesc
+*/
+PR_IMPLEMENT(PRUint32) PR_fprintf(PRFileDesc* fd, const char *fmt, ...)
+{
+    va_list ap;
+    PRUint32 rv;
+
+    va_start(ap, fmt);
+    rv = PR_vfprintf(fd, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+PR_IMPLEMENT(PRUint32) PR_vfprintf(PRFileDesc* fd, const char *fmt, va_list ap)
+{
+    /* XXX this could be better */
+    PRUint32 rv, len;
+    char* msg = PR_vsmprintf(fmt, ap);
+    if (NULL == msg) {
+        return -1;
+    }
+    len = strlen(msg);
+#ifdef XP_OS2
+    /*
+     * OS/2 really needs a \r for every \n.
+     * In the future we should try to use scatter-gather instead of a
+     * succession of PR_Write.
+     */
+    if (isatty(PR_FileDesc2NativeHandle(fd))) {
+        PRUint32 last = 0, idx;
+        PRInt32 tmp;
+        rv = 0;
+        for (idx = 0; idx < len+1; idx++) {
+            if ((idx - last > 0) && (('\n' == msg[idx]) || (idx == len))) {
+                tmp = PR_Write(fd, msg + last, idx - last);
+                if (tmp >= 0) {
+                    rv += tmp;
+                }
+                last = idx;
+            }
+            /*
+             * if current character is \n, and
+             * previous character isn't \r, and
+             * next character isn't \r
+             */
+            if (('\n' == msg[idx]) &&
+                ((0 == idx) || ('\r' != msg[idx-1])) &&
+                ('\r' != msg[idx+1])) {
+                /* add extra \r */
+                tmp = PR_Write(fd, "\r", 1);
+                if (tmp >= 0) {
+                    rv += tmp;
+                }
+            }
+        }
+    } else {
+        rv = PR_Write(fd, msg, len);
+    }
+#else
+    rv = PR_Write(fd, msg, len);
+#endif
+    PR_DELETE(msg);
+    return rv;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/linking/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/linking/Makefile.in
new file mode 100644
index 0000000..738132d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/linking/Makefile.in
@@ -0,0 +1,70 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+# Disable optimization of the nspr on SunOS4.1.3
+ifeq ($(OS_ARCH),SunOS)
+ifeq ($(OS_RELEASE),4.1.3_U1)
+OPTIMIZER =
+endif
+endif
+
+CSRCS =           \
+	prlink.c   \
+	$(NULL)
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES += -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/linking/prlink.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/linking/prlink.c
new file mode 100644
index 0000000..7cc55c4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/linking/prlink.c
@@ -0,0 +1,1630 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Steve Streeter (Hewlett-Packard Company)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+
+#ifdef XP_BEOS
+#include <image.h>
+#endif
+
+#if defined(XP_MACOSX) && defined(USE_MACH_DYLD)
+#include <Carbon/Carbon.h>
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#ifdef XP_UNIX
+#ifdef USE_DLFCN
+#include <dlfcn.h>
+/* Define these on systems that don't have them. */
+#ifndef RTLD_NOW
+#define RTLD_NOW 0
+#endif
+#ifndef RTLD_LAZY
+#define RTLD_LAZY RTLD_NOW
+#endif
+#ifndef RTLD_GLOBAL
+#define RTLD_GLOBAL 0
+#endif
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+#ifdef AIX
+#include <sys/ldr.h>
+#ifndef L_IGNOREUNLOAD /* AIX 4.3.3 does not have L_IGNOREUNLOAD. */
+#define L_IGNOREUNLOAD 0x10000000
+#endif
+#endif
+#ifdef OSF1
+#include <loader.h>
+#include <rld_interface.h>
+#endif
+#elif defined(USE_HPSHL)
+#include <dl.h>
+#elif defined(USE_MACH_DYLD)
+#include <mach-o/dyld.h>
+#endif
+#endif /* XP_UNIX */
+
+#define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY
+
+/*
+ * On these platforms, symbols have a leading '_'.
+ */
+#if defined(SUNOS4) || (defined(DARWIN) && defined(USE_MACH_DYLD)) \
+    || defined(NEXTSTEP) || defined(XP_OS2) \
+    || ((defined(OPENBSD) || defined(NETBSD)) && !defined(__ELF__))
+#define NEED_LEADING_UNDERSCORE
+#endif
+
+#define PR_LD_PATHW 0x8000  /* for PR_LibSpec_PathnameU */
+
+/************************************************************************/
+
+struct PRLibrary {
+    char*                       name;  /* Our own copy of the name string */
+    PRLibrary*                  next;
+    int                         refCount;
+    const PRStaticLinkTable*    staticTable;
+
+#ifdef XP_PC
+#ifdef XP_OS2
+    HMODULE                     dlh;
+#else
+    HINSTANCE                   dlh;
+#endif
+#endif
+
+#if defined(XP_MACOSX) && defined(USE_MACH_DYLD)
+    CFragConnectionID           connection;
+    CFBundleRef                 bundle;
+    Ptr                         main;
+    CFMutableDictionaryRef      wrappers;
+    const struct mach_header*   image;
+#endif
+
+#ifdef XP_UNIX
+#if defined(USE_HPSHL)
+    shl_t                       dlh;
+#elif defined(USE_MACH_DYLD)
+    NSModule                    dlh;
+#else
+    void*                       dlh;
+#endif 
+#endif 
+
+#ifdef XP_BEOS
+    void*                       dlh;
+    void*                       stub_dlh;
+#endif
+};
+
+static PRLibrary *pr_loadmap;
+static PRLibrary *pr_exe_loadmap;
+static PRMonitor *pr_linker_lock;
+static char* _pr_currentLibPath = NULL;
+
+static PRLibrary *pr_LoadLibraryByPathname(const char *name, PRIntn flags);
+
+/************************************************************************/
+
+#if !defined(USE_DLFCN) && !defined(HAVE_STRERROR)
+#define ERR_STR_BUF_LENGTH    20
+#endif
+
+static void DLLErrorInternal(PRIntn oserr)
+/*
+** This whole function, and most of the code in this file, are run
+** with a big hairy lock wrapped around it. Not the best of situations,
+** but will eventually come up with the right answer.
+*/
+{
+    const char *error = NULL;
+#ifdef USE_DLFCN
+    error = dlerror();  /* $$$ That'll be wrong some of the time - AOF */
+#elif defined(HAVE_STRERROR)
+    error = strerror(oserr);  /* this should be okay */
+#else
+    char errStrBuf[ERR_STR_BUF_LENGTH];
+    PR_snprintf(errStrBuf, sizeof(errStrBuf), "error %d", oserr);
+    error = errStrBuf;
+#endif
+    if (NULL != error)
+        PR_SetErrorText(strlen(error), error);
+}  /* DLLErrorInternal */
+
+void _PR_InitLinker(void)
+{
+    PRLibrary *lm = NULL;
+#if defined(XP_UNIX)
+    void *h;
+#endif
+
+    if (!pr_linker_lock) {
+        pr_linker_lock = PR_NewNamedMonitor("linker-lock");
+    }
+    PR_EnterMonitor(pr_linker_lock);
+
+#if defined(XP_PC)
+    lm = PR_NEWZAP(PRLibrary);
+    lm->name = strdup("Executable");
+#if defined(XP_OS2)
+    lm->dlh = NULLHANDLE;
+#else
+    /* A module handle for the executable. */
+    lm->dlh = GetModuleHandle(NULL);
+#endif /* ! XP_OS2 */
+
+    lm->refCount    = 1;
+    lm->staticTable = NULL;
+    pr_exe_loadmap  = lm;
+    pr_loadmap      = lm;
+
+#elif defined(XP_UNIX)
+#ifdef HAVE_DLL
+#if defined(USE_DLFCN) && !defined(NO_DLOPEN_NULL)
+    h = dlopen(0, RTLD_LAZY);
+    if (!h) {
+        char *error;
+        
+        DLLErrorInternal(_MD_ERRNO());
+        error = (char*)PR_MALLOC(PR_GetErrorTextLength());
+        (void) PR_GetErrorText(error);
+        fprintf(stderr, "failed to initialize shared libraries [%s]\n",
+            error);
+        PR_DELETE(error);
+        abort();/* XXX */
+    }
+#elif defined(USE_HPSHL)
+    h = NULL;
+    /* don't abort with this NULL */
+#elif defined(USE_MACH_DYLD) || defined(NO_DLOPEN_NULL)
+    h = NULL; /* XXXX  toshok */ /* XXXX  vlad */
+#else
+#error no dll strategy
+#endif /* USE_DLFCN */
+
+    lm = PR_NEWZAP(PRLibrary);
+    if (lm) {
+        lm->name = strdup("a.out");
+        lm->refCount = 1;
+        lm->dlh = h;
+        lm->staticTable = NULL;
+    }
+    pr_exe_loadmap = lm;
+    pr_loadmap = lm;
+#endif /* HAVE_DLL */
+#endif /* XP_UNIX */
+
+    if (lm) {
+        PR_LOG(_pr_linker_lm, PR_LOG_MIN,
+            ("Loaded library %s (init)", lm->name));
+    }
+
+    PR_ExitMonitor(pr_linker_lock);
+}
+
+/*
+ * _PR_ShutdownLinker does not unload the dlls loaded by the application
+ * via calls to PR_LoadLibrary.  Any dlls that still remain on the
+ * pr_loadmap list when NSPR shuts down are application programming errors.
+ * The only exception is pr_exe_loadmap, which was added to the list by
+ * NSPR and hence should be cleaned up by NSPR.
+ */
+void _PR_ShutdownLinker(void)
+{
+    /* FIXME: pr_exe_loadmap should be destroyed. */
+    
+    PR_DestroyMonitor(pr_linker_lock);
+    pr_linker_lock = NULL;
+
+    if (_pr_currentLibPath) {
+        free(_pr_currentLibPath);
+        _pr_currentLibPath = NULL;
+    }
+}
+
+/******************************************************************************/
+
+PR_IMPLEMENT(PRStatus) PR_SetLibraryPath(const char *path)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    PR_EnterMonitor(pr_linker_lock);
+    if (_pr_currentLibPath) {
+        free(_pr_currentLibPath);
+    }
+    if (path) {
+        _pr_currentLibPath = strdup(path);
+        if (!_pr_currentLibPath) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        rv = PR_FAILURE;
+        }
+    } else {
+        _pr_currentLibPath = 0;
+    }
+    PR_ExitMonitor(pr_linker_lock);
+    return rv;
+}
+
+/*
+** Return the library path for finding shared libraries.
+*/
+PR_IMPLEMENT(char *) 
+PR_GetLibraryPath(void)
+{
+    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
+    ev = getenv("LD_LIBRARY_PATH");
+    if (!ev) {
+    ev = ".;\\lib";
+    }
+    ev = strdup(ev);
+#endif
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+#if defined(USE_DLFCN) || defined(USE_MACH_DYLD) || defined(XP_BEOS)
+    {
+    char *p=NULL;
+    int len;
+
+#ifdef XP_BEOS
+    ev = getenv("LIBRARY_PATH");
+    if (!ev) {
+        ev = "%A/lib:/boot/home/config/lib:/boot/beos/system/lib";
+    }
+#else
+    ev = getenv("LD_LIBRARY_PATH");
+    if (!ev) {
+        ev = "/usr/lib:/lib";
+    }
+#endif
+    len = strlen(ev) + 1;        /* +1 for the null */
+
+    p = (char*) malloc(len);
+    if (p) {
+        strcpy(p, ev);
+    }   /* if (p)  */
+    ev = p;
+    PR_LOG(_pr_io_lm, PR_LOG_NOTICE, ("linker path '%s'", ev));
+
+    }
+#else
+    /* AFAIK there isn't a library path with the HP SHL interface --Rob */
+    ev = strdup("");
+#endif
+#endif
+
+    /*
+     * If ev is NULL, we have run out of memory
+     */
+    _pr_currentLibPath = ev;
+
+  exit:
+    if (_pr_currentLibPath) {
+        copy = strdup(_pr_currentLibPath);
+    }
+    PR_ExitMonitor(pr_linker_lock);
+    if (!copy) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return copy;
+}
+
+/*
+** Build library name from path, lib and extensions
+*/
+PR_IMPLEMENT(char*) 
+PR_GetLibraryName(const char *path, const char *lib)
+{
+    char *fullname;
+
+#ifdef XP_PC
+    if (strstr(lib, PR_DLL_SUFFIX) == NULL)
+    {
+        if (path) {
+            fullname = PR_smprintf("%s\\%s%s", path, lib, PR_DLL_SUFFIX);
+        } else {
+            fullname = PR_smprintf("%s%s", lib, PR_DLL_SUFFIX);
+        }
+    } else {
+        if (path) {
+            fullname = PR_smprintf("%s\\%s", path, lib);
+        } else {
+            fullname = PR_smprintf("%s", lib);
+        }
+    }
+#endif /* XP_PC */
+#if defined(XP_UNIX) || defined(XP_BEOS)
+    if (strstr(lib, PR_DLL_SUFFIX) == NULL)
+    {
+        if (path) {
+            fullname = PR_smprintf("%s/lib%s%s", path, lib, PR_DLL_SUFFIX);
+        } else {
+            fullname = PR_smprintf("lib%s%s", lib, PR_DLL_SUFFIX);
+        }
+    } else {
+        if (path) {
+            fullname = PR_smprintf("%s/%s", path, lib);
+        } else {
+            fullname = PR_smprintf("%s", lib);
+        }
+    }
+#endif /* XP_UNIX || XP_BEOS */
+    return fullname;
+}
+
+/*
+** Free the memory allocated, for the caller, by PR_GetLibraryName
+*/
+PR_IMPLEMENT(void) 
+PR_FreeLibraryName(char *mem)
+{
+    PR_smprintf_free(mem);
+}
+
+static PRLibrary* 
+pr_UnlockedFindLibrary(const char *name)
+{
+    PRLibrary* lm = pr_loadmap;
+    const char* np = strrchr(name, PR_DIRECTORY_SEPARATOR);
+    np = np ? np + 1 : name;
+    while (lm) {
+    const char* cp = strrchr(lm->name, PR_DIRECTORY_SEPARATOR);
+    cp = cp ? cp + 1 : lm->name;
+#ifdef WIN32
+        /* Windows DLL names are case insensitive... */
+    if (strcmpi(np, cp) == 0) 
+#elif defined(XP_OS2)
+    if (stricmp(np, cp) == 0)
+#else
+    if (strcmp(np, cp)  == 0) 
+#endif
+    {
+        /* found */
+        lm->refCount++;
+        PR_LOG(_pr_linker_lm, PR_LOG_MIN,
+           ("%s incr => %d (find lib)",
+            lm->name, lm->refCount));
+        return lm;
+    }
+    lm = lm->next;
+    }
+    return NULL;
+}
+
+PR_IMPLEMENT(PRLibrary*)
+PR_LoadLibraryWithFlags(PRLibSpec libSpec, PRIntn flags)
+{
+    if (flags == 0) {
+        flags = _PR_DEFAULT_LD_FLAGS;
+    }
+    switch (libSpec.type) {
+        case PR_LibSpec_Pathname:
+            return pr_LoadLibraryByPathname(libSpec.value.pathname, flags);
+#ifdef WIN32
+        case PR_LibSpec_PathnameU:
+            /*
+             * cast to |char *| and set PR_LD_PATHW flag so that
+             * it can be cast back to PRUnichar* in the callee.
+             */
+            return pr_LoadLibraryByPathname((const char*) 
+                                            libSpec.value.pathname_u, 
+                                            flags | PR_LD_PATHW);
+#endif
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return NULL;
+    }
+}
+            
+PR_IMPLEMENT(PRLibrary*) 
+PR_LoadLibrary(const char *name)
+{
+    PRLibSpec libSpec;
+
+    libSpec.type = PR_LibSpec_Pathname;
+    libSpec.value.pathname = name;
+    return PR_LoadLibraryWithFlags(libSpec, 0);
+}
+
+#if defined(USE_MACH_DYLD)
+static NSModule
+pr_LoadMachDyldModule(const char *name)
+{
+    NSObjectFileImage ofi;
+    NSModule h = NULL;
+    if (NSCreateObjectFileImageFromFile(name, &ofi)
+            == NSObjectFileImageSuccess) {
+        h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE
+                         | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
+        /*
+         * TODO: If NSLinkModule fails, use NSLinkEditError to retrieve
+         * error information.
+         */
+        if (NSDestroyObjectFileImage(ofi) == FALSE) {
+            if (h) {
+                (void)NSUnLinkModule(h, NSUNLINKMODULE_OPTION_NONE);
+                h = NULL;
+            }
+        }
+    }
+    return h;
+}
+#endif
+
+#if defined(XP_MACOSX) && defined(USE_MACH_DYLD)
+
+/*
+** macLibraryLoadProc is a function definition for a Mac shared library
+** loading method. The "name" param is the same full or partial pathname
+** that was passed to pr_LoadLibraryByPathName. The function must fill
+** in the fields of "lm" which apply to its library type. Returns
+** PR_SUCCESS if successful.
+*/
+
+typedef PRStatus (*macLibraryLoadProc)(const char *name, PRLibrary *lm);
+
+#ifdef __ppc__
+
+/*
+** CFM and its TVectors only exist on PowerPC.  Other OS X architectures
+** only use Mach-O as a native binary format.
+*/
+
+static void* TV2FP(CFMutableDictionaryRef dict, const char* name, void *tvp)
+{
+    static uint32 glue[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 };
+    uint32* newGlue = NULL;
+
+    if (tvp != NULL) {
+        CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
+        if (nameRef) {
+            CFMutableDataRef glueData = (CFMutableDataRef) CFDictionaryGetValue(dict, nameRef);
+            if (glueData == NULL) {
+                glueData = CFDataCreateMutable(NULL, sizeof(glue));
+                if (glueData != NULL) {
+                    newGlue = (uint32*) CFDataGetMutableBytePtr(glueData);
+                    memcpy(newGlue, glue, sizeof(glue));
+                    newGlue[0] |= ((UInt32)tvp >> 16);
+                    newGlue[1] |= ((UInt32)tvp & 0xFFFF);
+                    MakeDataExecutable(newGlue, sizeof(glue));
+                    CFDictionaryAddValue(dict, nameRef, glueData);
+                    CFRelease(glueData);
+
+                    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: created wrapper for CFM function %s().", name));
+                }
+            } else {
+                PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: found wrapper for CFM function %s().", name));
+
+                newGlue = (uint32*) CFDataGetMutableBytePtr(glueData);
+            }
+            CFRelease(nameRef);
+        }
+    }
+    
+    return newGlue;
+}
+
+static PRStatus
+pr_LoadViaCFM(const char *name, PRLibrary *lm)
+{
+    OSErr err;
+    Str255 errName;
+    FSRef ref;
+    FSSpec fileSpec;
+    Boolean tempUnusedBool;
+
+    /*
+     * Make an FSSpec from the path name and call GetDiskFragment.
+     */
+
+    /* Use direct conversion of POSIX path to FSRef to FSSpec. */
+    err = FSPathMakeRef((const UInt8*)name, &ref, NULL);
+    if (err != noErr)
+        return PR_FAILURE;
+    err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL,
+                           &fileSpec, NULL);
+    if (err != noErr)
+        return PR_FAILURE;
+
+    /* Resolve an alias if this was one */
+    err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool,
+                           &tempUnusedBool);
+    if (err != noErr)
+        return PR_FAILURE;
+
+    /* Finally, try to load the library */
+    err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, fileSpec.name,
+                          kLoadCFrag, &lm->connection, &lm->main, errName);
+
+    if (err == noErr && lm->connection) {
+        /*
+         * if we're a mach-o binary, need to wrap all CFM function
+         * pointers. need a hash-table of already seen function
+         * pointers, etc.
+         */
+        lm->wrappers = CFDictionaryCreateMutable(NULL, 16,
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+        if (lm->wrappers) {
+            lm->main = TV2FP(lm->wrappers, "main", lm->main);
+        } else
+            err = memFullErr;
+    }
+    return (err == noErr) ? PR_SUCCESS : PR_FAILURE;
+}
+#endif /* __ppc__ */
+
+/*
+** Creates a CFBundleRef if the pathname refers to a Mac OS X bundle
+** directory. The caller is responsible for calling CFRelease() to
+** deallocate.
+*/
+
+static PRStatus
+pr_LoadCFBundle(const char *name, PRLibrary *lm)
+{
+    CFURLRef bundleURL;
+    CFBundleRef bundle = NULL;
+    char pathBuf[PATH_MAX];
+    const char *resolvedPath;
+    CFStringRef pathRef;
+
+    /* Takes care of relative paths and symlinks */
+    resolvedPath = realpath(name, pathBuf);
+    if (!resolvedPath)
+        return PR_FAILURE;
+        
+    pathRef = CFStringCreateWithCString(NULL, pathBuf, kCFStringEncodingUTF8);
+    if (pathRef) {
+        bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef,
+                                                  kCFURLPOSIXPathStyle, true);
+        if (bundleURL) {
+            bundle = CFBundleCreate(NULL, bundleURL);
+            CFRelease(bundleURL);
+        }
+        CFRelease(pathRef);
+    }
+
+    lm->bundle = bundle;
+    return (bundle != NULL) ? PR_SUCCESS : PR_FAILURE;
+}
+
+static PRStatus
+pr_LoadViaDyld(const char *name, PRLibrary *lm)
+{
+    lm->dlh = pr_LoadMachDyldModule(name);
+    if (lm->dlh == NULL) {
+        lm->image = NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ON_ERROR
+                               | NSADDIMAGE_OPTION_WITH_SEARCHING);
+        if (lm->image == NULL) {
+            NSLinkEditErrors linkEditError;
+            int errorNum;
+            const char *errorString;
+            const char *fileName;
+            NSLinkEditError(&linkEditError, &errorNum, &fileName, &errorString);
+            PR_LOG(_pr_linker_lm, PR_LOG_MIN, 
+                   ("LoadMachDyldModule error %d:%d for file %s:\n%s",
+                    linkEditError, errorNum, fileName, errorString));
+        }
+    }
+    return (lm->dlh != NULL || lm->image != NULL) ? PR_SUCCESS : PR_FAILURE;
+}
+
+#endif /* XP_MACOSX && USE_MACH_DYLD */
+
+/*
+** Dynamically load a library. Only load libraries once, so scan the load
+** map first.
+*/
+static PRLibrary*
+pr_LoadLibraryByPathname(const char *name, PRIntn flags)
+{
+    PRLibrary *lm;
+    PRLibrary* result = NULL;
+    PRInt32 oserr;
+#ifdef WIN32
+    char utf8name_stack[MAX_PATH];
+    char *utf8name_malloc = NULL;
+    char *utf8name = utf8name_stack;
+    PRUnichar wname_stack[MAX_PATH];
+    PRUnichar *wname_malloc = NULL;
+    PRUnichar *wname = wname_stack;
+    int len;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* See if library is already loaded */
+    PR_EnterMonitor(pr_linker_lock);
+
+#ifdef WIN32
+    if (flags & PR_LD_PATHW) {
+        /* cast back what's cast to |char *| for the argument passing. */
+        wname = (LPWSTR) name;
+    } else {
+        int wlen = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
+        if (wlen > MAX_PATH)
+            wname = wname_malloc = PR_Malloc(wlen * sizeof(PRUnichar));
+        if (wname == NULL ||
+            !MultiByteToWideChar(CP_ACP, 0,  name, -1, wname, wlen)) {
+            oserr = _MD_ERRNO();
+            goto unlock;
+        }
+    }
+    len = WideCharToMultiByte(CP_UTF8, 0, wname, -1, NULL, 0, NULL, NULL);
+    if (len > MAX_PATH)
+        utf8name = utf8name_malloc = PR_Malloc(len);
+    if (utf8name == NULL ||
+        !WideCharToMultiByte(CP_UTF8, 0, wname, -1,
+                             utf8name, len, NULL, NULL)) {
+        oserr = _MD_ERRNO();
+        goto unlock;
+    }
+    /* the list of loaded library names are always kept in UTF-8 
+     * on Win32 platforms */
+    result = pr_UnlockedFindLibrary(utf8name);
+#else
+    result = pr_UnlockedFindLibrary(name);
+#endif
+
+    if (result != NULL) goto unlock;
+
+    lm = PR_NEWZAP(PRLibrary);
+    if (lm == NULL) {
+        oserr = _MD_ERRNO();
+        goto unlock;
+    }
+    lm->staticTable = NULL;
+
+#ifdef XP_OS2  /* Why isn't all this stuff in MD code?! */
+    {
+        HMODULE h;
+        UCHAR pszError[_MAX_PATH];
+        ULONG ulRc = NO_ERROR;
+
+          ulRc = DosLoadModule(pszError, _MAX_PATH, (PSZ) name, &h);
+          if (ulRc != NO_ERROR) {
+              oserr = ulRc;
+              PR_DELETE(lm);
+              goto unlock;
+          }
+          lm->name = strdup(name);
+          lm->dlh  = h;
+          lm->next = pr_loadmap;
+          pr_loadmap = lm;
+    }
+#endif /* XP_OS2 */
+
+#ifdef WIN32
+    {
+    HINSTANCE h;
+
+    h = LoadLibraryExW(wname, NULL,
+                       (flags & PR_LD_ALT_SEARCH_PATH) ?
+                       LOAD_WITH_ALTERED_SEARCH_PATH : 0);
+    if (h == NULL) {
+        oserr = _MD_ERRNO();
+        PR_DELETE(lm);
+        goto unlock;
+    }
+    lm->name = strdup(utf8name);
+    lm->dlh = h;
+    lm->next = pr_loadmap;
+    pr_loadmap = lm;
+    }
+#endif /* WIN32 */
+
+#if defined(XP_MACOSX) && defined(USE_MACH_DYLD)
+    {
+    int     i;
+    PRStatus status;
+
+    static const macLibraryLoadProc loadProcs[] = {
+#ifdef __ppc__
+        pr_LoadViaDyld, pr_LoadCFBundle, pr_LoadViaCFM
+#else  /* __ppc__ */
+        pr_LoadViaDyld, pr_LoadCFBundle
+#endif /* __ppc__ */
+    };
+
+    for (i = 0; i < sizeof(loadProcs) / sizeof(loadProcs[0]); i++) {
+        if ((status = loadProcs[i](name, lm)) == PR_SUCCESS)
+            break;
+    }
+    if (status != PR_SUCCESS) {
+        oserr = cfragNoLibraryErr;
+        PR_DELETE(lm);
+        goto unlock;        
+    }
+    lm->name = strdup(name);
+    lm->next = pr_loadmap;
+    pr_loadmap = lm;
+    }
+#endif
+
+#if defined(XP_UNIX) && !(defined(XP_MACOSX) && defined(USE_MACH_DYLD))
+#ifdef HAVE_DLL
+    {
+#if defined(USE_DLFCN)
+#ifdef NTO
+    /* Neutrino needs RTLD_GROUP to load Netscape plugins. (bug 71179) */
+    int dl_flags = RTLD_GROUP;
+#elif defined(AIX)
+    /* AIX needs RTLD_MEMBER to load an archive member.  (bug 228899) */
+    int dl_flags = RTLD_MEMBER;
+#else
+    int dl_flags = 0;
+#endif
+    void *h = NULL;
+
+    if (flags & PR_LD_LAZY) {
+        dl_flags |= RTLD_LAZY;
+    }
+    if (flags & PR_LD_NOW) {
+        dl_flags |= RTLD_NOW;
+    }
+    if (flags & PR_LD_GLOBAL) {
+        dl_flags |= RTLD_GLOBAL;
+    }
+    if (flags & PR_LD_LOCAL) {
+        dl_flags |= RTLD_LOCAL;
+    }
+#if defined(DARWIN)
+    /* ensure the file exists if it contains a slash character i.e. path */
+    /* DARWIN's dlopen ignores the provided path and checks for the */
+    /* plain filename in DYLD_LIBRARY_PATH */
+    if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL ||
+        PR_Access(name, PR_ACCESS_EXISTS) == PR_SUCCESS) {
+            h = dlopen(name, dl_flags);
+        }
+#else
+    h = dlopen(name, dl_flags);
+#endif
+#elif defined(USE_HPSHL)
+    int shl_flags = 0;
+    shl_t h;
+
+    /*
+     * Use the DYNAMIC_PATH flag only if 'name' is a plain file
+     * name (containing no directory) to match the behavior of
+     * dlopen().
+     */
+    if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) {
+        shl_flags |= DYNAMIC_PATH;
+    }
+    if (flags & PR_LD_LAZY) {
+        shl_flags |= BIND_DEFERRED;
+    }
+    if (flags & PR_LD_NOW) {
+        shl_flags |= BIND_IMMEDIATE;
+    }
+    /* No equivalent of PR_LD_GLOBAL and PR_LD_LOCAL. */
+    h = shl_load(name, shl_flags, 0L);
+#elif defined(USE_MACH_DYLD)
+    NSModule h = pr_LoadMachDyldModule(name);
+#else
+#error Configuration error
+#endif
+    if (!h) {
+        oserr = _MD_ERRNO();
+        PR_DELETE(lm);
+        goto unlock;
+    }
+    lm->name = strdup(name);
+    lm->dlh = h;
+    lm->next = pr_loadmap;
+    pr_loadmap = lm;
+    }
+#endif /* HAVE_DLL */
+#endif /* XP_UNIX && !(XP_MACOSX && USE_MACH_DYLD) */
+
+    lm->refCount = 1;
+
+#ifdef XP_BEOS
+    {
+        image_info info;
+        int32 cookie = 0;
+        image_id imageid = B_ERROR;
+        image_id stubid = B_ERROR;
+        PRLibrary *p;
+
+        for (p = pr_loadmap; p != NULL; p = p->next) {
+            /* hopefully, our caller will always use the same string
+               to refer to the same library */
+            if (strcmp(name, p->name) == 0) {
+                /* we've already loaded this library */
+                imageid = info.id;
+                lm->refCount++;
+                break;
+            }
+        }
+
+        if(imageid == B_ERROR) {
+            /* it appears the library isn't yet loaded - load it now */
+            char stubName [B_PATH_NAME_LENGTH + 1];
+
+            /* the following is a work-around to a "bug" in the beos -
+               the beos system loader allows only 32M (system-wide)
+               to be used by code loaded as "add-ons" (code loaded
+               through the 'load_add_on()' system call, which includes
+               mozilla components), but allows 256M to be used by
+               shared libraries.
+               
+               unfortunately, mozilla is too large to fit into the
+               "add-on" space, so we must trick the loader into
+               loading some of the components as shared libraries.  this
+               is accomplished by creating a "stub" add-on (an empty
+               shared object), and linking it with the component
+               (the actual .so file generated by the build process,
+               without any modifications).  when this stub is loaded
+               by load_add_on(), the loader will automatically load the
+               component into the shared library space.
+            */
+
+            strcpy(stubName, name);
+            strcat(stubName, ".stub");
+
+            /* first, attempt to load the stub (thereby loading the
+               component as a shared library */
+            if ((stubid = load_add_on(stubName)) > B_ERROR) {
+                /* the stub was loaded successfully. */
+                imageid = B_FILE_NOT_FOUND;
+
+                cookie = 0;
+                while (get_next_image_info(0, &cookie, &info) == B_OK) {
+                    const char *endOfSystemName = strrchr(info.name, '/');
+                    const char *endOfPassedName = strrchr(name, '/');
+                    if( 0 == endOfSystemName ) 
+                        endOfSystemName = info.name;
+                    else
+                        endOfSystemName++;
+                    if( 0 == endOfPassedName )
+                        endOfPassedName = name;
+                    else
+                        endOfPassedName++;
+                    if (strcmp(endOfSystemName, endOfPassedName) == 0) {
+                        /* this is the actual component - remember it */
+                        imageid = info.id;
+                        break;
+                    }
+                }
+
+            } else {
+                /* we failed to load the "stub" - try to load the
+                   component directly as an add-on */
+                stubid = B_ERROR;
+                imageid = load_add_on(name);
+            }
+        }
+
+        if (imageid <= B_ERROR) {
+            oserr = imageid;
+            PR_DELETE( lm );
+            goto unlock;
+        }
+        lm->name = strdup(name);
+        lm->dlh = (void*)imageid;
+        lm->stub_dlh = (void*)stubid;
+        lm->next = pr_loadmap;
+        pr_loadmap = lm;
+    }
+#endif
+
+    result = lm;    /* success */
+    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", lm->name));
+
+  unlock:
+    if (result == NULL) {
+        PR_SetError(PR_LOAD_LIBRARY_ERROR, oserr);
+        DLLErrorInternal(oserr);  /* sets error text */
+    }
+#ifdef WIN32
+    if (utf8name_malloc) 
+        PR_Free(utf8name_malloc);
+    if (wname_malloc)
+        PR_Free(wname_malloc);
+#endif
+    PR_ExitMonitor(pr_linker_lock);
+    return result;
+}
+
+/*
+** Unload a shared library which was loaded via PR_LoadLibrary
+*/
+PR_IMPLEMENT(PRStatus) 
+PR_UnloadLibrary(PRLibrary *lib)
+{
+    int result = 0;
+    PRStatus status = PR_SUCCESS;
+
+    if ((lib == 0) || (lib->refCount <= 0)) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    PR_EnterMonitor(pr_linker_lock);
+    if (--lib->refCount > 0) {
+    PR_LOG(_pr_linker_lm, PR_LOG_MIN,
+           ("%s decr => %d",
+        lib->name, lib->refCount));
+    goto done;
+    }
+
+#ifdef XP_BEOS
+    if(((image_id)lib->stub_dlh) == B_ERROR)
+        unload_add_on( (image_id) lib->dlh );
+    else
+        unload_add_on( (image_id) lib->stub_dlh);
+#endif
+
+#ifdef XP_UNIX
+#ifdef HAVE_DLL
+#ifdef USE_DLFCN
+    result = dlclose(lib->dlh);
+#elif defined(USE_HPSHL)
+    result = shl_unload(lib->dlh);
+#elif defined(USE_MACH_DYLD)
+    if (lib->dlh)
+        result = NSUnLinkModule(lib->dlh, NSUNLINKMODULE_OPTION_NONE) ? 0 : -1;
+#else
+#error Configuration error
+#endif
+#endif /* HAVE_DLL */
+#endif /* XP_UNIX */
+#ifdef XP_PC
+    if (lib->dlh) {
+        FreeLibrary((HINSTANCE)(lib->dlh));
+        lib->dlh = (HINSTANCE)NULL;
+    }
+#endif  /* XP_PC */
+
+#if defined(XP_MACOSX) && defined(USE_MACH_DYLD)
+    /* Close the connection */
+    if (lib->connection)
+        CloseConnection(&(lib->connection));
+    if (lib->bundle)
+        CFRelease(lib->bundle);
+    if (lib->wrappers)
+        CFRelease(lib->wrappers);
+    /* No way to unload an image (lib->image) */
+#endif
+
+    /* unlink from library search list */
+    if (pr_loadmap == lib)
+        pr_loadmap = pr_loadmap->next;
+    else if (pr_loadmap != NULL) {
+        PRLibrary* prev = pr_loadmap;
+        PRLibrary* next = pr_loadmap->next;
+        while (next != NULL) {
+            if (next == lib) {
+                prev->next = next->next;
+                goto freeLib;
+            }
+            prev = next;
+            next = next->next;
+        }
+        /*
+         * fail (the library is not on the _pr_loadmap list),
+         * but don't wipe out an error from dlclose/shl_unload.
+         */
+        PR_ASSERT(!"_pr_loadmap and lib->refCount inconsistent");
+        if (result == 0) {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            status = PR_FAILURE;
+        }
+    }
+    /*
+     * We free the PRLibrary structure whether dlclose/shl_unload
+     * succeeds or not.
+     */
+
+  freeLib:
+    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Unloaded library %s", lib->name));
+    free(lib->name);
+    lib->name = NULL;
+    PR_DELETE(lib);
+    if (result != 0) {
+        PR_SetError(PR_UNLOAD_LIBRARY_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        status = PR_FAILURE;
+    }
+
+done:
+    PR_ExitMonitor(pr_linker_lock);
+    return status;
+}
+
+static void* 
+pr_FindSymbolInLib(PRLibrary *lm, const char *name)
+{
+    void *f = NULL;
+#ifdef XP_OS2
+    int rc;
+#endif
+
+    if (lm->staticTable != NULL) {
+        const PRStaticLinkTable* tp;
+        for (tp = lm->staticTable; tp->name; tp++) {
+            if (strcmp(name, tp->name) == 0) {
+                return (void*) tp->fp;
+            }
+        }
+        /* 
+        ** If the symbol was not found in the static table then check if
+        ** the symbol was exported in the DLL... Win16 only!!
+        */
+#if !defined(WIN16) && !defined(XP_BEOS)
+        PR_SetError(PR_FIND_SYMBOL_ERROR, 0);
+        return (void*)NULL;
+#endif
+    }
+    
+#ifdef XP_OS2
+    rc = DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);
+#if defined(NEED_LEADING_UNDERSCORE)
+    /*
+     * Older plugins (not built using GCC) will have symbols that are not
+     * underscore prefixed.  We check for that here.
+     */
+    if (rc != NO_ERROR) {
+        name++;
+        DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);
+    }
+#endif
+#endif  /* XP_OS2 */
+
+#ifdef WIN32
+    f = GetProcAddress(lm->dlh, name);
+#endif  /* WIN32 */
+
+#if defined(XP_MACOSX) && defined(USE_MACH_DYLD)
+/* add this offset to skip the leading underscore in name */
+#define SYM_OFFSET 1
+    if (lm->bundle) {
+        CFStringRef nameRef = CFStringCreateWithCString(NULL, name + SYM_OFFSET, kCFStringEncodingASCII);
+        if (nameRef) {
+            f = CFBundleGetFunctionPointerForName(lm->bundle, nameRef);
+            CFRelease(nameRef);
+        }
+    }
+    if (lm->connection) {
+        Ptr                 symAddr;
+        CFragSymbolClass    symClass;
+        Str255              pName;
+        
+        PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Looking up symbol: %s", name + SYM_OFFSET));
+        
+        c2pstrcpy(pName, name + SYM_OFFSET);
+        
+        f = (FindSymbol(lm->connection, pName, &symAddr, &symClass) == noErr) ? symAddr : NULL;
+        
+#ifdef __ppc__
+        /* callers expect mach-o function pointers, so must wrap tvectors with glue. */
+        if (f && symClass == kTVectorCFragSymbol) {
+            f = TV2FP(lm->wrappers, name + SYM_OFFSET, f);
+        }
+#endif /* __ppc__ */
+        
+        if (f == NULL && strcmp(name + SYM_OFFSET, "main") == 0) f = lm->main;
+    }
+    if (lm->image) {
+        NSSymbol symbol;
+        symbol = NSLookupSymbolInImage(lm->image, name,
+                 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
+                 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
+        if (symbol != NULL)
+            f = NSAddressOfSymbol(symbol);
+        else
+            f = NULL;
+    }
+#undef SYM_OFFSET
+#endif /* XP_MACOSX && USE_MACH_DYLD */
+
+#ifdef XP_BEOS
+    if( B_NO_ERROR != get_image_symbol( (image_id)lm->dlh, name, B_SYMBOL_TYPE_TEXT, &f ) ) {
+        f = NULL;
+    }
+#endif
+
+#ifdef XP_UNIX
+#ifdef HAVE_DLL
+#ifdef USE_DLFCN
+    f = dlsym(lm->dlh, name);
+#elif defined(USE_HPSHL)
+    if (shl_findsym(&lm->dlh, name, TYPE_PROCEDURE, &f) == -1) {
+        f = NULL;
+    }
+#elif defined(USE_MACH_DYLD)
+    if (lm->dlh) {
+        NSSymbol symbol;
+        symbol = NSLookupSymbolInModule(lm->dlh, name);
+        if (symbol != NULL)
+            f = NSAddressOfSymbol(symbol);
+        else
+            f = NULL;
+    }
+#endif
+#endif /* HAVE_DLL */
+#endif /* XP_UNIX */
+    if (f == NULL) {
+        PR_SetError(PR_FIND_SYMBOL_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+    }
+    return f;
+}
+
+/*
+** Called by class loader to resolve missing native's
+*/
+PR_IMPLEMENT(void*) 
+PR_FindSymbol(PRLibrary *lib, const char *raw_name)
+{
+    void *f = NULL;
+#if defined(NEED_LEADING_UNDERSCORE)
+    char *name;
+#else
+    const char *name;
+#endif
+    /*
+    ** 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)
+    /*
+    ** AIX with the normal linker put's a "." in front of the symbol
+    ** name.  When use "svcc" and "svld" then the "." disappears. Go
+    ** figure.
+    */
+    name = raw_name;
+#else
+    name = raw_name;
+#endif
+
+    PR_EnterMonitor(pr_linker_lock);
+    PR_ASSERT(lib != NULL);
+    f = pr_FindSymbolInLib(lib, name);
+
+#if defined(NEED_LEADING_UNDERSCORE)
+    PR_smprintf_free(name);
+#endif
+
+    PR_ExitMonitor(pr_linker_lock);
+    return f;
+}
+
+/*
+** Return the address of the function 'raw_name' in the library 'lib'
+*/
+PR_IMPLEMENT(PRFuncPtr) 
+PR_FindFunctionSymbol(PRLibrary *lib, const char *raw_name)
+{
+    return ((PRFuncPtr) PR_FindSymbol(lib, raw_name));
+}
+
+PR_IMPLEMENT(void*) 
+PR_FindSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)
+{
+    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)
+    /*
+    ** AIX with the normal linker put's a "." in front of the symbol
+    ** name.  When use "svcc" and "svld" then the "." disappears. Go
+    ** figure.
+    */
+    name = raw_name;
+#else
+    name = raw_name;
+#endif
+
+    PR_EnterMonitor(pr_linker_lock);
+
+    /* search all libraries */
+    for (lm = pr_loadmap; lm != NULL; lm = lm->next) {
+        f = pr_FindSymbolInLib(lm, name);
+        if (f != NULL) {
+            *lib = lm;
+            lm->refCount++;
+            PR_LOG(_pr_linker_lm, PR_LOG_MIN,
+                       ("%s incr => %d (for %s)",
+                    lm->name, lm->refCount, name));
+            break;
+        }
+    }
+#if defined(NEED_LEADING_UNDERSCORE)
+    PR_smprintf_free(name);
+#endif
+
+    PR_ExitMonitor(pr_linker_lock);
+    return f;
+}
+
+PR_IMPLEMENT(PRFuncPtr) 
+PR_FindFunctionSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)
+{
+    return ((PRFuncPtr) PR_FindSymbolAndLibrary(raw_name, lib));
+}
+
+/*
+** Add a static library to the list of loaded libraries. If LoadLibrary
+** is called with the name then we will pretend it was already loaded
+*/
+PR_IMPLEMENT(PRLibrary*) 
+PR_LoadStaticLibrary(const char *name, const PRStaticLinkTable *slt)
+{
+    PRLibrary *lm=NULL;
+    PRLibrary* result = NULL;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* See if library is already loaded */
+    PR_EnterMonitor(pr_linker_lock);
+
+    /* If the lbrary is already loaded, then add the static table information... */
+    result = pr_UnlockedFindLibrary(name);
+    if (result != NULL) {
+        PR_ASSERT( (result->staticTable == NULL) || (result->staticTable == slt) );
+        result->staticTable = slt;
+        goto unlock;
+    }
+
+    /* Add library to list...Mark it static */
+    lm = PR_NEWZAP(PRLibrary);
+    if (lm == NULL) goto unlock;
+
+    lm->name = strdup(name);
+    lm->refCount    = 1;
+    lm->dlh         = pr_exe_loadmap ? pr_exe_loadmap->dlh : 0;
+    lm->staticTable = slt;
+    lm->next        = pr_loadmap;
+    pr_loadmap      = lm;
+
+    result = lm;    /* success */
+    PR_ASSERT(lm->refCount == 1);
+    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (static lib)", lm->name));
+  unlock:
+    PR_ExitMonitor(pr_linker_lock);
+    return result;
+}
+
+PR_IMPLEMENT(char *)
+PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr)
+{
+#if defined(USE_DLFCN) && !defined(ANDROID) && (defined(SOLARIS) || defined(FREEBSD) \
+        || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+        || defined(DARWIN))
+    Dl_info dli;
+    char *result;
+
+    if (dladdr((void *)addr, &dli) == 0) {
+        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    result = PR_Malloc(strlen(dli.dli_fname)+1);
+    if (result != NULL) {
+        strcpy(result, dli.dli_fname);
+    }
+    return result;
+#elif defined(USE_MACH_DYLD)
+    char *result;
+    const char *image_name;
+    int i, count = _dyld_image_count();
+
+    for (i = 0; i < count; i++) {
+        image_name = _dyld_get_image_name(i);
+        if (strstr(image_name, name) != NULL) {
+            result = PR_Malloc(strlen(image_name)+1);
+            if (result != NULL) {
+                strcpy(result, image_name);
+            }
+            return result;
+        }
+    }
+    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+    return NULL;
+#elif defined(AIX)
+    char *result;
+#define LD_INFO_INCREMENT 64
+    struct ld_info *info;
+    unsigned int info_length = LD_INFO_INCREMENT * sizeof(struct ld_info);
+    struct ld_info *infop;
+    int loadflags = L_GETINFO | L_IGNOREUNLOAD;
+
+    for (;;) {
+        info = PR_Malloc(info_length);
+        if (info == NULL) {
+            return NULL;
+        }
+        /* If buffer is too small, loadquery fails with ENOMEM. */
+        if (loadquery(loadflags, info, info_length) != -1) {
+            break;
+        }
+        /*
+         * Calling loadquery when compiled for 64-bit with the
+         * L_IGNOREUNLOAD flag can cause an invalid argument error
+         * on AIX 5.1. Detect this error the first time that
+         * loadquery is called, and try calling it again without
+         * this flag set.
+         */
+        if (errno == EINVAL && (loadflags & L_IGNOREUNLOAD)) {
+            loadflags &= ~L_IGNOREUNLOAD;
+            if (loadquery(loadflags, info, info_length) != -1) {
+                break;
+            }
+        }
+        PR_Free(info);
+        if (errno != ENOMEM) {
+            /* should not happen */
+            _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+            return NULL;
+        }
+        /* retry with a larger buffer */
+        info_length += LD_INFO_INCREMENT * sizeof(struct ld_info);
+    }
+
+    for (infop = info;
+         ;
+         infop = (struct ld_info *)((char *)infop + infop->ldinfo_next)) {
+        unsigned long start = (unsigned long)infop->ldinfo_dataorg;
+        unsigned long end = start + infop->ldinfo_datasize;
+        if (start <= (unsigned long)addr && end > (unsigned long)addr) {
+            result = PR_Malloc(strlen(infop->ldinfo_filename)+1);
+            if (result != NULL) {
+                strcpy(result, infop->ldinfo_filename);
+            }
+            break;
+        }
+        if (!infop->ldinfo_next) {
+            PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+            result = NULL;
+            break;
+        }
+    }
+    PR_Free(info);
+    return result;
+#elif defined(OSF1)
+    /* Contributed by Steve Streeter of HP */
+    ldr_process_t process, ldr_my_process();
+    ldr_module_t mod_id;
+    ldr_module_info_t info;
+    ldr_region_t regno;
+    ldr_region_info_t reginfo;
+    size_t retsize;
+    int rv;
+    char *result;
+
+    /* Get process for which dynamic modules will be listed */
+
+    process = ldr_my_process();
+
+    /* Attach to process */
+
+    rv = ldr_xattach(process);
+    if (rv) {
+        /* should not happen */
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        return NULL;
+    }
+
+    /* Print information for list of modules */
+
+    mod_id = LDR_NULL_MODULE;
+
+    for (;;) {
+
+        /* Get information for the next module in the module list. */
+
+        ldr_next_module(process, &mod_id);
+        if (ldr_inq_module(process, mod_id, &info, sizeof(info),
+                           &retsize) != 0) {
+            /* No more modules */
+            break;
+        }
+        if (retsize < sizeof(info)) {
+            continue;
+        }
+
+        /*
+         * Get information for each region in the module and check if any
+         * contain the address of this function.
+         */
+
+        for (regno = 0; ; regno++) {
+            if (ldr_inq_region(process, mod_id, regno, &reginfo,
+                               sizeof(reginfo), &retsize) != 0) {
+                /* No more regions */
+                break;
+            }
+            if (((unsigned long)reginfo.lri_mapaddr <=
+                (unsigned long)addr) &&
+                (((unsigned long)reginfo.lri_mapaddr + reginfo.lri_size) >
+                (unsigned long)addr)) {
+                /* Found it. */
+                result = PR_Malloc(strlen(info.lmi_name)+1);
+                if (result != NULL) {
+                    strcpy(result, info.lmi_name);
+                }
+                return result;
+            }
+        }
+    }
+    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+    return NULL;
+#elif defined(HPUX) && defined(USE_HPSHL)
+    int index;
+    struct shl_descriptor desc;
+    char *result;
+
+    for (index = 0; shl_get_r(index, &desc) == 0; index++) {
+        if (strstr(desc.filename, name) != NULL) {
+            result = PR_Malloc(strlen(desc.filename)+1);
+            if (result != NULL) {
+                strcpy(result, desc.filename);
+            }
+            return result;
+        }
+    }
+    /*
+     * Since the index value of a library is decremented if
+     * a library preceding it in the shared library search
+     * list was unloaded, it is possible that we missed some
+     * libraries as we went up the list.  So we should go
+     * down the list to be sure that we not miss anything.
+     */
+    for (index--; index >= 0; index--) {
+        if ((shl_get_r(index, &desc) == 0)
+                && (strstr(desc.filename, name) != NULL)) {
+            result = PR_Malloc(strlen(desc.filename)+1);
+            if (result != NULL) {
+                strcpy(result, desc.filename);
+            }
+            return result;
+        }
+    }
+    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+    return NULL;
+#elif defined(HPUX) && defined(USE_DLFCN)
+    struct load_module_desc desc;
+    char *result;
+    const char *module_name;
+
+    if (dlmodinfo((unsigned long)addr, &desc, sizeof desc, NULL, 0, 0) == 0) {
+        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    module_name = dlgetname(&desc, sizeof desc, NULL, 0, 0);
+    if (module_name == NULL) {
+        /* should not happen */
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    result = PR_Malloc(strlen(module_name)+1);
+    if (result != NULL) {
+        strcpy(result, module_name);
+    }
+    return result;
+#elif defined(WIN32)
+    PRUnichar wname[MAX_PATH];
+    HMODULE handle = NULL;
+    PRUnichar module_name[MAX_PATH];
+    int len;
+    char *result;
+
+    if (MultiByteToWideChar(CP_ACP, 0, name, -1, wname, MAX_PATH)) {
+        handle = GetModuleHandleW(wname);
+    }
+    if (handle == NULL) {
+        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    if (GetModuleFileNameW(handle, module_name, MAX_PATH) == 0) {
+        /* should not happen */
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        return NULL;
+    }
+    len = WideCharToMultiByte(CP_ACP, 0, module_name, -1,
+                              NULL, 0, NULL, NULL);
+    if (len == 0) {
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        return NULL;
+    }
+    result = PR_Malloc(len * sizeof(PRUnichar));
+    if (result != NULL) {
+        WideCharToMultiByte(CP_ACP, 0, module_name, -1,
+                            result, len, NULL, NULL);
+    }
+    return result;
+#elif defined(XP_OS2)
+    HMODULE module = NULL;
+    char module_name[_MAX_PATH];
+    char *result;
+    APIRET ulrc = DosQueryModFromEIP(&module, NULL, 0, NULL, NULL, (ULONG) addr);
+    if ((NO_ERROR != ulrc) || (NULL == module) ) {
+        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    ulrc = DosQueryModuleName(module, sizeof module_name, module_name);
+    if (NO_ERROR != ulrc) {
+        /* should not happen */
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        return NULL;
+    }
+    result = PR_Malloc(strlen(module_name)+1);
+    if (result != NULL) {
+        strcpy(result, module_name);
+    }
+    return result;
+#else
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+#endif
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/Makefile.in
new file mode 100644
index 0000000..981ec46
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/Makefile.in
@@ -0,0 +1,67 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+# Disable optimization of the nspr on SunOS4.1.3
+ifeq ($(OS_ARCH),SunOS)
+ifeq ($(OS_RELEASE),4.1.3_U1)
+OPTIMIZER =
+endif
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES += -D_NSPR_BUILD_
+
+CSRCS = prmalloc.c prmem.c
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/prmalloc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/prmalloc.c
new file mode 100644
index 0000000..10e9cf7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/prmalloc.c
@@ -0,0 +1,1174 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+/*
+** We override malloc etc. on any platform which has preemption +
+** nspr20 user level threads.  When we're debugging, we can make our
+** version of malloc fail occasionally.
+*/
+#ifdef _PR_OVERRIDE_MALLOC
+
+/*
+** Thread safe version of malloc, calloc, realloc, free
+*/
+#include <stdarg.h>
+
+#ifdef DEBUG
+#define SANITY
+#define EXTRA_SANITY
+#else
+#undef SANITY
+#undef EXTRA_SANITY
+#endif
+
+/* Forward decls */
+void *_PR_UnlockedMalloc(size_t size);
+void _PR_UnlockedFree(void *ptr);
+void *_PR_UnlockedRealloc(void *ptr, size_t size);
+void *_PR_UnlockedCalloc(size_t n, size_t elsize);
+
+/************************************************************************/
+
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ */
+
+/*
+ * Defining SANITY will enable some checks which will tell you if the users
+ * program did botch something
+ */
+
+/*
+ * Defining EXTRA_SANITY will enable some checks which are mostly related
+ * to internal conditions in malloc.c
+ */
+
+/*
+ * Very verbose progress on stdout...
+ */
+#if 0
+#  define TRACE(foo)    printf  foo
+static int malloc_event;
+#else
+#  define TRACE(foo)	
+#endif
+
+/* XXX Pick a number, any number */
+#   define malloc_pagesize		4096UL
+#   define malloc_pageshift		12UL
+
+#ifdef XP_UNIX
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+
+/*
+ * This structure describes a page's worth of chunks.
+ */
+
+struct pginfo {
+    struct pginfo	*next;	/* next on the free list */
+    char		*page;	/* Pointer to the page */
+    u_short		size;	/* size of this page's chunks */
+    u_short		shift;	/* How far to shift for this size chunks */
+    u_short		free;	/* How many free chunks */
+    u_short		total;	/* How many chunk */
+    u_long		bits[1]; /* Which chunks are free */
+};
+
+struct pgfree {
+    struct pgfree	*next;	/* next run of free pages */
+    struct pgfree	*prev;	/* prev run of free pages */
+    char		*page;	/* pointer to free pages */
+    char		*end;	/* pointer to end of free pages */
+    u_long		size;	/* number of bytes free */
+};
+
+/*
+ * How many bits per u_long in the bitmap.
+ * Change only if not 8 bits/byte
+ */
+#define	MALLOC_BITS	(8*sizeof(u_long))
+
+/*
+ * Magic values to put in the page_directory
+ */
+#define MALLOC_NOT_MINE	((struct pginfo*) 0)
+#define MALLOC_FREE 	((struct pginfo*) 1)
+#define MALLOC_FIRST	((struct pginfo*) 2)
+#define MALLOC_FOLLOW	((struct pginfo*) 3)
+#define MALLOC_MAGIC	((struct pginfo*) 4)
+
+/*
+ * Set to one when malloc_init has been called
+ */
+static	unsigned	initialized;
+
+/*
+ * The size of a page.
+ * Must be a integral multiplum of the granularity of mmap(2).
+ * Your toes will curl if it isn't a power of two
+ */
+#define malloc_pagemask	((malloc_pagesize)-1)
+
+/*
+ * The size of the largest chunk.
+ * Half a page.
+ */
+#define malloc_maxsize	((malloc_pagesize)>>1)
+
+/*
+ * malloc_pagesize == 1 << malloc_pageshift
+ */
+#ifndef malloc_pageshift
+static	unsigned	malloc_pageshift;
+#endif /* malloc_pageshift */
+
+/*
+ * The smallest allocation we bother about.
+ * Must be power of two
+ */
+#ifndef malloc_minsize
+static	unsigned  malloc_minsize;
+#endif /* malloc_minsize */
+
+/*
+ * The largest chunk we care about.
+ * Must be smaller than pagesize
+ * Must be power of two
+ */
+#ifndef malloc_maxsize
+static	unsigned  malloc_maxsize;
+#endif /* malloc_maxsize */
+
+#ifndef malloc_cache
+static	unsigned  malloc_cache;
+#endif /* malloc_cache */
+
+/*
+ * The offset from pagenumber to index into the page directory
+ */
+static	u_long  malloc_origo;
+
+/*
+ * The last index in the page directory we care about
+ */
+static	u_long  last_index;
+
+/*
+ * Pointer to page directory.
+ * Allocated "as if with" malloc
+ */
+static	struct	pginfo **page_dir;
+
+/*
+ * How many slots in the page directory
+ */
+static	unsigned	malloc_ninfo;
+
+/*
+ * Free pages line up here 
+ */
+static struct pgfree	free_list;
+
+/*
+ * Abort() if we fail to get VM ?
+ */
+static int malloc_abort;
+
+#ifdef SANITY
+/*
+ * Are we trying to die ?
+ */
+static int suicide;
+#endif
+
+/*
+ * dump statistics
+ */
+static int malloc_stats;
+
+/*
+ * always realloc ?
+ */
+static int malloc_realloc;
+
+/*
+ * my last break.
+ */
+static void *malloc_brk;
+
+/*
+ * one location cache for free-list holders
+ */
+static struct pgfree *px;
+
+static int set_pgdir(void *ptr, struct  pginfo *info);
+static int extend_page_directory(u_long index);
+
+#ifdef SANITY
+void
+malloc_dump(FILE *fd)
+{
+    struct pginfo **pd;
+    struct pgfree *pf;
+    int j;
+
+    pd = page_dir;
+
+    /* print out all the pages */
+    for(j=0;j<=last_index;j++) {
+	fprintf(fd,"%08lx %5d ",(j+malloc_origo) << malloc_pageshift,j);
+	if (pd[j] == MALLOC_NOT_MINE) {
+	    for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
+		;
+	    j--;
+	    fprintf(fd,".. %5d not mine\n",	j);
+	} else if (pd[j] == MALLOC_FREE) {
+	    for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
+		;
+	    j--;
+	    fprintf(fd,".. %5d free\n", j);
+	} else if (pd[j] == MALLOC_FIRST) {
+	    for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
+		;
+	    j--;
+	    fprintf(fd,".. %5d in use\n", j);
+	} else if (pd[j] < MALLOC_MAGIC) {
+	    fprintf(fd,"(%p)\n", pd[j]);
+	} else {
+	    fprintf(fd,"%p %d (of %d) x %d @ %p --> %p\n",
+		pd[j],pd[j]->free, pd[j]->total, 
+		pd[j]->size, pd[j]->page, pd[j]->next);
+	}
+    }
+
+    for(pf=free_list.next; pf; pf=pf->next) {
+	fprintf(fd,"Free: @%p [%p...%p[ %ld ->%p <-%p\n",
+		pf,pf->page,pf->end,pf->size,pf->prev,pf->next);
+	if (pf == pf->next) {
+		fprintf(fd,"Free_list loops.\n");
+		break;
+	}
+    }
+
+    /* print out various info */
+    fprintf(fd,"Minsize\t%d\n",malloc_minsize);
+    fprintf(fd,"Maxsize\t%ld\n",malloc_maxsize);
+    fprintf(fd,"Pagesize\t%ld\n",malloc_pagesize);
+    fprintf(fd,"Pageshift\t%ld\n",malloc_pageshift);
+    fprintf(fd,"FirstPage\t%ld\n",malloc_origo);
+    fprintf(fd,"LastPage\t%ld %lx\n",last_index+malloc_pageshift,
+	(last_index + malloc_pageshift) << malloc_pageshift);
+    fprintf(fd,"Break\t%ld\n",(u_long)sbrk(0) >> malloc_pageshift);
+}
+
+static void wrterror(char *fmt, ...)
+{
+    char *q = "malloc() error: ";
+    char buf[100];
+    va_list ap;
+
+    suicide = 1;
+
+    va_start(ap, fmt);
+    PR_vsnprintf(buf, sizeof(buf), fmt, ap);
+    va_end(ap);
+    fputs(q, stderr);
+    fputs(buf, stderr);
+
+    malloc_dump(stderr);
+    PR_Abort();
+}
+
+static void wrtwarning(char *fmt, ...)
+{
+    char *q = "malloc() warning: ";
+    char buf[100];
+    va_list ap;
+
+    va_start(ap, fmt);
+    PR_vsnprintf(buf, sizeof(buf), fmt, ap);
+    va_end(ap);
+    fputs(q, stderr);
+    fputs(buf, stderr);
+}
+#endif /* SANITY */
+
+
+/*
+ * Allocate a number of pages from the OS
+ */
+static caddr_t
+map_pages(int pages, int update)
+{
+    caddr_t result,tail;
+
+    result = ((caddr_t)sbrk(0)) + malloc_pagemask - 1;
+    result = (caddr_t) ((u_long)result & ~malloc_pagemask);
+    tail = result + (pages << malloc_pageshift);
+    if (!brk(tail)) {
+	last_index = ((u_long)tail >> malloc_pageshift) - malloc_origo -1;
+	malloc_brk = tail;
+	TRACE(("%6d S %p .. %p\n",malloc_event++, result, tail));
+	if (!update || last_index < malloc_ninfo ||
+	  extend_page_directory(last_index))
+	    return result;
+    }
+    TRACE(("%6d s %d %p %d\n",malloc_event++,pages,sbrk(0),errno));
+#ifdef EXTRA_SANITY
+    wrterror("map_pages fails\n");
+#endif
+    return 0;
+}
+
+#define set_bit(_pi,_bit) \
+    (_pi)->bits[(_bit)/MALLOC_BITS] |= 1L<<((_bit)%MALLOC_BITS)
+
+#define clr_bit(_pi,_bit) \
+    (_pi)->bits[(_bit)/MALLOC_BITS] &= ~(1L<<((_bit)%MALLOC_BITS));
+
+#define tst_bit(_pi,_bit) \
+    ((_pi)->bits[(_bit)/MALLOC_BITS] & (1L<<((_bit)%MALLOC_BITS)))
+
+/*
+ * Extend page directory
+ */
+static int
+extend_page_directory(u_long index)
+{
+    struct  pginfo **young, **old;
+    int i;
+
+    TRACE(("%6d E %lu\n",malloc_event++,index));
+    
+    /* Make it this many pages */
+    i = index * sizeof *page_dir;
+    i /= malloc_pagesize;
+    i += 2;
+
+    /* Get new pages, if you used this much mem you don't care :-) */
+    young = (struct pginfo**) map_pages(i,0);
+    if (!young)
+	return 0;
+
+    /* Copy the old stuff */
+    memset(young, 0, i * malloc_pagesize);
+    memcpy(young, page_dir,
+	    malloc_ninfo * sizeof *page_dir);
+
+    /* register the new size */
+    malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
+
+    /* swap the pointers */
+    old = page_dir;
+    page_dir = young;
+
+    /* Mark the pages */
+    index = ((u_long)young >> malloc_pageshift) - malloc_origo;
+    page_dir[index] = MALLOC_FIRST;
+    while (--i) {
+	page_dir[++index] = MALLOC_FOLLOW;
+    }
+
+    /* Now free the old stuff */
+    _PR_UnlockedFree(old);
+    return 1;
+}
+
+/*
+ * Set entry in page directory.
+ * Extend page directory if need be.
+ */
+static int
+set_pgdir(void *ptr, struct  pginfo *info)
+{
+    u_long index = ((u_long)ptr >> malloc_pageshift) - malloc_origo;
+
+    if (index >= malloc_ninfo && !extend_page_directory(index))
+	return 0;
+    page_dir[index] = info;
+    return 1;
+}
+
+/*
+ * Initialize the world
+ */
+static void
+malloc_init (void)
+{
+    int i;
+    char *p;
+
+    TRACE(("%6d I\n",malloc_event++));
+#ifdef DEBUG
+    for (p=getenv("MALLOC_OPTIONS"); p && *p; p++) {
+	switch (*p) {
+	    case 'a': malloc_abort = 0; break;
+	    case 'A': malloc_abort = 1; break;
+	    case 'd': malloc_stats = 0; break;
+	    case 'D': malloc_stats = 1; break;
+	    case 'r': malloc_realloc = 0; break;
+	    case 'R': malloc_realloc = 1; break;
+	    default:
+		wrtwarning("Unknown chars in MALLOC_OPTIONS\n");
+		break;
+	}
+    }
+#endif
+
+#ifndef malloc_pagesize
+    /* determine our pagesize */
+    malloc_pagesize = getpagesize();
+#endif /* malloc_pagesize */
+
+#ifndef malloc_pageshift
+    /* determine how much we shift by to get there */
+    for (i = malloc_pagesize; i > 1; i >>= 1)
+	malloc_pageshift++;
+#endif /* malloc_pageshift */
+
+#ifndef malloc_cache
+    malloc_cache = 50 << malloc_pageshift;	
+#endif /* malloc_cache */
+
+#ifndef malloc_minsize
+    /*
+     * find the smallest size allocation we will bother about.
+     * this is determined as the smallest allocation that can hold
+     * it's own pginfo;
+     */
+    i = 2;
+    for(;;) {
+	int j;
+
+	/* Figure out the size of the bits */
+	j = malloc_pagesize/i;
+	j /= 8;
+	if (j < sizeof(u_long))
+		j = sizeof (u_long);
+	if (sizeof(struct pginfo) + j - sizeof (u_long) <= i)
+		break;
+	i += i;
+    }
+    malloc_minsize = i;
+#endif /* malloc_minsize */
+
+
+    /* Allocate one page for the page directory */
+    page_dir = (struct pginfo **) map_pages(1,0);
+#ifdef SANITY
+    if (!page_dir)
+	wrterror("fatal: my first mmap failed.  (check limits ?)\n");
+#endif
+
+    /*
+     * We need a maximum of malloc_pageshift buckets, steal these from the
+     * front of the page_directory;
+     */
+    malloc_origo = (u_long) page_dir >> malloc_pageshift;
+    malloc_origo -= malloc_pageshift;
+
+    /* Clear it */
+    memset(page_dir,0,malloc_pagesize);
+
+    /* Find out how much it tells us */
+    malloc_ninfo = malloc_pagesize / sizeof *page_dir;
+
+    /* Plug the page directory into itself */
+    i = set_pgdir(page_dir,MALLOC_FIRST);
+#ifdef SANITY
+    if (!i)
+	wrterror("fatal: couldn't set myself in the page directory\n");
+#endif
+
+    /* Been here, done that */
+    initialized++;
+}
+
+/*
+ * Allocate a number of complete pages
+ */
+static void *malloc_pages(size_t size)
+{
+    void *p,*delay_free = 0;
+    int i;
+    struct pgfree *pf;
+    u_long index;
+
+    /* How many pages ? */
+    size += (malloc_pagesize-1);
+    size &= ~malloc_pagemask;
+
+    p = 0;
+    /* Look for free pages before asking for more */
+    for(pf = free_list.next; pf; pf = pf->next) {
+#ifdef EXTRA_SANITY
+	if (pf->page == pf->end)
+	    wrterror("zero entry on free_list\n");
+	if (pf->page > pf->end) {
+	    TRACE(("%6d !s %p %p %p <%d>\n",malloc_event++,
+		pf,pf->page,pf->end,__LINE__));
+	    wrterror("sick entry on free_list\n");
+	}
+	if ((void*)pf->page >= (void*)sbrk(0))
+	    wrterror("entry on free_list past brk\n");
+	if (page_dir[((u_long)pf->page >> malloc_pageshift) - malloc_origo] 
+	  != MALLOC_FREE) {
+	    TRACE(("%6d !f %p %p %p <%d>\n",malloc_event++,
+		pf,pf->page,pf->end,__LINE__));
+	    wrterror("non-free first page on free-list\n");
+	}
+	if (page_dir[((u_long)pf->end >> malloc_pageshift) - 1 - malloc_origo] 
+	  != MALLOC_FREE)
+	    wrterror("non-free last page on free-list\n");
+#endif /* EXTRA_SANITY */
+	if (pf->size < size) 
+	    continue;
+	else if (pf->size == size) {
+	    p = pf->page;
+	    if (pf->next)
+		    pf->next->prev = pf->prev;
+	    pf->prev->next = pf->next;
+	    delay_free = pf;
+	    break;
+	} else {
+	    p = pf->page;
+	    pf->page += size;
+	    pf->size -= size;
+	    break;
+        }
+    }
+#ifdef EXTRA_SANITY
+    if (p && page_dir[((u_long)p >> malloc_pageshift) - malloc_origo] 
+      != MALLOC_FREE) {
+	wrterror("allocated non-free page on free-list\n");
+    }
+#endif /* EXTRA_SANITY */
+
+    size >>= malloc_pageshift;
+
+    /* Map new pages */
+    if (!p)
+	p = map_pages(size,1);
+
+    if (p) {
+	/* Mark the pages in the directory */
+	index = ((u_long)p >> malloc_pageshift) - malloc_origo;
+	page_dir[index] = MALLOC_FIRST;
+	for (i=1;i<size;i++)
+	    page_dir[index+i] = MALLOC_FOLLOW;
+    }
+    if (delay_free) {
+	if (!px) 
+	    px = (struct pgfree*)delay_free;
+	else
+	    _PR_UnlockedFree(delay_free);
+    }
+    return p;
+}
+
+/*
+ * Allocate a page of fragments
+ */
+
+static int
+malloc_make_chunks(int bits)
+{
+    struct  pginfo *bp;
+    void *pp;
+    int i,k,l;
+
+    /* Allocate a new bucket */
+    pp = malloc_pages(malloc_pagesize);
+    if (!pp)
+	return 0;
+    l = sizeof *bp - sizeof(u_long);
+    l += sizeof(u_long) *
+	(((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
+    if ((1<<(bits)) <= l+l) {
+	bp = (struct  pginfo *)pp;
+    } else {
+	bp = (struct  pginfo *)_PR_UnlockedMalloc(l);
+    }
+    if (!bp)
+	return 0;
+    bp->size = (1<<bits);
+    bp->shift = bits;
+    bp->total = bp->free = malloc_pagesize >> bits;
+    bp->next = page_dir[bits];
+    bp->page = (char*)pp;
+    i = set_pgdir(pp,bp);
+    if (!i)
+	return 0;
+
+    /* We can safely assume that there is nobody in this chain */
+    page_dir[bits] = bp;
+
+    /* set all valid bits in the bits */
+    k = bp->total;
+    i = 0;
+/*
+    for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
+	bp->bits[i / MALLOC_BITS] = ~0;
+*/
+    for(; i < k; i++)
+	set_bit(bp,i);
+
+    if (bp != pp)
+	return 1;
+
+    /* We may have used the first ones already */
+    for(i=0;l > 0;i++) {
+	clr_bit(bp,i);
+	bp->free--;
+	bp->total--;
+	l -= (1 << bits);
+    }
+    return 1;
+}
+
+/*
+ * Allocate a fragment
+ */
+static void *malloc_bytes(size_t size)
+{
+    size_t s;
+    int j;
+    struct  pginfo *bp;
+    int k;
+    u_long *lp, bf;
+
+    /* Don't bother with anything less than this */
+    if (size < malloc_minsize) {
+	size = malloc_minsize;
+    }
+
+    /* Find the right bucket */
+    j = 1;
+    s = size - 1;
+    while (s >>= 1) {
+        j++;
+    }
+
+    /* If it's empty, make a page more of that size chunks */
+    if (!page_dir[j] && !malloc_make_chunks(j))
+	return 0;
+
+    /* Find first word of bitmap which isn't empty */
+    bp = page_dir[j];
+    for (lp = bp->bits; !*lp; lp++)
+	;
+
+    /* Find that bit */
+    bf = *lp;
+    k = 0;
+    while ((bf & 1) == 0) {
+	bf >>= 1;
+	k++;
+    }
+
+    *lp ^= 1L<<k;                       /* clear it */
+    bp->free--;
+    if (!bp->free) {
+	page_dir[j] = bp->next;
+	bp->next = 0;
+    }
+    k += (lp - bp->bits)*MALLOC_BITS;
+    return bp->page + (k << bp->shift);
+}
+
+void *_PR_UnlockedMalloc(size_t size)
+{
+    void *result;
+
+    /* Round up to a multiple of 8 bytes */
+    if (size & 7) {
+	size = size + 8 - (size & 7);
+    }
+
+    if (!initialized)
+	malloc_init();
+
+#ifdef SANITY
+    if (suicide)
+	PR_Abort();
+#endif
+
+    if (size <= malloc_maxsize)
+	result =  malloc_bytes(size);
+    else
+	result =  malloc_pages(size);
+#ifdef SANITY
+    if (malloc_abort && !result)
+	wrterror("malloc() returns NULL\n");
+#endif
+    TRACE(("%6d M %p %d\n",malloc_event++,result,size));
+
+    return result;
+}
+
+void *_PR_UnlockedMemalign(size_t alignment, size_t size)
+{
+    void *result;
+
+    /*
+     * alignment has to be a power of 2
+     */
+
+    if ((size <= alignment) && (alignment <= malloc_maxsize))
+		size = alignment;	
+    else
+           	size += alignment - 1;	
+
+    /* Round up to a multiple of 8 bytes */
+    if (size & 7) {
+	size = size + 8 - (size & 7);
+    }
+
+    if (!initialized)
+	malloc_init();
+
+#ifdef SANITY
+    if (suicide)
+	abort();
+#endif
+
+    if (size <= malloc_maxsize)
+	result =  malloc_bytes(size);
+    else
+	result =  malloc_pages(size);
+#ifdef SANITY
+    if (malloc_abort && !result)
+	wrterror("malloc() returns NULL\n");
+#endif
+    TRACE(("%6d A %p %d\n",malloc_event++,result,size));
+
+    if ((u_long)result & (alignment - 1))
+    	return ((void *)(((u_long)result + alignment)  & ~(alignment - 1)));
+    else
+    	return result;
+}
+
+void *_PR_UnlockedCalloc(size_t n, size_t nelem)
+{
+    void *p;
+
+    /* Compute total size and then round up to a double word amount */
+    n *= nelem;
+    if (n & 7) {
+	n = n + 8 - (n & 7);
+    }
+
+    /* Get the memory */
+    p = _PR_UnlockedMalloc(n);
+    if (p) {
+	/* Zero it */
+	memset(p, 0, n);
+    }
+    return p;
+}
+
+/*
+ * Change an allocation's size
+ */
+void *_PR_UnlockedRealloc(void *ptr, size_t size)
+{
+    void *p;
+    u_long osize,page,index,tmp_index;
+    struct pginfo **mp;
+
+    if (!initialized)
+	malloc_init();
+
+#ifdef SANITY
+    if (suicide)
+	PR_Abort();
+#endif
+
+    /* used as free() */
+    TRACE(("%6d R %p %d\n",malloc_event++, ptr, size));
+    if (ptr && !size) {
+	_PR_UnlockedFree(ptr);
+	return _PR_UnlockedMalloc (1);
+    }
+
+    /* used as malloc() */
+    if (!ptr) {
+	p = _PR_UnlockedMalloc(size);
+	return p;
+    }
+
+    /* Find the page directory entry for the page in question */
+    page = (u_long)ptr >> malloc_pageshift;
+    index = page - malloc_origo;
+
+    /*
+     * check if memory was allocated by memalign
+     */
+    tmp_index = index;
+    while (page_dir[tmp_index] == MALLOC_FOLLOW)
+	tmp_index--;
+    if (tmp_index != index) {
+	/*
+	 * memalign-allocated memory
+	 */
+	index = tmp_index;
+	page = index + malloc_origo;			
+	ptr = (void *) (page << malloc_pageshift);
+    }
+    TRACE(("%6d R2 %p %d\n",malloc_event++, ptr, size));
+
+    /* make sure it makes sense in some fashion */
+    if (index < malloc_pageshift || index > last_index) {
+#ifdef SANITY
+	wrtwarning("junk pointer passed to realloc()\n");
+#endif
+	return 0;
+    }
+
+    /* find the size of that allocation, and see if we need to relocate */
+    mp = &page_dir[index];
+    if (*mp == MALLOC_FIRST) {
+	osize = malloc_pagesize;
+	while (mp[1] == MALLOC_FOLLOW) {
+	    osize += malloc_pagesize;
+	    mp++;
+	}
+        if (!malloc_realloc && 
+		size < osize && 
+		size > malloc_maxsize &&
+	    size > (osize - malloc_pagesize)) {
+	    return ptr;
+	}
+    } else if (*mp >= MALLOC_MAGIC) {
+	osize = (*mp)->size;
+	if (!malloc_realloc &&
+		size < osize && 
+	    (size > (*mp)->size/2 || (*mp)->size == malloc_minsize)) {
+	    return ptr;
+	}
+    } else {
+#ifdef SANITY
+	wrterror("realloc() of wrong page.\n");
+#endif
+    }
+
+    /* try to reallocate */
+    p = _PR_UnlockedMalloc(size);
+
+    if (p) {
+	/* copy the lesser of the two sizes */
+	if (osize < size)
+	    memcpy(p,ptr,osize);
+	else
+	    memcpy(p,ptr,size);
+	_PR_UnlockedFree(ptr);
+    }
+#ifdef DEBUG
+    else if (malloc_abort)
+	wrterror("realloc() returns NULL\n");
+#endif
+
+    return p;
+}
+
+/*
+ * Free a sequence of pages
+ */
+
+static void
+free_pages(char *ptr, u_long page, int index, struct pginfo *info)
+{
+    int i;
+    struct pgfree *pf,*pt;
+    u_long l;
+    char *tail;
+
+    TRACE(("%6d FP %p %d\n",malloc_event++, ptr, page));
+    /* Is it free already ? */
+    if (info == MALLOC_FREE) {
+#ifdef SANITY
+	wrtwarning("freeing free page at %p.\n", ptr);
+#endif
+	return;
+    }
+
+#ifdef SANITY
+    /* Is it not the right place to begin ? */
+    if (info != MALLOC_FIRST)
+	wrterror("freeing wrong page.\n");
+
+    /* Is this really a pointer to a page ? */
+    if ((u_long)ptr & malloc_pagemask)
+	wrterror("freeing messed up page pointer.\n");
+#endif
+
+    /* Count how many pages it is anyway */
+    page_dir[index] = MALLOC_FREE;
+    for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
+	page_dir[index + i] = MALLOC_FREE;
+
+    l = i << malloc_pageshift;
+
+    tail = ptr+l;
+
+    /* add to free-list */
+    if (!px)
+	px = (struct pgfree*)_PR_UnlockedMalloc(sizeof *pt);
+    /* XXX check success */
+    px->page = ptr;
+    px->end =  tail;
+    px->size = l;
+    if (!free_list.next) {
+	px->next = free_list.next;
+	px->prev = &free_list;
+	free_list.next = px;
+	pf = px;
+	px = 0;
+    } else {
+	tail = ptr+l;
+	for(pf = free_list.next; pf->next && pf->end < ptr; pf = pf->next)
+	    ;
+	for(; pf; pf = pf->next) {
+	    if (pf->end == ptr ) {
+		/* append to entry */
+		pf->end += l;
+		pf->size += l;
+		if (pf->next && pf->end == pf->next->page ) {
+		    pt = pf->next;
+		    pf->end = pt->end;
+		    pf->size += pt->size;
+		    pf->next = pt->next;
+		    if (pf->next)
+			pf->next->prev = pf;
+		    _PR_UnlockedFree(pt);
+		}
+	    } else if (pf->page == tail) {
+		/* prepend to entry */
+		pf->size += l;
+		pf->page = ptr;
+	    } else if (pf->page > ptr) {
+		px->next = pf;
+		px->prev = pf->prev;
+		pf->prev = px;
+		px->prev->next = px;
+		pf = px;
+		px = 0;
+	    } else if (!pf->next) {
+		px->next = 0;
+		px->prev = pf;
+		pf->next = px;
+		pf = px;
+		px = 0;
+	    } else {
+		continue;
+	    }
+	    break;
+	}
+    }
+    if (!pf->next &&
+      pf->size > malloc_cache &&
+      pf->end == malloc_brk &&
+      malloc_brk == (void*)sbrk(0)) {
+	pf->end = pf->page + malloc_cache;
+	pf->size = malloc_cache;
+	TRACE(("%6d U %p %d\n",malloc_event++,pf->end,pf->end - pf->page));
+	brk(pf->end);
+	malloc_brk = pf->end;
+	/* Find the page directory entry for the page in question */
+	page = (u_long)pf->end >> malloc_pageshift;
+	index = page - malloc_origo;
+	/* Now update the directory */
+	for(i=index;i <= last_index;)
+	    page_dir[i++] = MALLOC_NOT_MINE;
+	last_index = index - 1;
+    }
+}
+
+/*
+ * Free a chunk, and possibly the page it's on, if the page becomes empty.
+ */
+
+static void
+free_bytes(void *ptr, u_long page, int index, struct pginfo *info)
+{
+    int i;
+    struct pginfo **mp;
+    void *vp;
+
+    /* Make sure that pointer is multiplum of chunk-size */
+#ifdef SANITY
+    if ((u_long)ptr & (info->size - 1))
+	wrterror("freeing messed up chunk pointer\n");
+#endif
+
+    /* Find the chunk number on the page */
+    i = ((u_long)ptr & malloc_pagemask) >> info->shift;
+
+    /* See if it's free already */
+    if (tst_bit(info,i)) {
+#ifdef SANITY
+	wrtwarning("freeing free chunk at %p\n", ptr);
+#endif
+	return;
+    }
+
+    /* Mark it free */
+    set_bit(info,i);
+    info->free++;
+
+    /* If the page was full before, we need to put it on the queue now */
+    if (info->free == 1) {
+	mp = page_dir + info->shift;
+	while (*mp && (*mp)->next && (*mp)->next->page < info->page)
+	    mp = &(*mp)->next;
+	info->next = *mp;
+	*mp = info;
+	return;
+    }
+
+    /* If this page isn't empty, don't do anything. */
+    if (info->free != info->total)
+	return;
+
+    /* We may want to keep at least one page of each size chunks around.  */
+    mp = page_dir + info->shift;
+    if (0 && (*mp == info) && !info->next)
+	return;
+
+    /* Find & remove this page in the queue */
+    while (*mp != info) {
+	mp = &((*mp)->next);
+#ifdef EXTRA_SANITY
+	if (!*mp) {
+		TRACE(("%6d !q %p\n",malloc_event++,info));
+		wrterror("Not on queue\n");
+	}
+#endif
+    }
+    *mp = info->next;
+
+    /* Free the page & the info structure if need be */
+    set_pgdir(info->page,MALLOC_FIRST);
+    if((void*)info->page == (void*)info) {
+	_PR_UnlockedFree(info->page);
+    } else {
+	vp = info->page;
+	_PR_UnlockedFree(info);
+	_PR_UnlockedFree(vp);
+    }
+}
+
+void _PR_UnlockedFree(void *ptr)
+{
+    u_long page;
+    struct pginfo *info;
+    int index, tmp_index;
+
+    TRACE(("%6d F %p\n",malloc_event++,ptr));
+    /* This is legal */
+    if (!ptr)
+	return;
+
+#ifdef SANITY
+    /* There wouldn't be anything to free */
+    if (!initialized) {
+	wrtwarning("free() called before malloc() ever got called\n");
+	return;
+    }
+#endif
+
+#ifdef SANITY
+    if (suicide)
+	PR_Abort();
+#endif
+
+    /* Find the page directory entry for the page in question */
+    page = (u_long)ptr >> malloc_pageshift;
+    index = page - malloc_origo;
+
+    /*
+     * check if memory was allocated by memalign
+     */
+    tmp_index = index;
+    while (page_dir[tmp_index] == MALLOC_FOLLOW)
+	tmp_index--;
+    if (tmp_index != index) {
+	/*
+	 * memalign-allocated memory
+	 */
+	index = tmp_index;
+	page = index + malloc_origo;			
+	ptr = (void *) (page << malloc_pageshift);
+    }
+    /* make sure it makes sense in some fashion */
+    if (index < malloc_pageshift) {
+#ifdef SANITY
+	wrtwarning("junk pointer %p (low) passed to free()\n", ptr);
+#endif
+	return;
+    }
+    if (index > last_index) {
+#ifdef SANITY
+	wrtwarning("junk pointer %p (high) passed to free()\n", ptr);
+#endif
+	return;
+    }
+
+    /* handle as page-allocation or chunk allocation */
+    info = page_dir[index];
+    if (info < MALLOC_MAGIC)
+        free_pages((char*)ptr, page, index, info);
+    else 
+	free_bytes(ptr,page,index,info);
+    return;
+}
+#endif /* _PR_OVERRIDE_MALLOC */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/prmem.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/prmem.c
new file mode 100644
index 0000000..24a924d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/malloc/prmem.c
@@ -0,0 +1,726 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Thread safe versions of malloc, free, realloc, calloc and cfree.
+*/
+
+#include "primpl.h"
+
+#ifdef _PR_ZONE_ALLOCATOR
+
+/*
+** The zone allocator code must use native mutexes and cannot
+** use PRLocks because PR_NewLock calls PR_Calloc, resulting
+** in cyclic dependency of initialization.
+*/
+
+#include <string.h>	
+
+union memBlkHdrUn;
+
+typedef struct MemoryZoneStr {
+    union memBlkHdrUn    *head;         /* free list */
+    pthread_mutex_t       lock;
+    size_t                blockSize;    /* size of blocks on this free list */
+    PRUint32              locked;       /* current state of lock */
+    PRUint32              contention;   /* counter: had to wait for lock */
+    PRUint32              hits;         /* allocated from free list */
+    PRUint32              misses;       /* had to call malloc */
+    PRUint32              elements;     /* on free list */
+} MemoryZone;
+
+typedef union memBlkHdrUn {
+    unsigned char filler[48];  /* fix the size of this beast */
+    struct memBlkHdrStr {
+        union memBlkHdrUn    *next;
+        MemoryZone           *zone;
+        size_t                blockSize;
+        size_t                requestedSize;
+        PRUint32              magic;
+    } s;
+} MemBlockHdr;
+
+#define MEM_ZONES     7
+#define THREAD_POOLS 11  /* prime number for modulus */
+#define ZONE_MAGIC  0x0BADC0DE
+
+static MemoryZone zones[MEM_ZONES][THREAD_POOLS];
+
+static PRBool use_zone_allocator = PR_FALSE;
+
+static void pr_ZoneFree(void *ptr);
+
+void
+_PR_DestroyZones(void)
+{   
+    int i, j;
+
+    if (!use_zone_allocator)
+        return;
+    
+    for (j = 0; j < THREAD_POOLS; j++) {
+        for (i = 0; i < MEM_ZONES; i++) {
+            MemoryZone *mz = &zones[i][j];
+            pthread_mutex_destroy(&mz->lock);
+            while (mz->head) {
+                MemBlockHdr *hdr = mz->head;
+                mz->head = hdr->s.next;  /* unlink it */
+                free(hdr);
+                mz->elements--;
+            }
+        }
+    } 
+    use_zone_allocator = PR_FALSE;
+} 
+
+/*
+** pr_FindSymbolInProg
+**
+** Find the specified data symbol in the program and return
+** its address.
+*/
+
+#ifdef HAVE_DLL
+
+#if defined(USE_DLFCN) && !defined(NO_DLOPEN_NULL)
+
+#include <dlfcn.h>
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+    void *h;
+    void *sym;
+
+    h = dlopen(0, RTLD_LAZY);
+    if (h == NULL)
+        return NULL;
+    sym = dlsym(h, name);
+    (void)dlclose(h);
+    return sym;
+}
+
+#elif defined(USE_HPSHL)
+
+#include <dl.h>
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+    shl_t h = NULL;
+    void *sym;
+
+    if (shl_findsym(&h, name, TYPE_DATA, &sym) == -1)
+        return NULL;
+    return sym;
+}
+
+#elif defined(USE_MACH_DYLD) || defined(NO_DLOPEN_NULL)
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+    /* FIXME: not implemented */
+    return NULL;
+}
+
+#else
+
+#error "The zone allocator is not supported on this platform"
+
+#endif
+
+#else /* !defined(HAVE_DLL) */
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+    /* can't be implemented */
+    return NULL;
+}
+
+#endif /* HAVE_DLL */
+
+void
+_PR_InitZones(void)
+{
+    int i, j;
+    char *envp;
+    PRBool *sym;
+
+    if ((sym = (PRBool *)pr_FindSymbolInProg("nspr_use_zone_allocator")) != NULL) {
+        use_zone_allocator = *sym;
+    } else if ((envp = getenv("NSPR_USE_ZONE_ALLOCATOR")) != NULL) {
+        use_zone_allocator = (atoi(envp) == 1);
+    }
+
+    if (!use_zone_allocator)
+        return;
+
+    for (j = 0; j < THREAD_POOLS; j++) { 
+        for (i = 0; i < MEM_ZONES; i++) {
+            MemoryZone *mz = &zones[i][j];
+            int rv = pthread_mutex_init(&mz->lock, NULL);
+            PR_ASSERT(0 == rv);
+            if (rv != 0) {
+                goto loser;
+            } 
+            mz->blockSize = 16 << ( 2 * i);
+        }
+    }
+    return;
+
+loser:
+    _PR_DestroyZones();
+    return;
+}
+
+PR_IMPLEMENT(void)
+PR_FPrintZoneStats(PRFileDesc *debug_out)
+{
+    int i, j;
+
+    for (j = 0; j < THREAD_POOLS; j++) {
+        for (i = 0; i < MEM_ZONES; i++) {
+            MemoryZone   *mz   = &zones[i][j];
+            MemoryZone    zone = *mz;
+            if (zone.elements || zone.misses || zone.hits) {
+                PR_fprintf(debug_out,
+"pool: %d, zone: %d, size: %d, free: %d, hit: %d, miss: %d, contend: %d\n",
+                    j, i, zone.blockSize, zone.elements,
+                    zone.hits, zone.misses, zone.contention);
+            }
+	}
+    }
+}
+
+static void *
+pr_ZoneMalloc(PRUint32 size)
+{
+    void         *rv;
+    unsigned int  zone;
+    size_t        blockSize;
+    MemBlockHdr  *mb, *mt;
+    MemoryZone   *mz;
+
+    /* Always allocate a non-zero amount of bytes */
+    if (size < 1) {
+        size = 1;
+    }
+    for (zone = 0, blockSize = 16; zone < MEM_ZONES; ++zone, blockSize <<= 2) {
+        if (size <= blockSize) {
+            break;
+        }
+    }
+    if (zone < MEM_ZONES) {
+        pthread_t me = pthread_self();
+        unsigned int pool = (PRUptrdiff)me % THREAD_POOLS;
+        PRUint32     wasLocked;
+        mz = &zones[zone][pool];
+        wasLocked = mz->locked;
+        pthread_mutex_lock(&mz->lock);
+        mz->locked = 1;
+        if (wasLocked)
+            mz->contention++;
+        if (mz->head) {
+            mb = mz->head;
+            PR_ASSERT(mb->s.magic == ZONE_MAGIC);
+            PR_ASSERT(mb->s.zone  == mz);
+            PR_ASSERT(mb->s.blockSize == blockSize);
+            PR_ASSERT(mz->blockSize == blockSize);
+
+            mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+            PR_ASSERT(mt->s.magic == ZONE_MAGIC);
+            PR_ASSERT(mt->s.zone  == mz);
+            PR_ASSERT(mt->s.blockSize == blockSize);
+
+            mz->hits++;
+            mz->elements--;
+            mz->head = mb->s.next;    /* take off free list */
+            mz->locked = 0;
+            pthread_mutex_unlock(&mz->lock);
+
+            mt->s.next          = mb->s.next          = NULL;
+            mt->s.requestedSize = mb->s.requestedSize = size;
+
+            rv = (void *)(mb + 1);
+            return rv;
+        }
+
+        mz->misses++;
+        mz->locked = 0;
+        pthread_mutex_unlock(&mz->lock);
+
+        mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb));
+        if (!mb) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return NULL;
+        }
+        mb->s.next          = NULL;
+        mb->s.zone          = mz;
+        mb->s.magic         = ZONE_MAGIC;
+        mb->s.blockSize     = blockSize;
+        mb->s.requestedSize = size;
+
+        mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+        memcpy(mt, mb, sizeof *mb);
+
+        rv = (void *)(mb + 1);
+        return rv;
+    }
+
+    /* size was too big.  Create a block with no zone */
+    blockSize = (size & 15) ? size + 16 - (size & 15) : size;
+    mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb));
+    if (!mb) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    mb->s.next          = NULL;
+    mb->s.zone          = NULL;
+    mb->s.magic         = ZONE_MAGIC;
+    mb->s.blockSize     = blockSize;
+    mb->s.requestedSize = size;
+
+    mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+    memcpy(mt, mb, sizeof *mb);
+
+    rv = (void *)(mb + 1);
+    return rv;
+}
+
+
+static void *
+pr_ZoneCalloc(PRUint32 nelem, PRUint32 elsize)
+{
+    PRUint32 size = nelem * elsize;
+    void *p = pr_ZoneMalloc(size);
+    if (p) {
+        memset(p, 0, size);
+    }
+    return p;
+}
+
+static void *
+pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
+{
+    void         *rv;
+    MemBlockHdr  *mb;
+    int           ours;
+    MemBlockHdr   phony;
+
+    if (!oldptr)
+        return pr_ZoneMalloc(bytes);
+    mb = (MemBlockHdr *)((char *)oldptr - (sizeof *mb));
+    if (mb->s.magic != ZONE_MAGIC) {
+        /* Maybe this just came from ordinary malloc */
+#ifdef DEBUG
+        fprintf(stderr,
+            "Warning: reallocing memory block %p from ordinary malloc\n",
+            oldptr);
+#endif
+        /*
+         * We are going to realloc oldptr.  If realloc succeeds, the
+         * original value of oldptr will point to freed memory.  So this
+         * function must not fail after a successfull realloc call.  We
+         * must perform any operation that may fail before the realloc
+         * call.
+         */
+        rv = pr_ZoneMalloc(bytes);  /* this may fail */
+        if (!rv) {
+            return rv;
+        }
+
+        /* We don't know how big it is.  But we can fix that. */
+        oldptr = realloc(oldptr, bytes);
+        /*
+         * If realloc returns NULL, this function loses the original
+         * value of oldptr.  This isn't a leak because the caller of
+         * this function still has the original value of oldptr.
+         */
+        if (!oldptr) {
+            if (bytes) {
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                pr_ZoneFree(rv);
+                return oldptr;
+            }
+        }
+        phony.s.requestedSize = bytes;
+        mb = &phony;
+        ours = 0;
+    } else {
+        size_t blockSize = mb->s.blockSize;
+        MemBlockHdr *mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+
+        PR_ASSERT(mt->s.magic == ZONE_MAGIC);
+        PR_ASSERT(mt->s.zone  == mb->s.zone);
+        PR_ASSERT(mt->s.blockSize == blockSize);
+	
+        if (bytes <= blockSize) {
+            /* The block is already big enough. */
+            mt->s.requestedSize = mb->s.requestedSize = bytes;
+            return oldptr;
+        }
+        ours = 1;
+        rv = pr_ZoneMalloc(bytes);
+        if (!rv) {
+            return rv;
+        }
+    }
+    
+    if (oldptr && mb->s.requestedSize)
+        memcpy(rv, oldptr, mb->s.requestedSize);
+    if (ours)
+        pr_ZoneFree(oldptr);
+    else if (oldptr)
+        free(oldptr);
+    return rv;
+}
+
+static void
+pr_ZoneFree(void *ptr)
+{
+    MemBlockHdr  *mb, *mt;
+    MemoryZone   *mz;
+    size_t        blockSize;
+    PRUint32      wasLocked;
+
+    if (!ptr)
+        return;
+
+    mb = (MemBlockHdr *)((char *)ptr - (sizeof *mb));
+
+    if (mb->s.magic != ZONE_MAGIC) {
+        /* maybe this came from ordinary malloc */
+#ifdef DEBUG
+        fprintf(stderr,
+            "Warning: freeing memory block %p from ordinary malloc\n", ptr);
+#endif
+        free(ptr);
+        return;
+    }
+
+    blockSize = mb->s.blockSize;
+    mz        = mb->s.zone;
+    mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+    PR_ASSERT(mt->s.magic == ZONE_MAGIC);
+    PR_ASSERT(mt->s.zone  == mz);
+    PR_ASSERT(mt->s.blockSize == blockSize);
+    if (!mz) {
+        PR_ASSERT(blockSize > 65536);
+        /* This block was not in any zone.  Just free it. */
+        free(mb);
+        return;
+    }
+    PR_ASSERT(mz->blockSize == blockSize);
+    wasLocked = mz->locked;
+    pthread_mutex_lock(&mz->lock);
+    mz->locked = 1;
+    if (wasLocked)
+        mz->contention++;
+    mt->s.next = mb->s.next = mz->head;        /* put on head of list */
+    mz->head = mb;
+    mz->elements++;
+    mz->locked = 0;
+    pthread_mutex_unlock(&mz->lock);
+}
+
+PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    return use_zone_allocator ? pr_ZoneMalloc(size) : malloc(size);
+}
+
+PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    return use_zone_allocator ?
+        pr_ZoneCalloc(nelem, elsize) : calloc(nelem, elsize);
+}
+
+PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    return use_zone_allocator ? pr_ZoneRealloc(ptr, size) : realloc(ptr, size);
+}
+
+PR_IMPLEMENT(void) PR_Free(void *ptr)
+{
+    if (use_zone_allocator)
+        pr_ZoneFree(ptr);
+    else
+        free(ptr);
+}
+
+#else /* !defined(_PR_ZONE_ALLOCATOR) */
+
+/*
+** The PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free functions simply
+** call their libc equivalents now.  This may seem redundant, but it
+** ensures that we are calling into the same runtime library.  On
+** Win32, it is possible to have multiple runtime libraries (e.g.,
+** objects compiled with /MD and /MDd) in the same process, and
+** they maintain separate heaps, which cannot be mixed.
+*/
+PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size)
+{
+#if defined (WIN16)
+    return PR_MD_malloc( (size_t) size);
+#else
+    return malloc(size);
+#endif
+}
+
+PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize)
+{
+#if defined (WIN16)
+    return PR_MD_calloc( (size_t)nelem, (size_t)elsize );
+    
+#else
+    return calloc(nelem, elsize);
+#endif
+}
+
+PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size)
+{
+#if defined (WIN16)
+    return PR_MD_realloc( ptr, (size_t) size);
+#else
+    return realloc(ptr, size);
+#endif
+}
+
+PR_IMPLEMENT(void) PR_Free(void *ptr)
+{
+#if defined (WIN16)
+    PR_MD_free( ptr );
+#else
+    free(ptr);
+#endif
+}
+
+#endif /* _PR_ZONE_ALLOCATOR */
+
+/*
+** Complexity alert!
+**
+** If malloc/calloc/free (etc.) were implemented to use pr lock's then
+** the entry points could block when called if some other thread had the
+** lock.
+**
+** Most of the time this isn't a problem. However, in the case that we
+** are using the thread safe malloc code after PR_Init but before
+** PR_AttachThread has been called (on a native thread that nspr has yet
+** to be told about) we could get royally screwed if the lock was busy
+** and we tried to context switch the thread away. In this scenario
+** 	PR_CURRENT_THREAD() == NULL
+**
+** To avoid this unfortunate case, we use the low level locking
+** facilities for malloc protection instead of the slightly higher level
+** locking. This makes malloc somewhat faster so maybe it's a good thing
+** anyway.
+*/
+#ifdef _PR_OVERRIDE_MALLOC
+
+/* Imports */
+extern void *_PR_UnlockedMalloc(size_t size);
+extern void *_PR_UnlockedMemalign(size_t alignment, size_t size);
+extern void _PR_UnlockedFree(void *ptr);
+extern void *_PR_UnlockedRealloc(void *ptr, size_t size);
+extern void *_PR_UnlockedCalloc(size_t n, size_t elsize);
+
+static PRBool _PR_malloc_initialised = PR_FALSE;
+
+#ifdef _PR_PTHREADS
+static pthread_mutex_t _PR_MD_malloc_crustylock;
+
+#define _PR_Lock_Malloc() {						\
+    				if(PR_TRUE == _PR_malloc_initialised) { \
+					PRStatus rv;			\
+					rv = pthread_mutex_lock(&_PR_MD_malloc_crustylock); \
+					PR_ASSERT(0 == rv);		\
+				}
+
+#define _PR_Unlock_Malloc() 	if(PR_TRUE == _PR_malloc_initialised) { \
+					PRStatus rv;			\
+					rv = pthread_mutex_unlock(&_PR_MD_malloc_crustylock); \
+					PR_ASSERT(0 == rv);		\
+				}					\
+			  }
+#else /* _PR_PTHREADS */
+static _MDLock _PR_MD_malloc_crustylock;
+
+#ifdef IRIX
+#define _PR_Lock_Malloc() {						\
+			   PRIntn _is;					\
+    				if(PR_TRUE == _PR_malloc_initialised) { \
+				if (_PR_MD_GET_ATTACHED_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_PR_MD_GET_ATTACHED_THREAD()))	\
+						_PR_INTSOFF(_is); 	\
+					_PR_MD_LOCK(&_PR_MD_malloc_crustylock); \
+				}
+
+#define _PR_Unlock_Malloc() 	if(PR_TRUE == _PR_malloc_initialised) { \
+					_PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \
+				if (_PR_MD_GET_ATTACHED_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_PR_MD_GET_ATTACHED_THREAD()))	\
+						_PR_INTSON(_is);	\
+				}					\
+			  }
+#else	/* IRIX */
+#define _PR_Lock_Malloc() {						\
+			   PRIntn _is;					\
+    				if(PR_TRUE == _PR_malloc_initialised) { \
+				if (_PR_MD_CURRENT_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_PR_MD_CURRENT_THREAD()))	\
+						_PR_INTSOFF(_is); 	\
+					_PR_MD_LOCK(&_PR_MD_malloc_crustylock); \
+				}
+
+#define _PR_Unlock_Malloc() 	if(PR_TRUE == _PR_malloc_initialised) { \
+					_PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \
+				if (_PR_MD_CURRENT_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_PR_MD_CURRENT_THREAD()))	\
+						_PR_INTSON(_is);	\
+				}					\
+			  }
+#endif	/* IRIX	*/
+#endif /* _PR_PTHREADS */
+
+PR_IMPLEMENT(PRStatus) _PR_MallocInit(void)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    if( PR_TRUE == _PR_malloc_initialised ) return PR_SUCCESS;
+
+#ifdef _PR_PTHREADS
+    {
+	int status;
+	pthread_mutexattr_t mattr;
+
+	status = _PT_PTHREAD_MUTEXATTR_INIT(&mattr);
+	PR_ASSERT(0 == status);
+	status = _PT_PTHREAD_MUTEX_INIT(_PR_MD_malloc_crustylock, mattr);
+	PR_ASSERT(0 == status);
+	status = _PT_PTHREAD_MUTEXATTR_DESTROY(&mattr);
+	PR_ASSERT(0 == status);
+    }
+#else /* _PR_PTHREADS */
+    _MD_NEW_LOCK(&_PR_MD_malloc_crustylock);
+#endif /* _PR_PTHREADS */
+
+    if( PR_SUCCESS == rv )
+    {
+        _PR_malloc_initialised = PR_TRUE;
+    }
+
+    return rv;
+}
+
+void *malloc(size_t size)
+{
+    void *p;
+    _PR_Lock_Malloc();
+    p = _PR_UnlockedMalloc(size);
+    _PR_Unlock_Malloc();
+    return p;
+}
+
+#if defined(IRIX)
+void *memalign(size_t alignment, size_t size)
+{
+    void *p;
+    _PR_Lock_Malloc();
+    p = _PR_UnlockedMemalign(alignment, size);
+    _PR_Unlock_Malloc();
+    return p;
+}
+
+void *valloc(size_t size)
+{
+    return(memalign(sysconf(_SC_PAGESIZE),size));
+}
+#endif	/* IRIX */
+
+void free(void *ptr)
+{
+    _PR_Lock_Malloc();
+    _PR_UnlockedFree(ptr);
+    _PR_Unlock_Malloc();
+}
+
+void *realloc(void *ptr, size_t size)
+{
+    void *p;
+    _PR_Lock_Malloc();
+    p = _PR_UnlockedRealloc(ptr, size);
+    _PR_Unlock_Malloc();
+    return p;
+}
+
+void *calloc(size_t n, size_t elsize)
+{
+    void *p;
+    _PR_Lock_Malloc();
+    p = _PR_UnlockedCalloc(n, elsize);
+    _PR_Unlock_Malloc();
+    return p;
+}
+
+void cfree(void *p)
+{
+    _PR_Lock_Malloc();
+    _PR_UnlockedFree(p);
+    _PR_Unlock_Malloc();
+}
+
+void _PR_InitMem(void)
+{
+    PRStatus rv;
+    rv = _PR_MallocInit();
+    PR_ASSERT(PR_SUCCESS == rv);
+}
+
+#endif /* _PR_OVERRIDE_MALLOC */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/Makefile.in
new file mode 100644
index 0000000..2b8d477
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/Makefile.in
@@ -0,0 +1,64 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = $(PR_MD_ARCH_DIR)
+
+CSRCS =          \
+	prosdep.c \
+	$(NULL)
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/Makefile.in
new file mode 100644
index 0000000..fca5cf2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/Makefile.in
@@ -0,0 +1,60 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+MOD_DEPTH	= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+include $(srcdir)/bsrcs.mk
+CSRCS += $(MDCSRCS)
+
+TARGETS		= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bcpu.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bcpu.c
new file mode 100644
index 0000000..548df8c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bcpu.c
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+PR_EXTERN(void) _PR_MD_INIT_CPUS();
+PR_EXTERN(void) _PR_MD_WAKEUP_CPUS();
+PR_EXTERN(void) _PR_MD_START_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_STOP_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_CLOCK_INTERRUPT(void);
+PR_EXTERN(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
+PR_EXTERN(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
+PR_EXTERN(PRInt32) _PR_MD_GET_INTSOFF(void);
+PR_EXTERN(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
+PR_EXTERN(_PRCPU*) _PR_MD_CURRENT_CPU(void);
+PR_EXTERN(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
+PR_EXTERN(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
+PR_EXTERN(PRInt32) _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/beos.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/beos.c
new file mode 100644
index 0000000..dba9ae2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/beos.c
@@ -0,0 +1,264 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <signal.h>
+#include <unistd.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+/*
+ * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
+ * PRInt32* pointer to a _PRSockLen_t* pointer.
+ */
+#define _PRSockLen_t int
+
+/*
+** Global lock variable used to bracket calls into rusty libraries that
+** aren't thread safe (like libc, libX, etc).
+*/
+static PRLock *_pr_rename_lock = NULL;
+static PRMonitor *_pr_Xfe_mon = NULL;
+
+/*
+ * Variables used by the GC code, initialized in _MD_InitSegs().
+ * _pr_zero_fd should be a static variable.  Unfortunately, there is
+ * still some Unix-specific code left in function PR_GrowSegment()
+ * in file memory/prseg.c that references it, so it needs
+ * to be a global variable for now.
+ */
+PRInt32 _pr_zero_fd = -1;
+static PRLock *_pr_md_lock = NULL;
+
+sigset_t timer_set;
+
+void _PR_UnixInit()
+{
+	struct sigaction sigact;
+	int rv;
+
+	sigemptyset(&timer_set);
+
+	sigact.sa_handler = SIG_IGN;
+	sigemptyset(&sigact.sa_mask);
+	sigact.sa_flags = 0;
+	rv = sigaction(SIGPIPE, &sigact, 0);
+	PR_ASSERT(0 == rv);
+
+	_pr_rename_lock = PR_NewLock();
+	PR_ASSERT(NULL != _pr_rename_lock);
+	_pr_Xfe_mon = PR_NewMonitor();
+	PR_ASSERT(NULL != _pr_Xfe_mon);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the Unix
+ *     implementation.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+	struct timeval tv;
+	PRInt64 s, us, s2us;
+
+	GETTIMEOFDAY(&tv);
+	LL_I2L(s2us, PR_USEC_PER_SEC);
+	LL_I2L(s, tv.tv_sec);
+	LL_I2L(us, tv.tv_usec);
+	LL_MUL(s, s, s2us);
+	LL_ADD(s, s, us);
+	return s;
+}
+
+PRIntervalTime
+_PR_UNIX_GetInterval()
+{
+	struct timeval time;
+	PRIntervalTime ticks;
+
+	(void)GETTIMEOFDAY(&time);  /* fallicy of course */
+	ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
+	ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
+	return ticks;
+}  /* _PR_SUNOS_GetInterval */
+
+PRIntervalTime _PR_UNIX_TicksPerSecond()
+{
+	return 1000;  /* this needs some work :) */
+}
+
+/************************************************************************/
+
+/*
+** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread
+** safe.  Unfortunately, neither is mozilla. To make these programs work
+** in a pre-emptive threaded environment, we need to use a lock.
+*/
+
+void PR_XLock()
+{
+	PR_EnterMonitor(_pr_Xfe_mon);
+}
+
+void PR_XUnlock()
+{
+	PR_ExitMonitor(_pr_Xfe_mon);
+}
+
+PRBool PR_XIsLocked()
+{
+	return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE;
+}
+
+void PR_XWait(int ms)
+{
+	PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms));
+}
+
+void PR_XNotify(void)
+{
+	PR_Notify(_pr_Xfe_mon);
+}
+
+void PR_XNotifyAll(void)
+{
+	PR_NotifyAll(_pr_Xfe_mon);
+}
+
+#if !defined(BEOS)
+#ifdef HAVE_BSD_FLOCK
+
+#include <sys/file.h>
+
+PR_IMPLEMENT(PRStatus)
+_MD_LOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = flock(f, LOCK_EX);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_TLOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = flock(f, LOCK_EX|LOCK_NB);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_UNLOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = flock(f, LOCK_UN);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+#else
+
+PR_IMPLEMENT(PRStatus)
+_MD_LOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = lockf(f, F_LOCK, 0);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_TLOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = lockf(f, F_TLOCK, 0);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_UNLOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = lockf(f, F_ULOCK, 0);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+#endif
+
+PR_IMPLEMENT(PRStatus)
+  _MD_GETHOSTNAME (char *name, PRUint32 namelen)
+{
+    PRIntn rv;
+
+    rv = gethostname(name, namelen);
+    if (0 == rv) {
+		return PR_SUCCESS;
+    }
+	_PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+#endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/beos_errors.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/beos_errors.c
new file mode 100644
index 0000000..bfb44eb
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/beos_errors.c
@@ -0,0 +1,1526 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prtypes.h"
+#include "md/_unix_errors.h"
+#include "prerror.h"
+#include <errno.h>
+
+void _MD_unix_map_opendir_error(int err)
+{
+	switch (err) {
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENFILE:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_closedir_error(int err)
+{
+	switch (err) {
+		case EINVAL:
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_readdir_error(int err)
+{
+
+	switch (err) {
+		case 0:
+		case ENOENT:
+			PR_SetError(PR_NO_MORE_FILES_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#ifdef IRIX
+#ifdef IRIX5_3
+#else
+		case EDIRCORRUPTED:
+			PR_SetError(PR_DIRECTORY_CORRUPTED_ERROR, err);
+			break;
+#endif
+#endif
+#ifdef EOVERFLOW
+		case EOVERFLOW:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#endif
+		case EINVAL:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#ifdef EBADMSG
+		case EBADMSG:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#endif
+		case EDEADLK:
+			PR_SetError(PR_DEADLOCK_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ENOLCK:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+#ifdef ENOLINK
+		case ENOLINK:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+#endif
+		case ENXIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_unlink_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EBUSY:
+			PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EPERM:
+			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_stat_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+#ifdef EOVERFLOW
+		case EOVERFLOW:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_fstat_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ETIMEDOUT:
+#ifdef ENOLINK
+		case ENOLINK:
+#endif
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+#ifdef EOVERFLOW
+		case EOVERFLOW:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_rename_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EBUSY:
+			PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err);
+			break;
+#ifdef EDQUOT
+		case EDQUOT:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#endif
+		case EEXIST:
+			PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EISDIR:
+			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		case EXDEV:
+			PR_SetError(PR_NOT_SAME_DEVICE_ERROR, err);
+			break;
+		case EMLINK:
+			PR_SetError(PR_MAX_DIRECTORY_ENTRIES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_access_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_mkdir_error(int err)
+{
+	switch (err) {
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EEXIST:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case EMLINK:
+			PR_SetError(PR_MAX_DIRECTORY_ENTRIES_ERROR, err);
+			break;
+		case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#ifdef EDQUOT
+		case EDQUOT:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#endif
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_rmdir_error(int err)
+{
+
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EBUSY:
+			PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err);
+			break;
+		case EEXIST:
+			PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_read_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#ifdef EBADMSG
+		case EBADMSG:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#endif
+		case EDEADLK:
+			PR_SetError(PR_DEADLOCK_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ENOLCK:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ENXIO:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EISDIR:
+			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
+			break;
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+#ifdef ENOLINK
+		case ENOLINK:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_write_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EDEADLK:
+			PR_SetError(PR_DEADLOCK_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EFBIG:
+			PR_SetError(PR_FILE_TOO_BIG_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ENOLCK:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ENXIO:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case ERANGE:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+#ifdef EDQUOT
+		case EDQUOT:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#endif
+#ifdef ENOLINK
+		case ENOLINK:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_lseek_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ESPIPE:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_fsync_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#ifdef ENOLINK
+		case ENOLINK:
+#endif
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_close_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+#ifdef ENOLINK
+		case ENOLINK:
+#endif
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_socket_error(int err)
+{
+	switch (err) {
+		case EPROTONOSUPPORT:
+			PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+			break;
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENFILE:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+#endif /* !defined(SCO) */
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_socketavailable_error(int err)
+{
+	PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+}
+
+void _MD_unix_map_recv_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_recvfrom_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ECONNRESET:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_send_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+#if !defined(BEOS)
+		case EMSGSIZE:
+#endif
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif /* !defined(SCO) */
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_sendto_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+#if !defined(BEOS)
+		case EMSGSIZE:
+#endif
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif /* !defined(SCO) */
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_writev_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_accept_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+#if !defined(BEOS)
+		case EOPNOTSUPP:
+#endif
+		case ENODEV:
+			PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENFILE:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+#ifdef EPROTO
+		case EPROTO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_connect_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EADDRNOTAVAIL:
+			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+			break;
+		case EINPROGRESS:
+			PR_SetError(PR_IN_PROGRESS_ERROR, err);
+			break;
+		case EALREADY:
+			PR_SetError(PR_ALREADY_INITIATED_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EAFNOSUPPORT:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_IO_TIMEOUT_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case ENETUNREACH:
+			PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err);
+			break;
+		case EADDRINUSE:
+			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		/*
+		 * UNIX domain sockets are not supported in NSPR
+		 */
+		case EACCES:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EIO:
+#if defined(UNIXWARE) || defined(SNI) || defined(NEC)
+			/*
+			 * On some platforms, if we connect to a port on
+			 * the local host (the loopback address) that no
+			 * process is listening on, we get EIO instead
+			 * of ECONNREFUSED.
+			 */
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+#else
+			PR_SetError(PR_IO_ERROR, err);
+#endif
+			break;
+		case ELOOP:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ENXIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EPROTOTYPE:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_bind_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EADDRNOTAVAIL:
+			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+			break;
+		case EADDRINUSE:
+			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_SOCKET_ADDRESS_IS_BOUND_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		/*
+		 * UNIX domain sockets are not supported in NSPR
+		 */
+		case EIO:
+		case EISDIR:
+		case ELOOP:
+		case ENOENT:
+		case ENOTDIR:
+		case EROFS:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_listen_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+#if !defined(BEOS)
+		case EOPNOTSUPP:
+			PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_shutdown_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case ENOTCONN:
+			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_socketpair_error(int err)
+{
+	switch (err) {
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case EAFNOSUPPORT:
+		case EPROTONOSUPPORT:
+#if !defined(BEOS)
+		case EOPNOTSUPP:
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_getsockname_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+#endif /* !defined(SCO) */
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_getpeername_error(int err)
+{
+
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case ENOTCONN:
+			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+#endif /* !defined(SCO) */
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_getsockopt_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case ENOPROTOOPT:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_setsockopt_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case ENOPROTOOPT:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_open_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EAGAIN:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case EBUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EEXIST:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EISDIR:
+			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENFILE:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENODEV:
+		case ENOENT:
+		case ENXIO:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EPERM:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_mmap_error(int err)
+{
+
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EAGAIN:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_gethostname_error(int err)
+{
+    switch (err) {
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+void _MD_unix_map_select_error(int err)
+{
+    switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+void _MD_unix_map_poll_error(int err)
+{
+    PRErrorCode prerror;
+    switch (err) {
+        case EAGAIN:
+            prerror = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case EINVAL:
+            prerror = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case EFAULT:
+            prerror = PR_ACCESS_FAULT_ERROR;
+            break;
+        default:
+            prerror = PR_UNKNOWN_ERROR;
+            break;
+    }
+    PR_SetError(prerror, err);
+}
+
+void _MD_unix_map_flock_error(int err)
+{
+    switch (err) {
+		case EBADF:
+		case EINVAL:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EWOULDBLOCK:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+void _MD_unix_map_lockf_error(int err)
+{
+    switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case EDEADLK:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+#ifdef HPUX11
+void _MD_hpux_map_sendfile_error(int oserror)
+{
+    PRErrorCode prerror;
+
+    switch (oserror) {
+        case ENOTSOCK:
+            prerror = PR_NOT_SOCKET_ERROR;
+            break;
+        case EFAULT:
+            prerror = PR_ACCESS_FAULT_ERROR;
+            break;
+        case ENOBUFS:
+            prerror = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case EINVAL:
+            prerror = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case ENOTCONN:
+            prerror = PR_NOT_CONNECTED_ERROR;
+            break;
+        case EPIPE:
+            prerror = PR_CONNECT_RESET_ERROR;
+            break;
+        case ENOMEM:
+            prerror = PR_OUT_OF_MEMORY_ERROR;
+            break;
+        case EOPNOTSUPP:
+            prerror = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+        default:
+            prerror = PR_UNKNOWN_ERROR;
+    }
+    PR_SetError(prerror, oserror); 
+}
+#endif /* HPUX11 */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bfile.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bfile.c
new file mode 100644
index 0000000..4ab02d0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bfile.c
@@ -0,0 +1,905 @@
+/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+/*
+** Global lock variable used to bracket calls into rusty libraries that
+** aren't thread safe (like libc, libX, etc).
+*/
+static PRLock *_pr_rename_lock = NULL; 
+
+void
+_MD_InitIO (void)
+{
+}
+
+PRStatus
+_MD_open_dir (_MDDir *md,const char *name)
+{
+int err;
+
+	md->d = opendir(name);
+	if (!md->d) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_OPENDIR_ERROR(err);
+		return PR_FAILURE;
+	}
+	return PR_SUCCESS;
+}
+
+char*
+_MD_read_dir (_MDDir *md, PRIntn flags)
+{
+struct dirent *de;
+int err;
+
+	for (;;) {
+		/*
+		 * XXX: readdir() is not MT-safe
+		 */
+		_MD_ERRNO() = 0;
+		de = readdir(md->d);
+
+		if (!de) {
+			err = _MD_ERRNO();
+			_PR_MD_MAP_READDIR_ERROR(err);
+			return 0;
+		}
+
+		if ((flags & PR_SKIP_DOT) &&
+		    (de->d_name[0] == '.') && (de->d_name[1] == 0))
+			continue;
+
+		if ((flags & PR_SKIP_DOT_DOT) &&
+		    (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
+		    (de->d_name[2] == 0))
+			continue;
+
+		if ((flags & PR_SKIP_HIDDEN) && (de->d_name[1] == '.'))
+			continue;
+
+		break;
+	}
+	return de->d_name;
+}
+
+
+PRInt32
+_MD_close_dir (_MDDir *md)
+{
+int rv = 0, err;
+
+	if (md->d) {
+		rv = closedir(md->d);
+		if (rv == -1) {
+			err = _MD_ERRNO();
+			_PR_MD_MAP_CLOSEDIR_ERROR(err);
+		}
+	}
+	return(rv);
+}
+
+void
+_MD_make_nonblock (PRFileDesc *fd)
+{
+	int blocking = 1;
+	setsockopt(fd->secret->md.osfd, SOL_SOCKET, SO_NONBLOCK, &blocking, sizeof(blocking));
+
+}
+
+PRStatus
+_MD_set_fd_inheritable (PRFileDesc *fd, PRBool inheritable)
+{
+        int rv;
+	
+        rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);
+        if (-1 == rv) {
+                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+                return PR_FAILURE;
+        }
+        return PR_SUCCESS;
+}
+
+void
+_MD_init_fd_inheritable (PRFileDesc *fd, PRBool imported)
+{
+	if (imported) {
+		fd->secret->inheritable = _PR_TRI_UNKNOWN;
+	} else {
+		int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
+		if (flags == -1) {
+			PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+			return;
+		}
+		fd->secret->inheritable = (flags & FD_CLOEXEC) ? 
+			_PR_TRI_TRUE : _PR_TRI_FALSE;
+	}
+}
+
+void
+_MD_query_fd_inheritable (PRFileDesc *fd)
+{
+	int flags;
+	
+	PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+	flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
+	PR_ASSERT(-1 != flags);
+	fd->secret->inheritable = (flags & FD_CLOEXEC) ?
+		_PR_TRI_FALSE : _PR_TRI_TRUE;
+}
+
+PRInt32
+_MD_open (const char *name, PRIntn flags, PRIntn mode)
+{
+	PRInt32 osflags;
+	PRInt32 rv, err;
+
+	if (flags & PR_RDWR) {
+		osflags = O_RDWR;
+	} else if (flags & PR_WRONLY) {
+		osflags = O_WRONLY;
+	} else {
+		osflags = O_RDONLY;
+	}
+
+	if (flags & PR_EXCL)
+		osflags |= O_EXCL;
+	if (flags & PR_APPEND)
+		osflags |= O_APPEND;
+	if (flags & PR_TRUNCATE)
+		osflags |= O_TRUNC;
+	if (flags & PR_SYNC) {
+/* Ummmm.  BeOS doesn't appear to
+   support sync in any way shape or
+   form. */
+		return PR_NOT_IMPLEMENTED_ERROR;
+	}
+
+	/*
+	** On creations we hold the 'create' lock in order to enforce
+	** the semantics of PR_Rename. (see the latter for more details)
+	*/
+	if (flags & PR_CREATE_FILE)
+	{
+		osflags |= O_CREAT ;
+		if (NULL !=_pr_rename_lock)
+		    PR_Lock(_pr_rename_lock);
+	}
+
+        rv = open(name, osflags, mode);
+
+        if (rv < 0) {
+                err = _MD_ERRNO();
+                _PR_MD_MAP_OPEN_ERROR(err);
+        }                                                                      
+
+    if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
+        PR_Unlock(_pr_rename_lock);
+        return rv;
+}
+
+PRInt32
+_MD_close_file (PRInt32 osfd)
+{
+PRInt32 rv, err;
+
+	rv = close(osfd);
+	if (rv == -1) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_CLOSE_ERROR(err);
+	}
+	return(rv);
+}
+
+PRInt32
+_MD_read (PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    PRInt32 rv, err;
+    PRInt32 osfd = fd->secret->md.osfd;
+
+    rv = read( osfd, buf, amount );
+    if (rv < 0) {
+	err = _MD_ERRNO();
+	_PR_MD_MAP_READ_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32
+_MD_write (PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    PRInt32 rv, err;
+    PRInt32 osfd = fd->secret->md.osfd;
+
+    rv = write( osfd, buf, amount );
+
+    if( rv < 0 ) {
+
+	err = _MD_ERRNO();
+	_PR_MD_MAP_WRITE_ERROR(err);
+    }
+    return( rv );
+}
+
+#ifndef BONE_VERSION /* Writev moves to bnet.c with BONE */
+PRInt32
+_MD_writev (PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
+	    PRIntervalTime timeout)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+#endif
+
+PRInt32
+_MD_lseek (PRFileDesc *fd, PRInt32 offset, int whence)
+{
+PRInt32 rv, err;
+
+    rv = lseek (fd->secret->md.osfd, offset, whence);
+    if (rv == -1) {
+        err = _MD_ERRNO();
+	_PR_MD_MAP_LSEEK_ERROR(err);
+    }
+    return( rv );
+}
+
+PRInt64
+_MD_lseek64 (PRFileDesc *fd, PRInt64 offset, int whence)
+{
+PRInt32 rv, err;
+
+/* According to the BeOS headers, lseek accepts a
+ * variable of type off_t for the offset, and off_t
+ * is defined to be a 64-bit value.  So no special
+ * cracking needs to be done on "offset".
+ */
+
+    rv = lseek (fd->secret->md.osfd, offset, whence);
+    if (rv == -1) {
+        err = _MD_ERRNO();
+	_PR_MD_MAP_LSEEK_ERROR(err);
+    }
+    return( rv );
+}
+
+PRInt32
+_MD_fsync (PRFileDesc *fd)
+{
+PRInt32 rv, err;
+
+    rv = fsync(fd->secret->md.osfd);
+    if (rv == -1) {
+	err = _MD_ERRNO();
+	_PR_MD_MAP_FSYNC_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32
+_MD_delete (const char *name)
+{
+PRInt32 rv, err;
+
+    rv = unlink(name);
+    if (rv == -1)
+    {
+	err = _MD_ERRNO();
+        _PR_MD_MAP_UNLINK_ERROR(err);
+    }
+    return (rv);
+}
+
+PRInt32
+_MD_getfileinfo (const char *fn, PRFileInfo *info)
+{
+struct stat sb;
+PRInt32 rv, err;
+PRInt64 s, s2us;
+
+	rv = stat(fn, &sb);
+	if (rv < 0) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_STAT_ERROR(err);
+	} else if (info) {
+		if (S_IFREG & sb.st_mode)
+			info->type = PR_FILE_FILE;
+		else if (S_IFDIR & sb.st_mode)
+			info->type = PR_FILE_DIRECTORY;
+		else
+			info->type = PR_FILE_OTHER;
+
+		/* Must truncate file size for the 32 bit
+		   version */
+		info->size = (sb.st_size & 0xffffffff);
+		LL_I2L(s, sb.st_mtime);
+		LL_I2L(s2us, PR_USEC_PER_SEC);
+		LL_MUL(s, s, s2us);
+		info->modifyTime = s;
+		LL_I2L(s, sb.st_ctime);
+		LL_MUL(s, s, s2us);
+		info->creationTime = s;
+	}
+	return rv;
+}
+
+PRInt32
+_MD_getfileinfo64 (const char *fn, PRFileInfo64 *info)
+{
+struct stat sb;
+PRInt32 rv, err;
+PRInt64 s, s2us;
+
+	rv = stat(fn, &sb);
+	if (rv < 0) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_STAT_ERROR(err);
+	} else if (info) {
+		if (S_IFREG & sb.st_mode)
+			info->type = PR_FILE_FILE;
+		else if (S_IFDIR & sb.st_mode)
+			info->type = PR_FILE_DIRECTORY;
+		else
+			info->type = PR_FILE_OTHER;
+	
+		/* For the 64 bit version we can use
+		 * the native st_size without modification
+		 */
+		info->size = sb.st_size;
+		LL_I2L(s, sb.st_mtime);
+		LL_I2L(s2us, PR_USEC_PER_SEC);
+		LL_MUL(s, s, s2us);
+		info->modifyTime = s;
+		LL_I2L(s, sb.st_ctime);
+		LL_MUL(s, s, s2us);
+		info->creationTime = s;
+	}
+	return rv;
+}
+
+PRInt32
+_MD_getopenfileinfo (const PRFileDesc *fd, PRFileInfo *info)
+{
+        struct stat sb;
+        PRInt64 s, s2us;
+        PRInt32 rv, err;
+
+        rv = fstat(fd->secret->md.osfd, &sb);
+        if (rv < 0) {
+                        err = _MD_ERRNO();
+                        _PR_MD_MAP_FSTAT_ERROR(err);
+        } else if (info) {
+                if (info) {
+                        if (S_IFREG & sb.st_mode)
+                                info->type = PR_FILE_FILE ;
+                        else if (S_IFDIR & sb.st_mode)
+                                info->type = PR_FILE_DIRECTORY;
+                        else
+                                info->type = PR_FILE_OTHER;
+			/* Use lower 32 bits of file size */
+                        info->size = ( sb.st_size & 0xffffffff);
+                        LL_I2L(s, sb.st_mtime);
+                        LL_I2L(s2us, PR_USEC_PER_SEC);
+                        LL_MUL(s, s, s2us);
+                        info->modifyTime = s;
+                        LL_I2L(s, sb.st_ctime);
+                        LL_MUL(s, s, s2us);
+                        info->creationTime = s;
+                }
+        }
+        return rv;
+}
+
+PRInt32
+_MD_getopenfileinfo64 (const PRFileDesc *fd, PRFileInfo64 *info)
+{
+        struct stat sb;
+        PRInt64 s, s2us;
+        PRInt32 rv, err;
+
+        rv = fstat(fd->secret->md.osfd, &sb);
+        if (rv < 0) {
+                        err = _MD_ERRNO();
+                        _PR_MD_MAP_FSTAT_ERROR(err);
+        } else if (info) {
+                if (info) {
+                        if (S_IFREG & sb.st_mode)
+                                info->type = PR_FILE_FILE ;
+                        else if (S_IFDIR & sb.st_mode)
+                                info->type = PR_FILE_DIRECTORY;
+                        else
+                                info->type = PR_FILE_OTHER;
+                        info->size = sb.st_size;
+                        LL_I2L(s, sb.st_mtime);
+                        LL_I2L(s2us, PR_USEC_PER_SEC);
+                        LL_MUL(s, s, s2us);
+                        info->modifyTime = s;
+                        LL_I2L(s, sb.st_ctime);
+                        LL_MUL(s, s, s2us);
+                        info->creationTime = s;
+                }
+        }
+        return rv;
+}
+
+PRInt32
+_MD_rename (const char *from, const char *to)
+{
+    PRInt32 rv = -1, err;
+
+    /*
+    ** This is trying to enforce the semantics of WINDOZE' rename
+    ** operation. That means one is not allowed to rename over top
+    ** of an existing file. Holding a lock across these two function
+    ** and the open function is known to be a bad idea, but ....
+    */
+    if (NULL != _pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+    if (0 == access(to, F_OK))
+        PR_SetError(PR_FILE_EXISTS_ERROR, 0);
+    else
+    {
+            rv = rename(from, to);
+            if (rv < 0) {
+                    err = _MD_ERRNO();
+                    _PR_MD_MAP_RENAME_ERROR(err);
+            }
+    }
+    if (NULL != _pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+    return rv; 
+}
+
+PRInt32
+_MD_access (const char *name, PRIntn how)
+{
+PRInt32 rv, err;
+int checkFlags;
+struct stat buf;
+
+	switch (how) {
+		case PR_ACCESS_WRITE_OK:
+			checkFlags = S_IWUSR | S_IWGRP | S_IWOTH;
+			break;
+		
+		case PR_ACCESS_READ_OK:
+			checkFlags = S_IRUSR | S_IRGRP | S_IROTH;
+			break;
+		
+		case PR_ACCESS_EXISTS:
+			/* we don't need to examine st_mode. */
+			break;
+		
+		default:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+			return -1;
+	}
+
+	rv = stat(name, &buf);
+	if (rv == 0 && how != PR_ACCESS_EXISTS && (!(buf.st_mode & checkFlags))) {
+		PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
+		return -1;
+	}
+
+	if (rv < 0) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_STAT_ERROR(err);
+	}
+
+	return(rv);
+}
+
+PRInt32
+_MD_stat (const char *name, struct stat *buf)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+PRInt32
+_MD_mkdir (const char *name, PRIntn mode)
+{
+    status_t rv;
+    int err;
+
+    /*
+    ** This lock is used to enforce rename semantics as described
+    ** in PR_Rename. Look there for more fun details.
+    */
+    if (NULL !=_pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+
+    rv = mkdir(name, mode);
+    if (rv < 0) {
+	err = _MD_ERRNO();
+	_PR_MD_MAP_MKDIR_ERROR(err);
+    }
+    if (NULL !=_pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+    return rv; 
+}
+
+PRInt32
+_MD_rmdir (const char *name)
+{
+int rv, err;
+
+        rv = rmdir(name);
+        if (rv == -1) {
+                        err = _MD_ERRNO();
+                        _PR_MD_MAP_RMDIR_ERROR(err);
+        }
+        return rv;
+}
+
+PRInt32
+_MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+	PRInt32 rv = 0;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	/*
+	 * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
+	 */
+	fd_set rd, wt, ex;
+	PRFileDesc *bottom;
+	PRPollDesc *pd, *epd;
+	PRInt32 maxfd = -1, ready, err;
+	PRIntervalTime remaining, elapsed, start;
+
+	struct timeval tv, *tvp = NULL;
+
+	if (_PR_PENDING_INTERRUPT(me))
+	{
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+
+	if (0 == npds) {
+		PR_Sleep(timeout);
+		return rv;
+	}
+
+	FD_ZERO(&rd);
+	FD_ZERO(&wt);
+	FD_ZERO(&ex);
+
+	ready = 0;
+	for (pd = pds, epd = pd + npds; pd < epd; pd++)
+	{
+		PRInt16 in_flags_read = 0, in_flags_write = 0;
+		PRInt16 out_flags_read = 0, out_flags_write = 0; 
+		
+		if ((NULL != pd->fd) && (0 != pd->in_flags))
+		{
+			if (pd->in_flags & PR_POLL_READ)
+			{
+				in_flags_read = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+			}
+			if (pd->in_flags & PR_POLL_WRITE)
+			{
+				in_flags_write = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+			}
+			if ((0 != (in_flags_read & out_flags_read))
+			    || (0 != (in_flags_write & out_flags_write)))
+			{
+				/* this one's ready right now */
+				if (0 == ready)
+				{
+					/*
+					 * We will have to return without calling the
+					 * system poll/select function.  So zero the
+					 * out_flags fields of all the poll descriptors
+					 * before this one. 
+					 */
+					PRPollDesc *prev;
+					for (prev = pds; prev < pd; prev++)
+					{
+						prev->out_flags = 0;
+					}
+				}
+				ready += 1;
+				pd->out_flags = out_flags_read | out_flags_write;
+			}
+			else
+			{
+				pd->out_flags = 0;  /* pre-condition */
+				
+				/* make sure this is an NSPR supported stack */
+				bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+				PR_ASSERT(NULL != bottom);  /* what to do about that? */
+				if ((NULL != bottom)
+				    && (_PR_FILEDESC_OPEN == bottom->secret->state))
+				{
+					if (0 == ready)
+					{
+						PRInt32 osfd = bottom->secret->md.osfd; 
+						if (osfd > maxfd) maxfd = osfd;
+						if (in_flags_read & PR_POLL_READ)
+						{
+							pd->out_flags |= _PR_POLL_READ_SYS_READ;
+							FD_SET(osfd, &rd);
+						}
+						if (in_flags_read & PR_POLL_WRITE)
+						{
+							pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+							FD_SET(osfd, &wt);
+						}
+						if (in_flags_write & PR_POLL_READ)
+						{
+							pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+							FD_SET(osfd, &rd);
+						}
+						if (in_flags_write & PR_POLL_WRITE)
+						{
+							pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+							FD_SET(osfd, &wt);
+						}
+						if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
+					}
+				}
+				else
+				{
+					if (0 == ready)
+					{
+						PRPollDesc *prev;
+						for (prev = pds; prev < pd; prev++)
+						{
+							prev->out_flags = 0;
+						}
+					}
+					ready += 1;  /* this will cause an abrupt return */
+					pd->out_flags = PR_POLL_NVAL;  /* bogii */
+				}
+			}
+		}
+		else
+		{
+			pd->out_flags = 0;
+		}
+	}
+
+	if (0 != ready) return ready;  /* no need to block */
+
+	remaining = timeout;
+	start = PR_IntervalNow(); 
+
+ retry:
+	if (timeout != PR_INTERVAL_NO_TIMEOUT)
+	{
+		PRInt32 ticksPerSecond = PR_TicksPerSecond();
+		tv.tv_sec = remaining / ticksPerSecond;
+		tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
+		tvp = &tv;
+	}
+	
+	ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
+	
+	if (ready == -1 && errno == EINTR)
+	{
+		if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
+		else
+		{
+			elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+			if (elapsed > timeout) ready = 0;  /* timed out */
+			else
+			{
+				remaining = timeout - elapsed;
+				goto retry; 
+			}
+		}
+	} 
+
+	/*
+	** Now to unravel the select sets back into the client's poll
+	** descriptor list. Is this possibly an area for pissing away
+	** a few cycles or what?
+	*/
+	if (ready > 0)
+	{
+		ready = 0;
+		for (pd = pds, epd = pd + npds; pd < epd; pd++)
+		{
+			PRInt16 out_flags = 0;
+			if ((NULL != pd->fd) && (0 != pd->in_flags))
+			{
+				PRInt32 osfd;
+				bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+				PR_ASSERT(NULL != bottom);
+				
+				osfd = bottom->secret->md.osfd; 
+				
+				if (FD_ISSET(osfd, &rd))
+				{
+					if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+						out_flags |= PR_POLL_READ;
+					if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+						out_flags |= PR_POLL_WRITE;
+				}
+				if (FD_ISSET(osfd, &wt))
+				{
+					if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+						out_flags |= PR_POLL_READ;
+					if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+						out_flags |= PR_POLL_WRITE;
+				}
+				if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
+
+/* Workaround for nonblocking connects under net_server */
+#ifndef BONE_VERSION 		
+				if (out_flags)
+				{
+					/* check if it is a pending connect */
+					int i = 0, j = 0;
+					PR_Lock( _connectLock );
+					for( i = 0; i < connectCount; i++ ) 
+					{
+						if(connectList[i].osfd == osfd)
+						{
+							int connectError;
+							int connectResult;
+					
+							connectResult = connect(connectList[i].osfd,
+							                        &connectList[i].addr,
+							                        connectList[i].addrlen);
+							connectError = errno;
+					
+							if(connectResult < 0 ) 
+							{
+								if(connectError == EINTR || connectError == EWOULDBLOCK ||
+					  		   connectError == EINPROGRESS || connectError == EALREADY)
+								{
+									break;
+								}
+							}
+					
+							if(i == (connectCount - 1))
+							{
+								connectList[i].osfd = -1;
+							} else {
+								for(j = i; j < connectCount; j++ )
+								{
+									memcpy( &connectList[j], &connectList[j+1],
+									        sizeof(connectList[j]));
+								}
+							}
+							connectCount--;
+					
+							bottom->secret->md.connectReturnValue = connectResult;
+							bottom->secret->md.connectReturnError = connectError;
+							bottom->secret->md.connectValueValid = PR_TRUE;
+							break;
+						}
+					}
+					PR_Unlock( _connectLock );
+				}
+#endif
+			}
+			pd->out_flags = out_flags;
+			if (out_flags) ready++;
+		}
+		PR_ASSERT(ready > 0);
+	}
+	else if (ready < 0)
+	{ 
+		err = _MD_ERRNO();
+		if (err == EBADF)
+		{
+			/* Find the bad fds */
+			ready = 0;
+			for (pd = pds, epd = pd + npds; pd < epd; pd++)
+			{
+				pd->out_flags = 0;
+				if ((NULL != pd->fd) && (0 != pd->in_flags))
+				{
+					bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+					if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
+					{
+						pd->out_flags = PR_POLL_NVAL;
+						ready++;
+					}
+				}
+			}
+			PR_ASSERT(ready > 0);
+		}
+		else _PR_MD_MAP_SELECT_ERROR(err);
+	}
+	
+	return ready;
+}  /* _MD_pr_poll */
+
+/*
+ * File locking.
+ */
+
+PRStatus
+_MD_lockfile (PRInt32 osfd)
+{
+    PRInt32 rv;
+    struct flock linfo;
+
+    linfo.l_type = 
+    linfo.l_whence = SEEK_SET;
+    linfo.l_start = 0;
+    linfo.l_len = 0;
+
+    rv = fcntl(osfd, F_SETLKW, &linfo);
+    if (rv == 0)
+	return PR_SUCCESS;
+
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_tlockfile (PRInt32 osfd)
+{
+    PRInt32 rv;
+    struct flock linfo;
+
+    linfo.l_type = 
+    linfo.l_whence = SEEK_SET;
+    linfo.l_start = 0;
+    linfo.l_len = 0;
+
+    rv = fcntl(osfd, F_SETLK, &linfo);
+    if (rv == 0)
+	return PR_SUCCESS;
+
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_unlockfile (PRInt32 osfd)
+{
+    PRInt32 rv;
+    struct flock linfo;
+
+    linfo.l_type = 
+    linfo.l_whence = SEEK_SET;
+    linfo.l_start = 0;
+    linfo.l_len = 0;
+
+    rv = fcntl(osfd, F_UNLCK, &linfo);
+
+    if (rv == 0)
+	return PR_SUCCESS;
+
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmemory.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmemory.c
new file mode 100644
index 0000000..17c7332
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmemory.c
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+PR_EXTERN(void) _PR_MD_INIT_SEGS(void);
+PR_EXTERN(PRStatus) _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
+PR_EXTERN(void) _PR_MD_FREE_SEGMENT(PRSegment *seg);
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmisc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmisc.c
new file mode 100644
index 0000000..429cd7b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmisc.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <stdlib.h>
+
+PRLock *_connectLock = NULL;
+
+#ifndef BONE_VERSION
+/* Workaround for nonblocking connects under net_server */
+PRUint32 connectCount = 0;
+ConnectListNode connectList[64];
+#endif
+                                   
+void
+_MD_cleanup_before_exit (void)
+{
+}
+
+void
+_MD_exit (PRIntn status)
+{
+    exit(status);
+}
+
+void
+_MD_early_init (void)
+{
+}
+
+static PRLock *monitor = NULL;
+
+void
+_MD_final_init (void)
+{
+    _connectLock = PR_NewLock();
+    PR_ASSERT(NULL != _connectLock); 
+#ifndef BONE_VERSION   
+    /* Workaround for nonblocking connects under net_server */
+    connectCount = 0;
+#endif
+}
+
+void
+_MD_AtomicInit (void)
+{
+    if (monitor == NULL) {
+        monitor = PR_NewLock();
+    }
+}
+
+/*
+** This is exceedingly messy.  atomic_add returns the last value, NSPR expects the new value.
+** We just add or subtract 1 from the result.  The actual memory update is atomic.
+*/
+
+PRInt32
+_MD_AtomicAdd( PRInt32 *ptr, PRInt32 val )
+{
+    return( ( atomic_add( (long *)ptr, val ) ) + val );
+}
+
+PRInt32
+_MD_AtomicIncrement( PRInt32 *val )
+{
+    return( ( atomic_add( (long *)val, 1 ) ) + 1 );
+}
+
+PRInt32
+_MD_AtomicDecrement( PRInt32 *val )
+{
+    return( ( atomic_add( (long *)val, -1 ) ) - 1 );
+}
+
+PRInt32
+_MD_AtomicSet( PRInt32 *val, PRInt32 newval )
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(monitor);
+    rv = *val;
+    *val = newval;
+    PR_Unlock(monitor);
+    return rv;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmmap.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmmap.c
new file mode 100644
index 0000000..9edd067
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bmmap.c
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+PR_EXTERN(PRStatus)
+_PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return PR_FAILURE;
+}
+
+PR_EXTERN(PRInt32)
+_PR_MD_GET_MEM_MAP_ALIGNMENT(void)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return -1;
+}
+
+PR_EXTERN(void *)
+_PR_MD_MEM_MAP(PRFileMap *fmap, PRInt64 offset, PRUint32 len)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return 0;
+}
+
+PR_EXTERN(PRStatus)
+_PR_MD_MEM_UNMAP(void *addr, PRUint32 size)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return PR_FAILURE;
+}
+
+PR_EXTERN(PRStatus)
+_PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return PR_FAILURE;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bnet.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bnet.c
new file mode 100644
index 0000000..d0975ed
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bnet.c
@@ -0,0 +1,943 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <signal.h>
+#include <unistd.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+/*
+ * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
+ * PRInt32* pointer to a _PRSockLen_t* pointer.
+ */
+#define _PRSockLen_t int
+
+
+/*
+** Global lock variable used to bracket calls into rusty libraries that
+** aren't thread safe (like libc, libX, etc).
+*/
+static PRLock *_pr_rename_lock = NULL;
+static PRMonitor *_pr_Xfe_mon = NULL;
+
+#define READ_FD     1
+#define WRITE_FD    2
+
+/*
+** This is a support routine to handle "deferred" i/o on sockets. 
+** It uses "select", so it is subject to all of the BeOS limitations
+** (only READ notification, only sockets)
+*/
+
+/*
+ * socket_io_wait --
+ *
+ * wait for socket i/o, periodically checking for interrupt
+ *
+ */
+
+static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
+                              PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    struct timeval tv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime epoch, now, elapsed, remaining;
+    PRBool wait_for_remaining;
+    PRInt32 syserror;
+    fd_set rd_wr;
+
+    switch (timeout) {
+    case PR_INTERVAL_NO_WAIT:
+        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        break;
+    case PR_INTERVAL_NO_TIMEOUT:
+        /*
+         * This is a special case of the 'default' case below.
+         * Please see the comments there.
+         */
+        tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+        tv.tv_usec = 0;
+        FD_ZERO(&rd_wr);
+        do {
+            FD_SET(osfd, &rd_wr);
+            if (fd_type == READ_FD)
+                rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
+            else
+                rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
+            if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+#ifdef BONE_VERSION
+                _PR_MD_MAP_SELECT_ERROR(syserror);
+#else
+                if (syserror == EBADF) {
+                    PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
+                } else {
+                    PR_SetError(PR_UNKNOWN_ERROR, syserror);
+                }
+#endif
+                break;
+            }
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                break;
+            }
+        } while (rv == 0 || (rv == -1 && syserror == EINTR));
+        break;
+    default:
+        now = epoch = PR_IntervalNow();
+        remaining = timeout;
+        FD_ZERO(&rd_wr);
+        do {
+            /*
+             * We block in _MD_SELECT for at most
+             * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+             * so that there is an upper limit on the delay
+             * before the interrupt bit is checked.
+             */
+            wait_for_remaining = PR_TRUE;
+            tv.tv_sec = PR_IntervalToSeconds(remaining);
+            if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
+                wait_for_remaining = PR_FALSE;
+                tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+                tv.tv_usec = 0;
+            } else {
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                                 remaining -
+                                 PR_SecondsToInterval(tv.tv_sec));
+            }
+            FD_SET(osfd, &rd_wr);
+            if (fd_type == READ_FD)
+                rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
+            else
+                rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
+            /*
+             * we don't consider EINTR a real error
+             */
+            if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+#ifdef BONE_VERSION
+                _PR_MD_MAP_SELECT_ERROR(syserror);
+#else
+                if (syserror == EBADF) {
+                    PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
+                } else {
+                    PR_SetError(PR_UNKNOWN_ERROR, syserror);
+                }
+#endif
+                break;
+            }
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                break;
+            }
+            /*
+             * We loop again if _MD_SELECT timed out or got interrupted
+             * by a signal, and the timeout deadline has not passed yet.
+             */
+            if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+                /*
+                 * If _MD_SELECT timed out, we know how much time
+                 * we spent in blocking, so we can avoid a
+                 * PR_IntervalNow() call.
+                 */
+                if (rv == 0) {
+                    if (wait_for_remaining) {
+                        now += remaining;
+                    } else {
+                        now += PR_SecondsToInterval(tv.tv_sec)
+                               + PR_MicrosecondsToInterval(tv.tv_usec);
+                    }
+                } else {
+                    now = PR_IntervalNow();
+                }
+                elapsed = (PRIntervalTime) (now - epoch);
+                if (elapsed >= timeout) {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                    rv = -1;
+                    break;
+                } else {
+                    remaining = timeout - elapsed;
+                }
+            }
+        } while (rv == 0 || (rv == -1 && syserror == EINTR));
+        break;
+    }
+    return(rv);
+}
+
+PRInt32
+_MD_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRInt32 flags,
+          PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+#ifndef BONE_VERSION
+    if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_READ) {
+        _PR_MD_MAP_RECV_ERROR(EPIPE);
+        return -1;
+    }
+#endif
+
+#ifdef BONE_VERSION
+    /*
+    ** Gah, stupid hack.  If reading a zero amount, instantly return success.
+    ** BONE beta 6 returns EINVAL for reads of zero bytes, which parts of
+    ** mozilla use to check for socket availability.
+    */
+
+    if( 0 == amount ) return(0);
+#endif
+
+    while ((rv = recv(osfd, buf, amount, flags)) == -1) {
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            /* If socket was supposed to be blocking,
+            wait a while for the condition to be
+            satisfied. */
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+
+        } else
+            break;
+    }
+
+    if (rv < 0) {
+        _PR_MD_MAP_RECV_ERROR(err);
+    }
+
+done:
+    return(rv);
+}
+
+PRInt32
+_MD_recvfrom (PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+              PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((*addrlen = PR_NETADDR_SIZE(addr)),
+            ((rv = recvfrom(osfd, buf, amount, flags,
+                            (struct sockaddr *) addr,
+                            (_PRSockLen_t *)addrlen)) == -1)) {
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
+            continue;
+        } else {
+            break;
+        }
+    }
+
+    if (rv < 0) {
+        _PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+
+done:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv != -1) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    return(rv);
+}
+
+PRInt32
+_MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags,
+          PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+#ifndef BONE_VERSION
+    if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_WRITE)
+    {
+        _PR_MD_MAP_SEND_ERROR(EPIPE);
+        return -1;
+    }
+#endif
+
+    while ((rv = send(osfd, buf, amount, flags)) == -1) {
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+
+#ifndef BONE_VERSION
+            if( _PR_PENDING_INTERRUPT(me)) {
+
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+
+            /* in UNIX implementations, you could do a socket_io_wait here.
+             * but since BeOS doesn't yet support WRITE notification in select,
+             * you're spanked.
+             */
+            snooze( 10000L );
+            continue;
+#else /* BONE_VERSION */
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
+                goto done;
+#endif
+
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
+            continue;
+
+        } else {
+            break;
+        }
+    }
+
+#ifdef BONE_VERSION
+    /*
+     * optimization; if bytes sent is less than "amount" call
+     * select before returning. This is because it is likely that
+     * the next writev() call will return EWOULDBLOCK.
+     */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+        && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
+            rv = -1;
+            goto done;
+        }
+    }
+#endif /* BONE_VERSION */
+    
+    if (rv < 0) {
+        _PR_MD_MAP_SEND_ERROR(err);
+    }
+
+#ifdef BONE_VERSION
+done:
+#endif
+    return(rv);
+}
+
+PRInt32
+_MD_sendto (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+
+    while ((rv = sendto(osfd, buf, amount, flags,
+                        (struct sockaddr *) &addrCopy, addrlen)) == -1) {
+#else
+    while ((rv = sendto(osfd, buf, amount, flags,
+                        (struct sockaddr *) addr, addrlen)) == -1) {
+#endif
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+
+#ifdef BONE_VERSION
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
+                goto done;
+#endif
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
+            continue;
+
+        } else {
+            break;
+        }
+    }
+
+    if (rv < 0) {
+        _PR_MD_MAP_SENDTO_ERROR(err);
+    }
+
+#ifdef BONE_VERSION
+done:
+#endif
+    return(rv);
+}
+
+#ifdef BONE_VERSION
+
+PRInt32 _MD_writev(
+    PRFileDesc *fd, const PRIOVec *iov,
+    PRInt32 iov_size, PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 index, amount = 0;
+    PRInt32 osfd = fd->secret->md.osfd;
+    struct iovec osiov[PR_MAX_IOVECTOR_SIZE];
+
+    /* Ensured by PR_Writev */
+    PR_ASSERT(iov_size <= PR_MAX_IOVECTOR_SIZE);
+
+    /*
+     * We can't pass iov to writev because PRIOVec and struct iovec
+     * may not be binary compatible.  Make osiov a copy of iov and
+     * pass osiov to writev.
+     */
+    for (index = 0; index < iov_size; index++) {
+        osiov[index].iov_base = iov[index].iov_base;
+        osiov[index].iov_len = iov[index].iov_len;
+    }
+
+    /*
+     * Calculate the total number of bytes to be sent; needed for
+     * optimization later.
+     * We could avoid this if this number was passed in; but it is
+     * probably not a big deal because iov_size is usually small (less than
+     * 3)
+     */
+    if (!fd->secret->nonblocking) {
+        for (index=0; index<iov_size; index++) {
+            amount += iov[index].iov_len;
+        }
+    }
+
+    while ((rv = writev(osfd, osiov, iov_size)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
+                goto done;
+
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+
+    /*
+     * optimization; if bytes sent is less than "amount" call
+     * select before returning. This is because it is likely that
+     * the next writev() call will return EWOULDBLOCK.
+     */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+        && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
+            rv = -1;
+            goto done;
+        }
+    }
+
+
+    if (rv < 0) {
+        _PR_MD_MAP_WRITEV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+#endif /* BONE_VERSION */
+
+PRInt32
+_MD_accept (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
+            PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = accept(osfd, (struct sockaddr *) addr,
+                        (_PRSockLen_t *)addrlen)) == -1) {
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            /* If it's SUPPOSED to be a blocking thread, wait
+             * a while to see if the triggering condition gets
+             * satisfied.
+             */
+            /* Assume that we're always using a native thread */
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_ACCEPT_ERROR(err);
+    } else if (addr != NULL) {
+        /* bug 134099 */
+        err = getpeername(rv, (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+    }
+done:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv != -1) {
+        /* Mask off the first byte of struct sockaddr (the length field) */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    return(rv);
+}
+
+PRInt32
+_MD_connect (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,
+             PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 osfd = fd->secret->md.osfd;
+
+#ifndef BONE_VERSION
+    fd->secret->md.connectValueValid = PR_FALSE;
+#endif
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+#endif
+
+    /* (Copied from unix.c)
+     * We initiate the connection setup by making a nonblocking connect()
+     * call.  If the connect() call fails, there are two cases we handle
+     * specially:
+     * 1. The connect() call was interrupted by a signal.  In this case
+     *    we simply retry connect().
+     * 2. The NSPR socket is nonblocking and connect() fails with
+     *    EINPROGRESS.  We first wait until the socket becomes writable.
+     *    Then we try to find out whether the connection setup succeeded
+     *    or failed.
+     */
+
+retry:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) {
+#else
+    if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {
+#endif
+        err = _MD_ERRNO();
+#ifndef BONE_VERSION
+        fd->secret->md.connectReturnValue = rv;
+        fd->secret->md.connectReturnError = err;
+        fd->secret->md.connectValueValid = PR_TRUE;
+#endif
+        if( err == EINTR ) {
+
+            if( _PR_PENDING_INTERRUPT(me)) {
+
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+#ifndef BONE_VERSION
+            snooze( 100000L );
+#endif
+            goto retry;
+        }
+
+#ifndef BONE_VERSION
+        if(!fd->secret->nonblocking && ((err == EINPROGRESS) || (err==EAGAIN) || (err==EALREADY))) {
+
+            /*
+            ** There's no timeout on this connect, but that's not
+            ** a big deal, since the connect times out anyways
+            ** after 30 seconds.   Just sleep for 1/10th of a second
+            ** and retry until we go through or die.
+            */
+
+            if( _PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+
+            goto retry;
+        }
+
+        if( fd->secret->nonblocking && ((err == EAGAIN) || (err == EINPROGRESS))) {
+            PR_Lock(_connectLock);
+            if (connectCount < sizeof(connectList)/sizeof(connectList[0])) {
+                connectList[connectCount].osfd = osfd;
+                memcpy(&connectList[connectCount].addr, addr, addrlen);
+                connectList[connectCount].addrlen = addrlen;
+                connectList[connectCount].timeout = timeout;
+                connectCount++;
+                PR_Unlock(_connectLock);
+                _PR_MD_MAP_CONNECT_ERROR(err);
+            } else {
+                PR_Unlock(_connectLock);
+                PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+            }
+            return rv;
+        }
+#else /* BONE_VERSION */
+        if(!fd->secret->nonblocking && (err == EINTR)) {
+
+            rv = socket_io_wait(osfd, WRITE_FD, timeout);
+            if (rv == -1) {
+                return -1;
+            }
+
+            PR_ASSERT(rv == 1);
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            err = _MD_beos_get_nonblocking_connect_error(osfd);
+            if (err != 0) {
+                _PR_MD_MAP_CONNECT_ERROR(err);
+                return -1;
+            }
+            return 0;
+        }
+#endif
+
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+
+    return rv;
+}
+
+PRInt32
+_MD_bind (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv, err;
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen);
+#else
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);
+#endif
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_BIND_ERROR(err);
+    }
+
+    return(rv);
+}
+
+PRInt32
+_MD_listen (PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv, err;
+
+#ifndef BONE_VERSION
+    /* Bug workaround!  Setting listen to 0 on Be accepts no connections.
+    ** On most UN*Xes this sets the default.
+    */
+
+    if( backlog == 0 ) backlog = 5;
+#endif
+
+    rv = listen(fd->secret->md.osfd, backlog);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_LISTEN_ERROR(err);
+    }
+
+    return(rv);
+}
+
+PRInt32
+_MD_shutdown (PRFileDesc *fd, PRIntn how)
+{
+    PRInt32 rv, err;
+
+#ifndef BONE_VERSION
+    if (how == PR_SHUTDOWN_SEND)
+        fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_WRITE;
+    else if (how == PR_SHUTDOWN_RCV)
+        fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_READ;
+    else if (how == PR_SHUTDOWN_BOTH) {
+        fd->secret->md.sock_state = (BE_SOCK_SHUTDOWN_WRITE | BE_SOCK_SHUTDOWN_READ);
+    }
+
+    return 0;
+#else /* BONE_VERSION */
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SHUTDOWN_ERROR(err);
+    }
+    return(rv);
+#endif
+}
+
+PRInt32
+_MD_socketpair (int af, int type, int flags, PRInt32 *osfd)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+PRInt32
+_MD_close_socket (PRInt32 osfd)
+{
+#ifdef BONE_VERSION
+    close( osfd );
+#else
+    closesocket( osfd );
+#endif
+}
+
+PRStatus
+_MD_getsockname (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockname(fd->secret->md.osfd,
+                     (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv == 0) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETSOCKNAME_ERROR(err);
+    }
+
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_MD_getpeername (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getpeername(fd->secret->md.osfd,
+                     (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv == 0) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETPEERNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_MD_getsockopt (PRFileDesc *fd, PRInt32 level,
+                PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockopt(fd->secret->md.osfd, level, optname,
+                    optval, (_PRSockLen_t *)optlen);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETSOCKOPT_ERROR(err);
+    }
+
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_MD_setsockopt (PRFileDesc *fd, PRInt32 level,
+                PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv, err;
+
+    rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRInt32
+_MD_accept_read (PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr,
+                 void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+#ifndef BONE_VERSION
+PRInt32
+_MD_socket (int af, int type, int flags)
+{
+    PRInt32 osfd, err;
+
+    osfd = socket( af, type, 0 );
+
+    if( -1 == osfd ) {
+
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKET_ERROR( err );
+    }
+
+    return( osfd );
+}
+#else
+PRInt32
+_MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
+{
+    PRInt32 osfd, err;
+
+    osfd = socket(domain, type, proto);
+
+    if (osfd == -1) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKET_ERROR(err);
+    }
+
+    return(osfd);
+}
+#endif
+
+PRInt32
+_MD_socketavailable (PRFileDesc *fd)
+{
+#ifdef BONE_VERSION
+    PRInt32 result;
+
+    if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+        _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO());
+        return -1;
+    }
+    return result;
+#else
+    return PR_NOT_IMPLEMENTED_ERROR;
+#endif
+}
+
+PRInt32
+_MD_get_socket_error (void)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+PRStatus
+_MD_gethostname (char *name, PRUint32 namelen)
+{
+    PRInt32 rv, err;
+
+    rv = gethostname(name, namelen);
+    if (rv == 0)
+    {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETHOSTNAME_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+#ifndef BONE_VERSION
+PRInt32
+_MD_beos_get_nonblocking_connect_error(PRFileDesc *fd)
+{
+    int rv;
+    int flags = 0;
+
+    rv = recv(fd->secret->md.osfd, NULL, 0, flags);
+    PR_ASSERT(-1 == rv || 0 == rv);
+    if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) {
+        return errno;
+    }
+    return 0;  /* no error */
+}
+#else
+PRInt32
+_MD_beos_get_nonblocking_connect_error(int osfd)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+    //    int err;
+    //    _PRSockLen_t optlen = sizeof(err);
+    //    if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) {
+    //        return errno;
+    //    } else {
+    //        return err;
+    //    }
+}
+#endif /* BONE_VERSION */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bproc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bproc.c
new file mode 100644
index 0000000..dd24871
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bproc.c
@@ -0,0 +1,244 @@
+/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <stdio.h>
+#include <signal.h>
+
+#define _PR_SIGNALED_EXITSTATUS 256
+
+PRProcess*
+_MD_create_process (const char *path, char *const *argv,
+		    char *const *envp, const PRProcessAttr *attr)
+{
+	PRProcess *process;
+	int nEnv, idx;
+	char *const *childEnvp;
+	char **newEnvp = NULL;
+	int flags;
+	PRBool found = PR_FALSE;
+
+	process = PR_NEW(PRProcess);
+	if (!process) {
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+		return NULL;
+	}
+
+	childEnvp = envp;
+	if (attr && attr->fdInheritBuffer) {
+		if (NULL == childEnvp) {
+			childEnvp = environ;
+		}
+		for (nEnv = 0; childEnvp[nEnv]; nEnv++) {
+		}
+		newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *));
+		if (NULL == newEnvp) {
+			PR_DELETE(process);
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+			return NULL;
+		}
+		for (idx = 0; idx < nEnv; idx++) {
+			newEnvp[idx] = childEnvp[idx];
+			if (!found && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) {
+				newEnvp[idx] = attr->fdInheritBuffer;
+				found = PR_TRUE;
+			}
+		}
+		if (!found) {
+			newEnvp[idx++] = attr->fdInheritBuffer;
+		}
+		newEnvp[idx] = NULL;
+		childEnvp = newEnvp;
+	}
+
+	process->md.pid = fork();
+
+	if ((pid_t) -1 == process->md.pid) {
+		PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno);
+		PR_DELETE(process);
+		if (newEnvp) {
+			PR_DELETE(newEnvp);
+		}
+		return NULL;
+	} else if (0 == process->md.pid) {  /* the child process */
+		/*
+		 * If the child process needs to exit, it must call _exit().
+		 * Do not call exit(), because exit() will flush and close
+		 * the standard I/O file descriptors, and hence corrupt
+		 * the parent process's standard I/O data structures.
+		 */
+
+		if (attr) {
+			/* the osfd's to redirect stdin, stdout, and stderr to */
+			int in_osfd = -1, out_osfd = -1, err_osfd = -1;
+
+			if (attr->stdinFd
+			    && attr->stdinFd->secret->md.osfd != 0) {
+				in_osfd = attr->stdinFd->secret->md.osfd;
+				if (dup2(in_osfd, 0) != 0) {
+					_exit(1);  /* failed */
+				}
+				flags = fcntl(0, F_GETFL, 0);
+				if (flags & O_NONBLOCK) {
+					fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
+				}
+			}
+			if (attr->stdoutFd
+			    && attr->stdoutFd->secret->md.osfd != 1) {
+				out_osfd = attr->stdoutFd->secret->md.osfd;
+				if (dup2(out_osfd, 1) != 1) {
+					_exit(1);  /* failed */
+				}
+				flags = fcntl(1, F_GETFL, 0);
+				if (flags & O_NONBLOCK) {
+					fcntl(1, F_SETFL, flags & ~O_NONBLOCK);
+				}
+			}
+			if (attr->stderrFd
+			    && attr->stderrFd->secret->md.osfd != 2) {
+				err_osfd = attr->stderrFd->secret->md.osfd;
+				if (dup2(err_osfd, 2) != 2) {
+					_exit(1);  /* failed */
+				}
+				flags = fcntl(2, F_GETFL, 0);
+				if (flags & O_NONBLOCK) {
+					fcntl(2, F_SETFL, flags & ~O_NONBLOCK);
+				}
+			}
+			if (in_osfd != -1) {
+				close(in_osfd);
+			}
+			if (out_osfd != -1 && out_osfd != in_osfd) {
+				close(out_osfd);
+			}
+			if (err_osfd != -1 && err_osfd != in_osfd
+			    && err_osfd != out_osfd) {
+				close(err_osfd);
+			}
+			if (attr->currentDirectory) {
+				if (chdir(attr->currentDirectory) < 0) {
+					_exit(1);  /* failed */
+				}
+			}
+		}
+
+		if (childEnvp) {
+			(void)execve(path, argv, childEnvp);
+		} else {
+			/* Inherit the environment of the parent. */
+			(void)execv(path, argv);
+		}
+		/* Whoops! It returned. That's a bad sign. */
+		_exit(1);
+	}
+
+	if (newEnvp) {
+		PR_DELETE(newEnvp);
+	}
+
+	return process;
+}
+
+PRStatus
+_MD_detach_process (PRProcess *process)
+{
+	/* If we kept a process table like unix does,
+	 * we'd remove the entry here.
+	 * Since we dont', just delete the process variable
+	 */
+	PR_DELETE(process);
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_wait_process (PRProcess *process, PRInt32 *exitCode)
+{
+	PRStatus retVal = PR_SUCCESS;
+	int ret, status;
+	
+	/* Ignore interruptions */
+	do {
+		ret = waitpid(process->md.pid, &status, 0);
+	} while (ret == -1 && errno == EINTR);
+
+	/*
+	 * waitpid() cannot return 0 because we did not invoke it
+	 * with the WNOHANG option.
+	 */ 
+	PR_ASSERT(0 != ret);
+
+	if (ret < 0) {
+                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+		return PR_FAILURE;
+	}
+
+	/* If child process exited normally, return child exit code */
+	if (WIFEXITED(status)) {
+		*exitCode = WEXITSTATUS(status);
+	} else {
+		PR_ASSERT(WIFSIGNALED(status));
+		*exitCode = _PR_SIGNALED_EXITSTATUS;
+	}		
+
+	PR_DELETE(process);
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_kill_process (PRProcess *process)
+{
+	PRErrorCode prerror;
+	PRInt32 oserror;
+	
+	if (kill(process->md.pid, SIGKILL) == 0) {
+		return PR_SUCCESS;
+	}
+	oserror = errno;
+	switch (oserror) {
+        case EPERM:
+		prerror = PR_NO_ACCESS_RIGHTS_ERROR;
+		break;
+        case ESRCH:
+		prerror = PR_INVALID_ARGUMENT_ERROR;
+		break;
+        default:
+		prerror = PR_UNKNOWN_ERROR;
+		break;
+	}
+	PR_SetError(prerror, oserror);
+	return PR_FAILURE;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/brng.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/brng.c
new file mode 100644
index 0000000..2d1b851
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/brng.c
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <time.h>
+#include "primpl.h"
+
+extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
+{
+    struct timeval tv;
+    int n = 0;
+    int s;
+
+    GETTIMEOFDAY(&tv);
+
+    if ( size > 0 ) {
+        s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec));
+        size -= s;
+        n += s;
+    }
+    if ( size > 0 ) {
+        s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec));
+        size -= s;
+        n += s;
+    }
+
+    return n;
+} /* end _PR_MD_GetRandomNoise() */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bseg.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bseg.c
new file mode 100644
index 0000000..b6b3b67
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bseg.c
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+PR_IMPLEMENT(void)
+    _MD_init_segs (void)
+{
+}
+
+PR_IMPLEMENT(PRStatus)
+    _MD_alloc_segment (PRSegment *seg, PRUint32 size, void *vaddr)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+PR_IMPLEMENT(void)
+    _MD_free_segment (PRSegment *seg)
+{
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bsrcs.mk b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bsrcs.mk
new file mode 100644
index 0000000..c6eb6fe
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/bsrcs.mk
@@ -0,0 +1,54 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+# this file lists the source files to be compiled (used in Makefile) and
+# then enumerated as object files (in objs.mk) for inclusion in the NSPR
+# shared library
+
+MDCSRCS =             \
+	beos.c        \
+	beos_errors.c \
+	bfile.c       \
+	bmisc.c       \
+	bnet.c        \
+	bproc.c       \
+	brng.c        \
+	bseg.c        \
+	btime.c       \
+	bmmap.c       \
+	$(NULL)
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/btime.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/btime.c
new file mode 100644
index 0000000..aaaa9d2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/btime.c
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <kernel/OS.h>
+
+static bigtime_t start;
+
+PRTime
+_MD_now (void)
+{
+    return (PRTime)real_time_clock_usecs();
+}
+
+void
+_MD_interval_init (void)
+{
+    /* grab the base interval time */
+    start = real_time_clock_usecs();
+}
+
+PRIntervalTime
+_MD_get_interval (void)
+{
+    return( (PRIntervalTime) real_time_clock_usecs() / 10 );
+
+#if 0
+    /* return the number of tens of microseconds that have elapsed since
+       we were initialized */
+    bigtime_t now = real_time_clock_usecs();
+    now -= start;
+    now /= 10;
+    return (PRIntervalTime)now;
+#endif
+}
+
+PRIntervalTime
+_MD_interval_per_sec (void)
+{
+    return 100000L;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/objs.mk b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/objs.mk
new file mode 100644
index 0000000..163c5d9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/beos/objs.mk
@@ -0,0 +1,43 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This makefile appends to the variable OBJS the platform-dependent
+# object modules that will be part of the nspr20 library.
+
+include $(srcdir)/md/beos/bsrcs.mk
+
+OBJS += $(MDCSRCS:%.c=md/beos/$(OBJDIR)/%.$(OBJ_SUFFIX))
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/Makefile.in
new file mode 100644
index 0000000..4b00af9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/Makefile.in
@@ -0,0 +1,79 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifeq ($(OS_TARGET), OS2)
+CSRCS = \
+    os2misc.c \
+    os2sem.c   \
+    os2inrval.c \
+    os2gc.c \
+    os2thred.c \
+    os2io.c \
+    os2cv.c \
+    os2sock.c \
+    os2_errors.c \
+    os2poll.c \
+    os2rng.c \
+    $(NULL)
+endif
+
+ASFILES = os2emx.s os2vaclegacy.s
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/objs.mk b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/objs.mk
new file mode 100644
index 0000000..05abac8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/objs.mk
@@ -0,0 +1,59 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This makefile appends to the variable OBJS the platform-dependent
+# object modules that will be part of the nspr20 library.
+
+CSRCS = \
+	os2io.c      \
+	os2sock.c    \
+	os2thred.c   \
+	os2cv.c      \
+	os2gc.c      \
+	os2misc.c    \
+	os2inrval.c  \
+	os2sem.c     \
+	os2_errors.c \
+	os2poll.c    \
+	os2rng.c     \
+	$(NULL)
+
+ASFILES = os2emx.s os2vaclegacy.s
+
+OBJS += $(addprefix md/os2/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)))  \
+	$(addprefix md/os2/$(OBJDIR)/,$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2_errors.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2_errors.c
new file mode 100644
index 0000000..37d0ff8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2_errors.c
@@ -0,0 +1,1127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prerror.h"
+#include "primpl.h"
+
+void _MD_os2_map_default_error(PRInt32 err)
+{
+	switch (err) {
+		case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EMSGSIZE:
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+void _MD_os2_map_opendir_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+      case ERROR_INVALID_ADDRESS:
+      case ERROR_INVALID_ACCESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+      case ERROR_INVALID_NAME:
+      case ERROR_INVALID_PARAMETER:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+      case ERROR_TOO_MANY_OPEN_FILES:
+		case ERROR_NOT_DOS_DISK:
+		case ERROR_NOT_READY:
+		case ERROR_OPEN_FAILED:
+      case ERROR_PATH_BUSY:
+      case ERROR_CANNOT_MAKE:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+      case ERROR_DRIVE_LOCKED:
+      case ERROR_DEVICE_IN_USE:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_SHARING_BUFFER_EXCEEDED:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_closedir_error(PRInt32 err)
+{
+	switch (err) {
+      case ERROR_FILE_NOT_FOUND:
+      case ERROR_ACCESS_DENIED:
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_readdir_error(PRInt32 err)
+{
+
+	switch (err) {
+		case ERROR_NO_MORE_FILES:
+			PR_SetError(PR_NO_MORE_FILES_ERROR, err);
+			break;
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_DOS_DISK:
+		case ERROR_LOCK_VIOLATION:
+		case ERROR_BROKEN_PIPE:
+		case ERROR_NOT_READY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+      case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_delete_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+/* The error code for stat() is in errno. */
+void _MD_os2_map_stat_error(PRInt32 err)
+{
+    switch (err) {
+        case ENOENT:
+            PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+            break;
+        case EACCES:
+            PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+            break;
+        default:
+            PR_SetError(PR_UNKNOWN_ERROR, err);
+    }
+}
+
+void _MD_os2_map_fstat_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_rename_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_INVALID_NAME:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_ALREADY_EXISTS:
+		case ERROR_FILE_EXISTS:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+/* The error code for access() is in errno. */
+void _MD_os2_map_access_error(PRInt32 err)
+{
+    switch (err) {
+        case ENOENT:
+            PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+            break;
+        case EACCES:
+            PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+            break;
+        default:
+            PR_SetError(PR_UNKNOWN_ERROR, err);
+    }
+}
+
+void _MD_os2_map_mkdir_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ALREADY_EXISTS:
+		case ERROR_FILE_EXISTS:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		case ERROR_FILE_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_INVALID_NAME:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DISK_FULL:
+		case ERROR_HANDLE_DISK_FULL:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_rmdir_error(PRInt32 err)
+{
+
+	switch (err) {
+		case ERROR_FILE_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_INVALID_NAME:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_read_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break; 
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_transmitfile_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_write_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+		case ERROR_DISK_FULL:
+      case ERROR_HANDLE_DISK_FULL:
+      case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EMSGSIZE:
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_lseek_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_SEEK_ON_DEVICE:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_fsync_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DISK_FULL:
+		case ERROR_HANDLE_DISK_FULL:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_close_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_INVALID_HANDLE:
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_socket_error(PRInt32 err)
+{
+	switch (err) {
+		case EPROTONOSUPPORT:
+			PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_recv_error(PRInt32 err)
+{
+	switch (err) {
+		case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_recvfrom_error(PRInt32 err)
+{
+	switch (err) {
+		case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_send_error(PRInt32 err)
+{
+	switch (err) {
+		case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EMSGSIZE:
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_sendto_error(PRInt32 err)
+{
+  _MD_os2_map_default_error(err);
+}
+
+void _MD_os2_map_writev_error(int err)
+{
+  _MD_os2_map_default_error(err);
+}
+
+void _MD_os2_map_accept_error(PRInt32 err)
+{
+  _MD_os2_map_default_error(err);
+}
+
+void _MD_os2_map_acceptex_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+/*
+ * An error code of 0 means that the nonblocking connect succeeded.
+ */
+
+int _MD_os2_get_nonblocking_connect_error(int osfd)
+{
+    int err;
+    int len = sizeof(err);
+    if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == -1) {
+        return sock_errno();
+    } else {
+        return err;
+    }
+}
+
+void _MD_os2_map_connect_error(PRInt32 err)
+{
+	switch (err) {
+       case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+        case EINPROGRESS:
+			PR_SetError(PR_IN_PROGRESS_ERROR, err);
+			break;
+		case EALREADY:
+		case EINVAL:
+			PR_SetError(PR_ALREADY_INITIATED_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EADDRNOTAVAIL:
+			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EAFNOSUPPORT:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_IO_TIMEOUT_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case ENETUNREACH:
+			PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err);
+			break;
+		case EADDRINUSE:
+			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+			break;
+      case EISCONN:
+         PR_SetError(PR_IS_CONNECTED_ERROR, err);
+         break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_bind_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case EADDRNOTAVAIL:
+			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+			break;
+		case EADDRINUSE:
+			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_SOCKET_ADDRESS_IS_BOUND_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_listen_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EOPNOTSUPP:
+			PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_shutdown_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case ENOTCONN:
+			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_socketpair_error(PRInt32 err)
+{
+  switch (err) {
+    case ENOMEM:
+      PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+      break;
+    case EAFNOSUPPORT:
+      PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+      break;
+    case EPROTONOSUPPORT:
+      PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+      break;
+    case EOPNOTSUPP:
+      PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+      break;
+    case EPROTOTYPE:
+      PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+      break;
+    default:
+      _MD_os2_map_default_error(err);
+      return;
+  }
+}
+
+void _MD_os2_map_getsockname_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_getpeername_error(PRInt32 err)
+{
+
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case ENOTCONN:
+			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_getsockopt_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case ENOPROTOOPT:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case EINVAL:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_setsockopt_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case ENOPROTOOPT:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case EINVAL:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_open_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ALREADY_EXISTS:
+		case ERROR_FILE_EXISTS:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		case ERROR_FILE_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_INVALID_NAME:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_OPEN_FAILED:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DISK_FULL:
+		case ERROR_HANDLE_DISK_FULL:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_gethostname_error(PRInt32 err)
+{
+    switch (err) {
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ENETDOWN:
+		case EINPROGRESS:
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+void _MD_os2_map_select_error(PRInt32 err)
+{
+    PRErrorCode prerror;
+
+    switch (err) {
+        /*
+         * OS/2 select() only works on sockets.  So in this
+         * context, ENOTSOCK is equivalent to EBADF on Unix.
+         */
+        case ENOTSOCK:
+            prerror = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case EINVAL:
+            prerror = PR_INVALID_ARGUMENT_ERROR;
+            break;
+#ifdef SOCEFAULT
+        case SOCEFAULT:
+            prerror = PR_ACCESS_FAULT_ERROR;
+            break;
+#endif
+        default:
+            prerror = PR_UNKNOWN_ERROR;
+    }
+    PR_SetError(prerror, err);
+}
+
+void _MD_os2_map_lockf_error(PRInt32 err)
+{
+    switch (err) {
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2cv.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2cv.c
new file mode 100644
index 0000000..33e3353
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2cv.c
@@ -0,0 +1,362 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *  os2cv.c -- OS/2 Machine-Dependent Code for Condition Variables
+ *
+ *  We implement our own condition variable wait queue.  Each thread
+ *  has a semaphore object (thread->md.blocked_sema) to block on while
+ *  waiting on a condition variable.
+ *
+ *  We use a deferred condition notify algorithm.  When PR_NotifyCondVar
+ *  or PR_NotifyAllCondVar is called, the condition notifies are simply
+ *  recorded in the _MDLock structure.  We defer the condition notifies
+ *  until right after we unlock the lock.  This way the awakened threads
+ *  have a better chance to reaquire the lock.
+ */
+ 
+#include "primpl.h"
+
+/*
+ * AddThreadToCVWaitQueueInternal --
+ *
+ * Add the thread to the end of the condition variable's wait queue.
+ * The CV's lock must be locked when this function is called.
+ */
+
+static void
+AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv)
+{
+    PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
+            || (cv->waitTail == NULL && cv->waitHead == NULL));
+    cv->nwait += 1;
+    thred->md.inCVWaitQueue = PR_TRUE;
+    thred->md.next = NULL;
+    thred->md.prev = cv->waitTail;
+    if (cv->waitHead == NULL) {
+        cv->waitHead = thred;
+    } else {
+        cv->waitTail->md.next = thred;
+    }
+    cv->waitTail = thred;
+}
+
+/*
+ * md_UnlockAndPostNotifies --
+ *
+ * Unlock the lock, and then do the deferred condition notifies.
+ * If waitThred and waitCV are not NULL, waitThred is added to
+ * the wait queue of waitCV before the lock is unlocked.
+ *
+ * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK,
+ * the two places where a lock is unlocked.
+ */
+void
+md_UnlockAndPostNotifies(
+    _MDLock *lock,
+    PRThread *waitThred,
+    _MDCVar *waitCV)
+{
+    PRIntn index;
+    _MDNotified post;
+    _MDNotified *notified, *prev = NULL;
+
+    /*
+     * Time to actually notify any conditions that were affected
+     * while the lock was held.  Get a copy of the list that's in
+     * the lock structure and then zero the original.  If it's
+     * linked to other such structures, we own that storage.
+     */
+    post = lock->notified;  /* a safe copy; we own the lock */
+
+#if defined(DEBUG)
+    memset(&lock->notified, 0, sizeof(_MDNotified));  /* reset */
+#else
+    lock->notified.length = 0;  /* these are really sufficient */
+    lock->notified.link = NULL;
+#endif
+
+    /* 
+     * Figure out how many threads we need to wake up.
+     */
+    notified = &post;  /* this is where we start */
+    do {
+        for (index = 0; index < notified->length; ++index) {
+            _MDCVar *cv = notified->cv[index].cv;
+            PRThread *thred;
+            int i;
+            
+            /* Fast special case: no waiting threads */
+            if (cv->waitHead == NULL) {
+                notified->cv[index].notifyHead = NULL;
+                continue;
+            }
+
+            /* General case */
+            if (-1 == notified->cv[index].times) {
+                /* broadcast */
+                thred = cv->waitHead;
+                while (thred != NULL) {
+                    thred->md.inCVWaitQueue = PR_FALSE;
+                    thred = thred->md.next;
+                }
+                notified->cv[index].notifyHead = cv->waitHead;
+                cv->waitHead = cv->waitTail = NULL;
+                cv->nwait = 0;
+            } else {
+                thred = cv->waitHead;
+                i = notified->cv[index].times;
+                while (thred != NULL && i > 0) {
+                    thred->md.inCVWaitQueue = PR_FALSE;
+                    thred = thred->md.next;
+                    i--;
+                }
+                notified->cv[index].notifyHead = cv->waitHead;
+                cv->waitHead = thred;
+                if (cv->waitHead == NULL) {
+                    cv->waitTail = NULL;
+                } else {
+                    if (cv->waitHead->md.prev != NULL) {
+                        cv->waitHead->md.prev->md.next = NULL;
+                        cv->waitHead->md.prev = NULL;
+                    }
+                }
+                cv->nwait -= notified->cv[index].times - i;
+            }
+        }
+        notified = notified->link;
+    } while (NULL != notified);
+
+    if (waitThred) {
+        AddThreadToCVWaitQueueInternal(waitThred, waitCV);
+    }
+
+    /* Release the lock before notifying */
+    DosReleaseMutexSem(lock->mutex);
+
+    notified = &post;  /* this is where we start */
+    do {
+        for (index = 0; index < notified->length; ++index) {
+            PRThread *thred;
+            PRThread *next;
+
+            thred = notified->cv[index].notifyHead;
+            while (thred != NULL) {
+                BOOL rv;
+
+                next = thred->md.next;
+                thred->md.prev = thred->md.next = NULL;
+                rv = DosPostEventSem(thred->md.blocked_sema);
+                PR_ASSERT(rv == NO_ERROR);
+                thred = next;
+            }
+        }
+        prev = notified;
+        notified = notified->link;
+        if (&post != prev) PR_DELETE(prev);
+    } while (NULL != notified);
+}
+
+/*
+ * Notifies just get posted to the protecting mutex.  The
+ * actual notification is done when the lock is released so that
+ * MP systems don't contend for a lock that they can't have.
+ */
+static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock,
+        PRBool broadcast)
+{
+    PRIntn index = 0;
+    _MDNotified *notified = &lock->notified;
+
+    while (1) {
+        for (index = 0; index < notified->length; ++index) {
+            if (notified->cv[index].cv == cvar) {
+                if (broadcast) {
+                    notified->cv[index].times = -1;
+                } else if (-1 != notified->cv[index].times) {
+                    notified->cv[index].times += 1;
+                }
+                return;
+            }
+        }
+        /* if not full, enter new CV in this array */
+        if (notified->length < _MD_CV_NOTIFIED_LENGTH) break;
+
+        /* if there's no link, create an empty array and link it */
+        if (NULL == notified->link) {
+            notified->link = PR_NEWZAP(_MDNotified);
+        }
+
+        notified = notified->link;
+    }
+
+    /* A brand new entry in the array */
+    notified->cv[index].times = (broadcast) ? -1 : 1;
+    notified->cv[index].cv = cvar;
+    notified->length += 1;
+}
+
+/*
+ * _PR_MD_NEW_CV() -- Creating new condition variable
+ * ... Solaris uses cond_init() in similar function.
+ *
+ * returns: -1 on failure
+ *          0 when it succeeds.
+ *
+ */
+PRInt32
+_PR_MD_NEW_CV(_MDCVar *cv)
+{
+    cv->magic = _MD_MAGIC_CV;
+    /*
+     * The waitHead, waitTail, and nwait fields are zeroed
+     * when the PRCondVar structure is created.
+     */
+    return 0;
+} 
+
+void _PR_MD_FREE_CV(_MDCVar *cv)
+{
+    cv->magic = (PRUint32)-1;
+    return;
+}
+
+/*
+ *  _PR_MD_WAIT_CV() -- Wait on condition variable
+ */
+void
+_PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
+{
+    PRThread *thred = _PR_MD_CURRENT_THREAD();
+    ULONG rv, count;
+    ULONG msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ?
+            SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(timeout);
+
+    /*
+     * If we have pending notifies, post them now.
+     */
+    if (0 != lock->notified.length) {
+        md_UnlockAndPostNotifies(lock, thred, cv);
+    } else {
+        AddThreadToCVWaitQueueInternal(thred, cv);
+        DosReleaseMutexSem(lock->mutex); 
+    }
+
+    /* Wait for notification or timeout; don't really care which */
+    rv = DosWaitEventSem(thred->md.blocked_sema, msecs);
+    if (rv == NO_ERROR) {
+        DosResetEventSem(thred->md.blocked_sema, &count);
+    }
+
+    DosRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT);
+
+    PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT);
+
+    if(rv == ERROR_TIMEOUT)
+    {
+       if (thred->md.inCVWaitQueue) {
+           PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
+                   || (cv->waitTail == NULL && cv->waitHead == NULL));
+           cv->nwait -= 1;
+           thred->md.inCVWaitQueue = PR_FALSE;
+           if (cv->waitHead == thred) {
+               cv->waitHead = thred->md.next;
+               if (cv->waitHead == NULL) {
+                   cv->waitTail = NULL;
+               } else {
+                   cv->waitHead->md.prev = NULL;
+               }
+           } else {
+               PR_ASSERT(thred->md.prev != NULL);
+               thred->md.prev->md.next = thred->md.next;
+               if (thred->md.next != NULL) {
+                   thred->md.next->md.prev = thred->md.prev;
+               } else {
+                   PR_ASSERT(cv->waitTail == thred);
+                   cv->waitTail = thred->md.prev;
+               }
+           }
+           thred->md.next = thred->md.prev = NULL;
+       } else {
+           /*
+            * This thread must have been notified, but the
+            * SemRelease call happens after SemRequest
+            * times out.  Wait on the semaphore again to make it
+            * non-signaled.  We assume this wait won't take long.
+            */
+           rv = DosWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT);
+           if (rv == NO_ERROR) {
+               DosResetEventSem(thred->md.blocked_sema, &count);
+           }
+           PR_ASSERT(rv == NO_ERROR);
+       }
+    }
+    PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE);
+    return;
+} /* --- end _PR_MD_WAIT_CV() --- */
+
+void
+_PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock)
+{
+    md_PostNotifyToCvar(cv, lock, PR_FALSE);
+    return;
+}
+
+PRStatus
+_PR_MD_NEW_LOCK(_MDLock *lock)
+{
+    DosCreateMutexSem(0, &(lock->mutex), 0, 0);
+    (lock)->notified.length=0;
+    (lock)->notified.link=NULL;
+    return PR_SUCCESS;
+}
+
+void
+_PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock)
+{
+    md_PostNotifyToCvar(cv, lock, PR_TRUE);
+    return;
+}
+
+void _PR_MD_UNLOCK(_MDLock *lock)
+{
+    if (0 != lock->notified.length) {
+        md_UnlockAndPostNotifies(lock, NULL, NULL);
+    } else {
+        DosReleaseMutexSem(lock->mutex);
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2emx.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2emx.s
new file mode 100644
index 0000000..3efd68c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2emx.s
@@ -0,0 +1,114 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ ***** BEGIN LICENSE BLOCK *****
+/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+/
+/ The contents of this file are subject to the Mozilla Public License Version
+/ 1.1 (the "License"); you may not use this file except in compliance with
+/ the License. You may obtain a copy of the License at
+/ http://www.mozilla.org/MPL/
+/
+/ Software distributed under the License is distributed on an "AS IS" basis,
+/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+/ for the specific language governing rights and limitations under the
+/ License.
+/
+/ The Original Code is the Netscape Portable Runtime (NSPR).
+/
+/ The Initial Developer of the Original Code is
+/ Netscape Communications Corporation.
+/ Portions created by the Initial Developer are Copyright (C) 2000
+/ the Initial Developer. All Rights Reserved.
+/
+/ Contributor(s):
+/
+/ Alternatively, the contents of this file may be used under the terms of
+/ either the GNU General Public License Version 2 or later (the "GPL"), or
+/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+/ in which case the provisions of the GPL or the LGPL are applicable instead
+/ of those above. If you wish to allow use of your version of this file only
+/ under the terms of either the GPL or the LGPL, and not to allow others to
+/ use your version of this file under the terms of the MPL, indicate your
+/ decision by deleting the provisions above and replace them with the notice
+/ and other provisions required by the GPL or the LGPL. If you do not delete
+/ the provisions above, a recipient may use your version of this file under
+/ the terms of any one of the MPL, the GPL or the LGPL.
+/
+/ ***** END LICENSE BLOCK *****
+
+/ PRInt32 __PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl __PR_MD_ATOMIC_INCREMENT
+    .align 4
+__PR_MD_ATOMIC_INCREMENT:
+    movl 4(%esp), %ecx
+    movl $1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    incl %eax
+    ret
+
+/ PRInt32 __PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl __PR_MD_ATOMIC_DECREMENT
+    .align 4
+__PR_MD_ATOMIC_DECREMENT:
+    movl 4(%esp), %ecx
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    decl %eax
+    ret
+
+/ PRInt32 __PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+/ An alternative implementation:
+/   .text
+/   .globl __PR_MD_ATOMIC_SET
+/   .align 4
+/__PR_MD_ATOMIC_SET:
+/   movl 4(%esp), %ecx
+/   movl 8(%esp), %edx
+/   movl (%ecx), %eax
+/retry:
+/   lock
+/   cmpxchgl %edx, (%ecx)
+/   jne retry
+/   ret
+/
+    .text
+    .globl __PR_MD_ATOMIC_SET
+    .align 4
+__PR_MD_ATOMIC_SET:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    xchgl %eax, (%ecx)
+    ret
+
+/ PRInt32 __PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl __PR_MD_ATOMIC_ADD
+    .align 4
+__PR_MD_ATOMIC_ADD:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    movl %eax, %edx
+    lock
+    xaddl %eax, (%ecx)
+    addl %edx, %eax
+    ret
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2gc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2gc.c
new file mode 100644
index 0000000..d9f7646
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2gc.c
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * GC related routines
+ *
+ */
+#include "primpl.h"
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) 
+{
+    CONTEXTRECORD context;
+    context.ContextFlags = CONTEXT_INTEGER;
+
+    if (_PR_IS_NATIVE_THREAD(t)) {
+        context.ContextFlags |= CONTEXT_CONTROL;
+        if (QueryThreadContext(t->md.handle, CONTEXT_CONTROL, &context)) {
+            t->md.gcContext[0] = context.ctx_RegEax;
+            t->md.gcContext[1] = context.ctx_RegEbx;
+            t->md.gcContext[2] = context.ctx_RegEcx;
+            t->md.gcContext[3] = context.ctx_RegEdx;
+            t->md.gcContext[4] = context.ctx_RegEsi;
+            t->md.gcContext[5] = context.ctx_RegEdi;
+            t->md.gcContext[6] = context.ctx_RegEsp;
+            t->md.gcContext[7] = context.ctx_RegEbp;
+            *np = PR_NUM_GCREGS;
+        } else {
+            PR_ASSERT(0);/* XXX */
+        }
+    }
+    return (PRWord *)&t->md.gcContext;
+}
+
+/* This function is not used right now, but is left as a reference.
+ * If you ever need to get the fiberID from the currently running fiber, 
+ * this is it.
+ */
+void *
+GetMyFiberID()
+{
+    void *fiberData = 0;
+
+    /* A pointer to our tib entry is found at FS:[18]
+     * At offset 10h is the fiberData pointer.  The context of the 
+     * fiber is stored in there.  
+     */
+#ifdef HAVE_ASM
+    __asm {
+        mov    EDX, FS:[18h]
+        mov    EAX, DWORD PTR [EDX+10h]
+        mov    [fiberData], EAX
+    }
+#endif
+  
+    return fiberData;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2inrval.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2inrval.c
new file mode 100644
index 0000000..4006f5f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2inrval.c
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * OS/2 interval timers
+ *
+ */
+
+#include "primpl.h"
+
+static PRBool useHighResTimer = PR_FALSE;
+PRIntervalTime _os2_ticksPerSec = -1;
+PRIntn _os2_bitShift = 0;
+PRInt32 _os2_highMask = 0;
+   
+void
+_PR_MD_INTERVAL_INIT()
+{
+    char *envp;
+    ULONG timerFreq;
+    APIRET rc;
+
+    if ((envp = getenv("NSPR_OS2_NO_HIRES_TIMER")) != NULL) {
+        if (atoi(envp) == 1)
+           return;
+    }
+
+    timerFreq = 0; /* OS/2 high-resolution timer frequency in Hz */
+    rc = DosTmrQueryFreq(&timerFreq);
+    if (NO_ERROR == rc) {
+        useHighResTimer = PR_TRUE;
+        PR_ASSERT(timerFreq != 0);
+        while (timerFreq > PR_INTERVAL_MAX) {
+            timerFreq >>= 1;
+            _os2_bitShift++;
+            _os2_highMask = (_os2_highMask << 1)+1;
+        }
+
+        _os2_ticksPerSec = timerFreq;
+        PR_ASSERT(_os2_ticksPerSec > PR_INTERVAL_MIN);
+    }
+}
+
+PRIntervalTime
+_PR_MD_GET_INTERVAL()
+{
+    if (useHighResTimer) {
+        QWORD timestamp;
+        PRInt32 top;
+        APIRET rc = DosTmrQueryTime(&timestamp);
+        if (NO_ERROR != rc) {
+            return -1;
+        }
+        /* Sadly, nspr requires the interval to range from 1000 ticks per
+         * second to only 100000 ticks per second. DosTmrQueryTime is too
+         * high resolution...
+         */
+        top = timestamp.ulHi & _os2_highMask;
+        top = top << (32 - _os2_bitShift);
+        timestamp.ulLo = timestamp.ulLo >> _os2_bitShift;   
+        timestamp.ulLo = timestamp.ulLo + top; 
+        return (PRUint32)timestamp.ulLo;
+    } else {
+        ULONG msCount = -1;
+        DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msCount, sizeof(msCount));
+        return msCount;
+    }
+}
+
+PRIntervalTime
+_PR_MD_INTERVAL_PER_SEC()
+{
+    if (useHighResTimer) {
+        return _os2_ticksPerSec;
+    } else {
+        return 1000;
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2io.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2io.c
new file mode 100644
index 0000000..143698f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2io.c
@@ -0,0 +1,974 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* OS2 IO module
+ *
+ * Assumes synchronous I/O.
+ *
+ */
+
+#include "primpl.h"
+#include "prio.h"
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <io.h>
+
+struct _MDLock               _pr_ioq_lock;
+
+static PRBool isWSEB = PR_FALSE; /* whether we are using an OS/2 kernel that supports large files */
+
+typedef APIRET (*DosOpenLType)(PSZ pszFileName, PHFILE pHf, PULONG pulAction,
+                            LONGLONG cbFile, ULONG ulAttribute,
+                            ULONG fsOpenFlags, ULONG fsOpenMode,
+                            PEAOP2 peaop2);
+
+typedef APIRET (*DosSetFileLocksLType)(HFILE hFile, PFILELOCKL pflUnlock,
+                                    PFILELOCKL pflLock, ULONG timeout,
+                                    ULONG flags);
+
+typedef APIRET (*DosSetFilePtrLType)(HFILE hFile, LONGLONG ib, ULONG method,
+                                  PLONGLONG ibActual);
+
+DosOpenLType myDosOpenL;
+DosSetFileLocksLType myDosSetFileLocksL;
+DosSetFilePtrLType myDosSetFilePtrL;
+
+void
+_PR_MD_INIT_IO()
+{
+    APIRET rc;
+    HMODULE module;
+
+    sock_init();
+    
+    rc = DosLoadModule(NULL, 0, "DOSCALL1", &module);
+    if (rc != NO_ERROR)
+    {
+        return;
+    }
+    rc = DosQueryProcAddr(module, 981, NULL, (PFN*) &myDosOpenL);
+    if (rc != NO_ERROR)
+    {
+        return;
+    }
+    rc = DosQueryProcAddr(module, 986, NULL, (PFN*) &myDosSetFileLocksL);
+    if (rc != NO_ERROR)
+    {
+        return;
+    }
+    rc = DosQueryProcAddr(module, 988, NULL, (PFN*) &myDosSetFilePtrL);
+    if (rc != NO_ERROR)
+    {
+        return;
+    }
+    isWSEB = PR_TRUE;
+}
+
+PRStatus
+_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PRInt32 rv;
+    ULONG count;
+
+    PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+        SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks);
+    rv = DosWaitEventSem(thread->md.blocked_sema, msecs);
+    DosResetEventSem(thread->md.blocked_sema, &count); 
+    switch(rv) 
+    {
+        case NO_ERROR:
+            return PR_SUCCESS;
+            break;
+        case ERROR_TIMEOUT:
+            _PR_THREAD_LOCK(thread);
+            if (thread->state == _PR_IO_WAIT) {
+			  ;
+            } else {
+                if (thread->wait.cvar != NULL) {
+                    thread->wait.cvar = NULL;
+                    _PR_THREAD_UNLOCK(thread);
+                } else {
+                    /* The CVAR was notified just as the timeout
+                     * occurred.  This led to us being notified twice.
+                     * call SemRequest() to clear the semaphore.
+                     */
+                    _PR_THREAD_UNLOCK(thread);
+                    rv = DosWaitEventSem(thread->md.blocked_sema, 0);
+                    DosResetEventSem(thread->md.blocked_sema, &count); 
+                    PR_ASSERT(rv == NO_ERROR);
+                }
+            }
+            return PR_SUCCESS;
+            break;
+        default:
+            break;
+    }
+    return PR_FAILURE;
+}
+PRStatus
+_PR_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if ( _PR_IS_NATIVE_THREAD(thread) ) 
+    {
+        if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR)
+            return PR_FAILURE;
+        else
+			return PR_SUCCESS;
+	}
+}
+
+
+/* --- FILE IO ----------------------------------------------------------- */
+/*
+ *  _PR_MD_OPEN() -- Open a file
+ *
+ *  returns: a fileHandle
+ *
+ *  The NSPR open flags (osflags) are translated into flags for OS/2
+ *
+ *  Mode seems to be passed in as a unix style file permissions argument
+ *  as in 0666, in the case of opening the logFile. 
+ *
+ */
+PRInt32
+_PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
+{
+    HFILE file;
+    PRInt32 access = OPEN_SHARE_DENYNONE;
+    PRInt32 flags = 0L;
+    APIRET rc = 0;
+    PRUword actionTaken;
+
+#ifdef MOZ_OS2_HIGH_MEMORY
+    /*
+     * All the pointer arguments (&file, &actionTaken and name) have to be in
+     * low memory for DosOpen to use them.
+     * The following moves name to low memory.
+     */ 
+    if ((ULONG)name >= 0x20000000)
+    {
+        size_t len = strlen(name) + 1;
+        char *copy = (char *)alloca(len);
+        memcpy(copy, name, len);
+        name = copy;
+    }
+#endif
+
+    if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH;
+
+    if (osflags & PR_RDONLY)
+        access |= OPEN_ACCESS_READONLY;
+    else if (osflags & PR_WRONLY)
+        access |= OPEN_ACCESS_WRITEONLY;
+    else if(osflags & PR_RDWR)
+        access |= OPEN_ACCESS_READWRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+    {
+        flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
+    }
+    else if (osflags & PR_CREATE_FILE)
+    {
+        if (osflags & PR_TRUNCATE)
+            flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
+        else
+            flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
+    } 
+    else
+    {
+        if (osflags & PR_TRUNCATE)
+            flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
+        else
+            flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
+    }
+
+    do {
+        if (isWSEB)
+        {
+                rc = myDosOpenL((char*)name,
+                     &file,            /* file handle if successful */
+                     &actionTaken,     /* reason for failure        */
+                     0,                /* initial size of new file  */
+                     FILE_NORMAL,      /* file system attributes    */
+                     flags,            /* Open flags                */
+                     access,           /* Open mode and rights      */
+                     0);               /* OS/2 Extended Attributes  */
+        }
+        else
+        {
+                rc = DosOpen((char*)name,
+                     &file,            /* file handle if successful */
+                     &actionTaken,     /* reason for failure        */
+                     0,                /* initial size of new file  */
+                     FILE_NORMAL,      /* file system attributes    */
+                     flags,            /* Open flags                */
+                     access,           /* Open mode and rights      */
+                     0);               /* OS/2 Extended Attributes  */
+        };
+        if (rc == ERROR_TOO_MANY_OPEN_FILES) {
+            ULONG CurMaxFH = 0;
+            LONG ReqCount = 20;
+            APIRET rc2;
+            rc2 = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
+            if (rc2 != NO_ERROR) {
+                break;
+            }
+        }
+    } while (rc == ERROR_TOO_MANY_OPEN_FILES);
+
+    if (rc != NO_ERROR) {
+        _PR_MD_MAP_OPEN_ERROR(rc);
+        return -1; 
+    }
+
+    return (PRInt32)file;
+}
+
+PRInt32
+_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
+{
+    ULONG bytes;
+    int rv;
+
+    rv = DosRead((HFILE)fd->secret->md.osfd,
+                 (PVOID)buf,
+                 len,
+                 &bytes);
+    
+    if (rv != NO_ERROR) 
+    {
+        /* ERROR_HANDLE_EOF can only be returned by async io */
+        PR_ASSERT(rv != ERROR_HANDLE_EOF);
+        if (rv == ERROR_BROKEN_PIPE)
+            return 0;
+		else {
+			_PR_MD_MAP_READ_ERROR(rv);
+        return -1;
+    }
+    }
+    return (PRInt32)bytes;
+}
+
+PRInt32
+_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
+{
+    PRInt32 bytes;
+    int rv; 
+
+    rv = DosWrite((HFILE)fd->secret->md.osfd,
+                  (PVOID)buf,
+                  len,
+                  (PULONG)&bytes);
+
+    if (rv != NO_ERROR) 
+    {
+        _PR_MD_MAP_WRITE_ERROR(rv);
+        return -1;
+    }
+
+    if (len != bytes) {
+        rv = ERROR_DISK_FULL;
+        _PR_MD_MAP_WRITE_ERROR(rv);
+        return -1;
+    }
+
+    return bytes;
+} /* --- end _PR_MD_WRITE() --- */
+
+PRInt32
+_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
+{
+    PRInt32 rv;
+    PRUword newLocation;
+
+    rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation);
+
+	if (rv != NO_ERROR) {
+		_PR_MD_MAP_LSEEK_ERROR(rv);
+		return -1;
+	} else
+		return newLocation;
+}
+
+PRInt64
+_PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
+{
+#ifdef NO_LONG_LONG
+    PRInt64 result;
+    PRInt32 rv, low = offset.lo, hi = offset.hi;
+    PRUword newLocation;
+
+    rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation);
+    rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation);
+
+  	if (rv != NO_ERROR) {
+		_PR_MD_MAP_LSEEK_ERROR(rv);
+		hi = newLocation = -1;
+   }
+
+    result.lo = newLocation;
+    result.hi = hi;
+	return result;
+
+#else
+    PRInt32 where, rc, lo = (PRInt32)offset, hi = (PRInt32)(offset >> 32);
+    PRUint64 rv;
+    PRUint32 newLocation, uhi;
+    PRUint64 newLocationL;
+
+    switch (whence)
+      {
+      case PR_SEEK_SET:
+        where = FILE_BEGIN;
+        break;
+      case PR_SEEK_CUR:
+        where = FILE_CURRENT;
+        break;
+      case PR_SEEK_END:
+        where = FILE_END;
+        break;
+      default:
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+    if (isWSEB)
+    {
+        rc = myDosSetFilePtrL((HFILE)fd->secret->md.osfd, offset, where, (PLONGLONG)&newLocationL);
+    }
+    else
+    {
+        rc = DosSetFilePtr((HFILE)fd->secret->md.osfd, lo, where, (PULONG)&newLocation);
+    }
+     
+    if (rc != NO_ERROR) {
+      _PR_MD_MAP_LSEEK_ERROR(rc);
+      return -1;
+    }
+    
+    if (isWSEB)
+    {
+        return newLocationL;
+    }
+
+    uhi = (PRUint32)hi;
+    PR_ASSERT((PRInt32)uhi >= 0);
+    rv = uhi;
+    PR_ASSERT((PRInt64)rv >= 0);
+    rv = (rv << 32);
+    PR_ASSERT((PRInt64)rv >= 0);
+    rv += newLocation;
+    PR_ASSERT((PRInt64)rv >= 0);
+    return (PRInt64)rv;
+#endif
+}
+
+PRInt32
+_PR_MD_FSYNC(PRFileDesc *fd)
+{
+    PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd);
+
+    if (rc != NO_ERROR) {
+   	if (rc != ERROR_ACCESS_DENIED) {	
+   			_PR_MD_MAP_FSYNC_ERROR(rc);
+   	    return -1;
+   	}
+    }
+    return 0;
+}
+
+PRInt32
+_MD_CloseFile(PRInt32 osfd)
+{
+    PRInt32 rv;
+    
+    rv = DosClose((HFILE)osfd);
+ 	if (rv != NO_ERROR)
+		_PR_MD_MAP_CLOSE_ERROR(rv);
+    return rv;
+}
+
+
+/* --- DIR IO ------------------------------------------------------------ */
+#define GetFileFromDIR(d)       (isWSEB?(d)->d_entry.large.achName:(d)->d_entry.small.achName)
+#define GetFileAttr(d)          (isWSEB?(d)->d_entry.large.attrFile:(d)->d_entry.small.attrFile)
+
+void FlipSlashes(char *cp, int len)
+{
+    while (--len >= 0) {
+    if (cp[0] == '/') {
+        cp[0] = PR_DIRECTORY_SEPARATOR;
+    }
+    cp++;
+    }
+}
+
+/*
+**
+** Local implementations of standard Unix RTL functions which are not provided
+** by the VAC RTL.
+**
+*/
+
+PRInt32
+_PR_MD_CLOSE_DIR(_MDDir *d)
+{
+   PRInt32 rc;
+
+    if ( d ) {
+      rc = DosFindClose(d->d_hdl);
+      if(rc == NO_ERROR){
+        d->magic = (PRUint32)-1;
+        return PR_SUCCESS;
+		} else {
+			_PR_MD_MAP_CLOSEDIR_ERROR(rc);
+        	return PR_FAILURE;
+		}
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+}
+
+
+PRStatus
+_PR_MD_OPEN_DIR(_MDDir *d, const char *name)
+{
+    char filename[ CCHMAXPATH ];
+    PRUword numEntries, rc;
+
+    numEntries = 1;
+
+    PR_snprintf(filename, CCHMAXPATH, "%s%s%s",
+                name, PR_DIRECTORY_SEPARATOR_STR, "*.*");
+    FlipSlashes( filename, strlen(filename) );
+
+    d->d_hdl = HDIR_CREATE;
+
+    if (isWSEB)
+    {
+        rc = DosFindFirst( filename,
+                           &d->d_hdl,
+                           FILE_DIRECTORY | FILE_HIDDEN,
+                           &(d->d_entry.large),
+                           sizeof(d->d_entry.large),
+                           &numEntries,
+                           FIL_STANDARDL);
+    }
+    else
+    {
+        rc = DosFindFirst( filename,
+                           &d->d_hdl,
+                           FILE_DIRECTORY | FILE_HIDDEN,
+                           &(d->d_entry.small),
+                           sizeof(d->d_entry.small),
+                           &numEntries,
+                           FIL_STANDARD);
+    }
+    if ( rc != NO_ERROR ) {
+		_PR_MD_MAP_OPENDIR_ERROR(rc);
+        return PR_FAILURE;
+    }
+    d->firstEntry = PR_TRUE;
+    d->magic = _MD_MAGIC_DIR;
+    return PR_SUCCESS;
+}
+
+char *
+_PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
+{
+    PRUword numFiles = 1;
+    BOOL rv;
+    char *fileName;
+    USHORT fileAttr;
+
+    if ( d ) {
+       while (1) {
+           if (d->firstEntry) {
+               d->firstEntry = PR_FALSE;
+               rv = NO_ERROR;
+           } else {
+               rv = DosFindNext(d->d_hdl,
+                                &(d->d_entry),
+                                sizeof(d->d_entry),
+                                &numFiles);
+           }
+           if (rv != NO_ERROR) {
+               break;
+           }
+           fileName = GetFileFromDIR(d);
+           fileAttr = GetFileAttr(d);
+           if ( (flags & PR_SKIP_DOT) &&
+                (fileName[0] == '.') && (fileName[1] == '\0'))
+                continue;
+           if ( (flags & PR_SKIP_DOT_DOT) &&
+                (fileName[0] == '.') && (fileName[1] == '.') &&
+                (fileName[2] == '\0'))
+                continue;
+			/*
+			 * XXX
+			 * Is this the correct definition of a hidden file on OS/2?
+			 */
+           if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN))
+                return fileName;
+           else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN))
+                continue;
+           return fileName;
+        }
+        PR_ASSERT(NO_ERROR != rv);
+			_PR_MD_MAP_READDIR_ERROR(rv);
+        return NULL;
+		}
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;
+}
+
+PRInt32
+_PR_MD_DELETE(const char *name)
+{
+    PRInt32 rc = DosDelete((char*)name);
+    if(rc == NO_ERROR) {
+        return 0;
+    } else {
+		_PR_MD_MAP_DELETE_ERROR(rc);
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_STAT(const char *fn, struct stat *info)
+{
+    PRInt32 rv;
+    char filename[CCHMAXPATH];
+
+    PR_snprintf(filename, CCHMAXPATH, "%s", fn);
+    FlipSlashes(filename, strlen(filename));
+
+    rv = _stat((char*)filename, info);
+    if (-1 == rv) {
+        /*
+         * Check for MSVC runtime library _stat() bug.
+         * (It's really a bug in FindFirstFile().)
+         * If a pathname ends in a backslash or slash,
+         * e.g., c:\temp\ or c:/temp/, _stat() will fail.
+         * Note: a pathname ending in a slash (e.g., c:/temp/)
+         * can be handled by _stat() on NT but not on Win95.
+         *
+         * We remove the backslash or slash at the end and
+         * try again.  
+         *
+         * Not sure if this happens on OS/2 or not,
+         * but it doesn't hurt to be careful.
+         */
+
+        int len = strlen(fn);
+        if (len > 0 && len <= _MAX_PATH
+                && (fn[len - 1] == '\\' || fn[len - 1] == '/')) {
+            char newfn[_MAX_PATH + 1];
+
+            strcpy(newfn, fn);
+            newfn[len - 1] = '\0';
+            rv = _stat(newfn, info);
+        }
+    }
+
+    if (-1 == rv) {
+        _PR_MD_MAP_STAT_ERROR(errno);
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
+{
+    struct stat sb;
+    PRInt32 rv;
+    PRInt64 s, s2us;
+ 
+    if ( (rv = _PR_MD_STAT(fn, &sb)) == 0 ) {
+        if (info) {
+            if (S_IFREG & sb.st_mode)
+                info->type = PR_FILE_FILE ;
+            else if (S_IFDIR & sb.st_mode)
+                info->type = PR_FILE_DIRECTORY;
+            else
+                info->type = PR_FILE_OTHER;
+            info->size = sb.st_size;
+            LL_I2L(s2us, PR_USEC_PER_SEC);
+            LL_I2L(s, sb.st_mtime);
+            LL_MUL(s, s, s2us);
+            info->modifyTime = s;
+            LL_I2L(s, sb.st_ctime);
+            LL_MUL(s, s, s2us);
+            info->creationTime = s;
+        }
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
+{
+    PRFileInfo info32;
+    PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32);
+    if (rv != 0)
+    {
+        return rv;
+    }
+    info->type = info32.type;
+    LL_UI2L(info->size,info32.size);
+    info->modifyTime = info32.modifyTime;
+    info->creationTime = info32.creationTime;
+    
+    if (isWSEB)
+    {
+        APIRET rc ;
+        FILESTATUS3L fstatus;
+
+        rc = DosQueryPathInfo(fn, FIL_STANDARDL, &fstatus, sizeof(fstatus));
+
+        if (NO_ERROR != rc)
+        {
+            _PR_MD_MAP_OPEN_ERROR(rc);
+            return -1;
+        }
+
+        if (! (fstatus.attrFile & FILE_DIRECTORY))
+        {
+            info->size = fstatus.cbFile;
+        }
+    }
+
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
+{
+   /* For once, the VAC compiler/library did a nice thing.
+    * The file handle used by the C runtime is the same one
+    * returned by the OS when you call DosOpen().  This means
+    * that you can take an OS HFILE and use it with C file
+    * functions.  The only caveat is that you have to call
+    * _setmode() first to initialize some junk.  This is
+    * immensely useful because I did not have a clue how to
+    * implement this function otherwise.  The windows folks
+    * took the source from the Microsoft C library source, but
+    * IBM wasn't kind enough to ship the source with VAC.
+    * On second thought, the needed function could probably
+    * be gotten from the OS/2 GNU library source, but the
+    * point is now moot.
+    */
+   struct stat hinfo;
+    PRInt64 s, s2us;
+
+    _setmode(fd->secret->md.osfd, O_BINARY);
+    if(fstat((int)fd->secret->md.osfd, &hinfo) != NO_ERROR) {
+		_PR_MD_MAP_FSTAT_ERROR(errno);
+        return -1;
+	}
+
+    if (hinfo.st_mode & S_IFDIR)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_FILE;
+
+    info->size = hinfo.st_size;
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, hinfo.st_mtime);
+    LL_MUL(s, s, s2us);
+    info->modifyTime = s;
+    LL_I2L(s, hinfo.st_ctime);
+    LL_MUL(s, s, s2us);
+    info->creationTime = s;
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    PRFileInfo info32;
+    PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32);
+    if (0 == rv)
+    {
+       info->type = info32.type;
+       LL_UI2L(info->size,info32.size);
+    
+       info->modifyTime = info32.modifyTime;
+       info->creationTime = info32.creationTime;
+    }
+    
+    if (isWSEB)
+    {
+        APIRET rc ;
+        FILESTATUS3L fstatus;
+
+        rc = DosQueryFileInfo(fd->secret->md.osfd, FIL_STANDARDL, &fstatus, sizeof(fstatus));
+
+        if (NO_ERROR != rc)
+        {
+            _PR_MD_MAP_OPEN_ERROR(rc);
+            return -1;
+        }
+
+        if (! (fstatus.attrFile & FILE_DIRECTORY))
+        {
+            info->size = fstatus.cbFile;
+        }
+    }
+
+    return rv;
+}
+
+
+PRInt32
+_PR_MD_RENAME(const char *from, const char *to)
+{
+   PRInt32 rc;
+    /* Does this work with dot-relative pathnames? */
+    if ( (rc = DosMove((char *)from, (char *)to)) == NO_ERROR) {
+        return 0;
+    } else {
+		_PR_MD_MAP_RENAME_ERROR(rc);
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_ACCESS(const char *name, PRAccessHow how)
+{
+  PRInt32 rv;
+    switch (how) {
+      case PR_ACCESS_WRITE_OK:
+        rv = access(name, 02);
+		break;
+      case PR_ACCESS_READ_OK:
+        rv = access(name, 04);
+		break;
+      case PR_ACCESS_EXISTS:
+        return access(name, 00);
+	  	break;
+      default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+    }
+	if (rv < 0)
+		_PR_MD_MAP_ACCESS_ERROR(errno);
+    return rv;
+}
+
+PRInt32
+_PR_MD_MKDIR(const char *name, PRIntn mode)
+{
+   PRInt32 rc;
+    /* XXXMB - how to translate the "mode"??? */
+    if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) {
+        return 0;
+    } else {
+		_PR_MD_MAP_MKDIR_ERROR(rc);
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_RMDIR(const char *name)
+{
+   PRInt32 rc;
+    if ( (rc = DosDeleteDir((char *)name)) == NO_ERROR) {
+        return 0;
+    } else {
+		_PR_MD_MAP_RMDIR_ERROR(rc);
+        return -1;
+    }
+}
+
+PRStatus
+_PR_MD_LOCKFILE(PRInt32 f)
+{
+    PRInt32   rv;
+    FILELOCK lock, unlock;
+    FILELOCKL lockL, unlockL;
+    
+    lock.lOffset = 0;
+    lockL.lOffset = 0;
+    lock.lRange = 0xffffffff;
+    lockL.lRange =  0xffffffffffffffff;
+    unlock.lOffset = 0;
+    unlock.lRange = 0;
+    unlockL.lOffset = 0;
+    unlockL.lRange = 0;
+
+    /*
+     * loop trying to DosSetFileLocks(),
+     * pause for a few miliseconds when can't get the lock
+     * and try again
+     */
+    for( rv = FALSE; rv == FALSE; /* do nothing */ )
+    {
+        if (isWSEB)
+        {
+	    rv = myDosSetFileLocksL( (HFILE) f,
+			                    &unlockL, &lockL,
+			                    0, 0);
+        }
+        else
+        {
+	    rv = DosSetFileLocks( (HFILE) f,
+			                    &unlock, &lock,
+			                    0, 0);
+        }
+		if ( rv != NO_ERROR )
+        {
+            DosSleep( 50 );  /* Sleep() a few milisecs and try again. */
+        }            
+    } /* end for() */
+    return PR_SUCCESS;
+} /* end _PR_MD_LOCKFILE() */
+
+PRStatus
+_PR_MD_TLOCKFILE(PRInt32 f)
+{
+    return _PR_MD_LOCKFILE(f);
+} /* end _PR_MD_TLOCKFILE() */
+
+
+PRStatus
+_PR_MD_UNLOCKFILE(PRInt32 f)
+{
+    PRInt32   rv;
+    FILELOCK lock, unlock;
+    FILELOCKL lockL, unlockL;
+    
+    lock.lOffset = 0;
+    lockL.lOffset = 0;
+    lock.lRange = 0;
+    lockL.lRange = 0;
+    unlock.lOffset = 0;
+    unlockL.lOffset = 0;
+    unlock.lRange = 0xffffffff;
+    unlockL.lRange = 0xffffffffffffffff;
+    
+    if (isWSEB)
+    {
+        rv = myDosSetFileLocksL( (HFILE) f,
+                                        &unlockL, &lockL,
+                                        0, 0);
+    }
+    else
+    {
+        rv = DosSetFileLocks( (HFILE) f,
+                                    &unlock, &lock,
+                                    0, 0);
+    }
+            
+    if ( rv != NO_ERROR )
+    {
+        return PR_SUCCESS;
+    }
+    else
+    {
+        return PR_FAILURE;
+    }
+} /* end _PR_MD_UNLOCKFILE() */
+
+PRStatus
+_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
+{
+    APIRET rc = 0;
+    ULONG flags;
+    switch (fd->methods->file_type)
+    {
+        case PR_DESC_PIPE:
+        case PR_DESC_FILE:
+            rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags);
+            if (rc != NO_ERROR) {
+                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+                return PR_FAILURE;
+            }
+
+            if (inheritable)
+              flags &= ~OPEN_FLAGS_NOINHERIT;
+            else
+              flags |= OPEN_FLAGS_NOINHERIT;
+
+            /* Mask off flags DosSetFHState don't want. */
+            flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT);
+            rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags);
+            if (rc != NO_ERROR) {
+                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+                return PR_FAILURE;
+            }
+            break;
+
+        case PR_DESC_LAYERED:
+            /* what to do here? */
+            PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/);
+            return PR_FAILURE;
+
+        case PR_DESC_SOCKET_TCP:
+        case PR_DESC_SOCKET_UDP:
+            /* These are global on OS/2. */
+            break;
+    }
+
+    return PR_SUCCESS;
+}
+
+void
+_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
+{
+    /* XXX this function needs to be implemented */
+    fd->secret->inheritable = _PR_TRI_UNKNOWN;
+}
+
+void
+_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
+{
+    /* XXX this function needs to be reviewed */
+    ULONG flags;
+
+    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+    if (DosQueryFHState((HFILE)fd->secret->md.osfd, &flags) == 0) {
+        if (flags & OPEN_FLAGS_NOINHERIT) {
+            fd->secret->inheritable = _PR_TRI_FALSE;
+        } else {
+            fd->secret->inheritable = _PR_TRI_TRUE;
+        }
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2misc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2misc.c
new file mode 100644
index 0000000..05e0f2f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2misc.c
@@ -0,0 +1,653 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Davide Bresolin <davide@teamos2.it>
+ *   Rich Walsh <dragtext@e-vertise.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * os2misc.c
+ *
+ */
+
+#ifdef MOZ_OS2_HIGH_MEMORY
+/* os2safe.h has to be included before os2.h, needed for high mem */
+#include <os2safe.h>
+#endif
+
+#include <string.h>
+#include "primpl.h"
+
+extern int   _CRT_init(void);
+extern void  _CRT_term(void);
+extern void __ctordtorInit(int flag);
+extern void __ctordtorTerm(int flag);
+
+char *
+_PR_MD_GET_ENV(const char *name)
+{
+    return getenv(name);
+}
+
+PRIntn
+_PR_MD_PUT_ENV(const char *name)
+{
+    return putenv(name);
+}
+
+
+/*
+ **************************************************************************
+ **************************************************************************
+ **
+ **     Date and time routines
+ **
+ **************************************************************************
+ **************************************************************************
+ */
+
+#include <sys/timeb.h>
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the
+ *     implementation for OS/2.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+    PRInt64 s, ms, ms2us, s2us;
+    struct timeb b;
+
+    ftime(&b);
+    LL_I2L(ms2us, PR_USEC_PER_MSEC);
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, b.time);
+    LL_I2L(ms, b.millitm);
+    LL_MUL(ms, ms, ms2us);
+    LL_MUL(s, s, s2us);
+    LL_ADD(s, s, ms);
+    return s;       
+}
+
+
+/*
+ ***********************************************************************
+ ***********************************************************************
+ *
+ * Process creation routines
+ *
+ ***********************************************************************
+ ***********************************************************************
+ */
+
+/*
+ * Assemble the command line by concatenating the argv array.
+ * Special characters intentionally do not get escaped, and it is
+ * expected that the caller wraps arguments in quotes if needed
+ * (e.g. for filename with spaces).
+ *
+ * On success, this function returns 0 and the resulting command
+ * line is returned in *cmdLine.  On failure, it returns -1.
+ */
+static int assembleCmdLine(char *const *argv, char **cmdLine)
+{
+    char *const *arg;
+    int cmdLineSize;
+
+    /*
+     * Find out how large the command line buffer should be.
+     */
+    cmdLineSize = 1; /* final null */
+    for (arg = argv+1; *arg; arg++) {
+        cmdLineSize += strlen(*arg) + 1; /* space in between */
+    }
+    *cmdLine = PR_MALLOC(cmdLineSize);
+    if (*cmdLine == NULL) {
+        return -1;
+    }
+
+    (*cmdLine)[0] = '\0';
+
+    for (arg = argv+1; *arg; arg++) {
+        if (arg > argv +1) {
+            strcat(*cmdLine, " ");
+        }
+        strcat(*cmdLine, *arg);
+    } 
+    return 0;
+}
+
+/*
+ * Assemble the environment block by concatenating the envp array
+ * (preserving the terminating null byte in each array element)
+ * and adding a null byte at the end.
+ *
+ * Returns 0 on success.  The resulting environment block is returned
+ * in *envBlock.  Note that if envp is NULL, a NULL pointer is returned
+ * in *envBlock.  Returns -1 on failure.
+ */
+static int assembleEnvBlock(char **envp, char **envBlock)
+{
+    char *p;
+    char *q;
+    char **env;
+    char *curEnv;
+    char *cwdStart, *cwdEnd;
+    int envBlockSize;
+
+    PPIB ppib = NULL;
+    PTIB ptib = NULL;
+
+    if (envp == NULL) {
+        *envBlock = NULL;
+        return 0;
+    }
+
+    if(DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR)
+       return -1;
+
+    curEnv = ppib->pib_pchenv;
+
+    cwdStart = curEnv;
+    while (*cwdStart) {
+        if (cwdStart[0] == '=' && cwdStart[1] != '\0'
+                && cwdStart[2] == ':' && cwdStart[3] == '=') {
+            break;
+        }
+        cwdStart += strlen(cwdStart) + 1;
+    }
+    cwdEnd = cwdStart;
+    if (*cwdEnd) {
+        cwdEnd += strlen(cwdEnd) + 1;
+        while (*cwdEnd) {
+            if (cwdEnd[0] != '=' || cwdEnd[1] == '\0'
+                    || cwdEnd[2] != ':' || cwdEnd[3] != '=') {
+                break;
+            }
+            cwdEnd += strlen(cwdEnd) + 1;
+        }
+    }
+    envBlockSize = cwdEnd - cwdStart;
+
+    for (env = envp; *env; env++) {
+        envBlockSize += strlen(*env) + 1;
+    }
+    envBlockSize++;
+
+    p = *envBlock = PR_MALLOC(envBlockSize);
+    if (p == NULL) {
+        return -1;
+    }
+
+    q = cwdStart;
+    while (q < cwdEnd) {
+        *p++ = *q++;
+    }
+
+    for (env = envp; *env; env++) {
+        q = *env;
+        while (*q) {
+            *p++ = *q++;
+        }
+        *p++ = '\0';
+    }
+    *p = '\0';
+    return 0;
+}
+
+/*
+ * For qsort.  We sort (case-insensitive) the environment strings
+ * before generating the environment block.
+ */
+static int compare(const void *arg1, const void *arg2)
+{
+    return stricmp(* (char**)arg1, * (char**)arg2);
+}
+
+PRProcess * _PR_CreateOS2Process(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    PRProcess *proc = NULL;
+    char *cmdLine = NULL;
+    char **newEnvp = NULL;
+    char *envBlock = NULL;
+   
+    STARTDATA startData = {0};
+    APIRET    rc;
+    ULONG     ulAppType = 0;
+    PID       pid = 0;
+    char     *pszComSpec;
+    char      pszEXEName[CCHMAXPATH] = "";
+    char      pszFormatString[CCHMAXPATH];
+    char      pszObjectBuffer[CCHMAXPATH];
+    char     *pszFormatResult = NULL;
+
+    /*
+     * Variables for DosExecPgm
+     */
+    char szFailed[CCHMAXPATH];
+    char *pszCmdLine = NULL;
+    RESULTCODES procInfo;
+    HFILE hStdIn  = 0,
+          hStdOut = 0,
+          hStdErr = 0;
+    HFILE hStdInSave  = -1,
+          hStdOutSave = -1,
+          hStdErrSave = -1;
+
+    proc = PR_NEW(PRProcess);
+    if (!proc) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+   
+    if (assembleCmdLine(argv, &cmdLine) == -1) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+#ifdef MOZ_OS2_HIGH_MEMORY
+    /*
+     * DosQueryAppType() fails if path (the char* in the first argument) is in
+     * high memory. If that is the case, the following moves it to low memory.
+     */ 
+    if ((ULONG)path >= 0x20000000) {
+        size_t len = strlen(path) + 1;
+        char *copy = (char *)alloca(len);
+        memcpy(copy, path, len);
+        path = copy;
+    }
+#endif
+   
+    if (envp == NULL) {
+        newEnvp = NULL;
+    } else {
+        int i;
+        int numEnv = 0;
+        while (envp[numEnv]) {
+            numEnv++;
+        }
+        newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *));
+        for (i = 0; i <= numEnv; i++) {
+            newEnvp[i] = envp[i];
+        }
+        qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
+    }
+    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+  
+    rc = DosQueryAppType(path, &ulAppType);
+    if (rc != NO_ERROR) {
+       char *pszDot = strrchr(path, '.');
+       if (pszDot) {
+          /* If it is a CMD file, launch the users command processor */
+          if (!stricmp(pszDot, ".cmd")) {
+             rc = DosScanEnv("COMSPEC", (PSZ *)&pszComSpec);
+             if (!rc) {
+                strcpy(pszFormatString, "/C %s %s");
+                strcpy(pszEXEName, pszComSpec);
+                ulAppType = FAPPTYP_WINDOWCOMPAT;
+             }
+          }
+       }
+    }
+    if (ulAppType == 0) {
+       PR_SetError(PR_UNKNOWN_ERROR, 0);
+       goto errorExit;
+    }
+ 
+    if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) {
+        startData.SessionType = SSF_TYPE_PM;
+    }
+    else if (ulAppType & FAPPTYP_WINDOWCOMPAT) {
+        startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
+    }
+    else {
+        startData.SessionType = SSF_TYPE_DEFAULT;
+    }
+ 
+    if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))
+    {
+        strcpy(pszEXEName, "WINOS2.COM");
+        startData.SessionType = PROG_31_STDSEAMLESSVDM;
+        strcpy(pszFormatString, "/3 %s %s");
+    }
+ 
+    startData.InheritOpt = SSF_INHERTOPT_SHELL;
+ 
+    if (pszEXEName[0]) {
+        pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));
+        sprintf(pszFormatResult, pszFormatString, path, cmdLine);
+        startData.PgmInputs = pszFormatResult;
+    } else {
+        strcpy(pszEXEName, path);
+        startData.PgmInputs = cmdLine;
+    }
+    startData.PgmName = pszEXEName;
+ 
+    startData.Length = sizeof(startData);
+    startData.Related = SSF_RELATED_INDEPENDENT;
+    startData.ObjectBuffer = pszObjectBuffer;
+    startData.ObjectBuffLen = CCHMAXPATH;
+    startData.Environment = envBlock;
+ 
+    if (attr) {
+        /* On OS/2, there is really no way to pass file handles for stdin,
+         * stdout, and stderr to a new process.  Instead, we can make it
+         * a child process and make the given file handles a copy of our
+         * stdin, stdout, and stderr.  The child process then inherits
+         * ours, and we set ours back.  Twisted and gross I know. If you
+         * know a better way, please use it.
+         */
+        if (attr->stdinFd) {
+            hStdIn = 0;
+            DosDupHandle(hStdIn, &hStdInSave);
+            DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn);
+        }
+
+        if (attr->stdoutFd) {
+            hStdOut = 1;
+            DosDupHandle(hStdOut, &hStdOutSave);
+            DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut);
+        }
+
+        if (attr->stderrFd) {
+            hStdErr = 2;
+            DosDupHandle(hStdErr, &hStdErrSave);
+            DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr);
+        }
+        /*
+         * Build up the Command Line for DosExecPgm
+         */
+        pszCmdLine = PR_MALLOC(strlen(pszEXEName) +
+                               strlen(startData.PgmInputs) + 3);
+        sprintf(pszCmdLine, "%s%c%s%c", pszEXEName, '\0',
+                startData.PgmInputs, '\0');
+        rc = DosExecPgm(szFailed,
+                        CCHMAXPATH,
+                        EXEC_ASYNCRESULT,
+                        pszCmdLine,
+                        envBlock,
+                        &procInfo,
+                        pszEXEName);
+        PR_DELETE(pszCmdLine);
+
+        /* Restore our old values.  Hope this works */
+        if (hStdInSave != -1) {
+            DosDupHandle(hStdInSave, &hStdIn);
+            DosClose(hStdInSave);
+        }
+
+        if (hStdOutSave != -1) {
+            DosDupHandle(hStdOutSave, &hStdOut);
+            DosClose(hStdOutSave);
+        }
+
+        if (hStdErrSave != -1) {
+            DosDupHandle(hStdErrSave, &hStdErr);
+            DosClose(hStdErrSave);
+        }
+
+        if (rc != NO_ERROR) {
+            /* XXX what error code? */
+            PR_SetError(PR_UNKNOWN_ERROR, rc);
+            goto errorExit;
+        }
+
+        proc->md.pid = procInfo.codeTerminate;
+    } else {	
+        /*
+         * If no STDIN/STDOUT redirection is not needed, use DosStartSession
+         * to create a new, independent session
+         */
+        rc = DosStartSession(&startData, &ulAppType, &pid);
+
+        if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {
+            PR_SetError(PR_UNKNOWN_ERROR, rc);
+            goto errorExit;
+        }
+ 
+        proc->md.pid = pid;
+    }
+
+    if (pszFormatResult) {
+        PR_DELETE(pszFormatResult);
+    }
+
+    PR_DELETE(cmdLine);
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+    if (envBlock) {
+        PR_DELETE(envBlock);
+    }
+    return proc;
+
+errorExit:
+    if (cmdLine) {
+        PR_DELETE(cmdLine);
+    }
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+    if (envBlock) {
+        PR_DELETE(envBlock);
+    }
+    if (proc) {
+        PR_DELETE(proc);
+    }
+    return NULL;
+}  /* _PR_CreateOS2Process */
+
+PRStatus _PR_DetachOS2Process(PRProcess *process)
+{
+    /* On OS/2, a process is either created as a child or not. 
+     * You can't 'detach' it later on.
+     */
+    PR_DELETE(process);
+    return PR_SUCCESS;
+}
+
+/*
+ * XXX: This will currently only work on a child process.
+ */
+PRStatus _PR_WaitOS2Process(PRProcess *process,
+    PRInt32 *exitCode)
+{
+    ULONG ulRetVal;
+    RESULTCODES results;
+    PID pidEnded = 0;
+
+    ulRetVal = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, 
+                            &results,
+                            &pidEnded, process->md.pid);
+
+    if (ulRetVal != NO_ERROR) {
+       printf("\nDosWaitChild rc = %lu\n", ulRetVal);
+        PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
+        return PR_FAILURE;
+    }
+    PR_DELETE(process);
+    return PR_SUCCESS;
+}
+
+PRStatus _PR_KillOS2Process(PRProcess *process)
+{
+   ULONG ulRetVal;
+    if ((ulRetVal = DosKillProcess(DKP_PROCESS, process->md.pid)) == NO_ERROR) {
+	return PR_SUCCESS;
+    }
+    PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
+    return PR_FAILURE;
+}
+
+PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen)
+{
+    PRIntn rv;
+
+    rv = gethostname(name, (PRInt32) namelen);
+    if (0 == rv) {
+        return PR_SUCCESS;
+    }
+	_PR_MD_MAP_GETHOSTNAME_ERROR(sock_errno());
+    return PR_FAILURE;
+}
+
+void
+_PR_MD_WAKEUP_CPUS( void )
+{
+    return;
+}    
+
+/*
+ **********************************************************************
+ *
+ * Memory-mapped files
+ *
+ * A credible emulation of memory-mapped i/o on OS/2 would require
+ * an exception-handler on each thread that might access the mapped
+ * memory.  In the Mozilla environment, that would be impractical.
+ * Instead, the following simulates those modes which don't modify
+ * the mapped file.  It reads the entire mapped file segment at once
+ * when MemMap is called, and frees it on MemUnmap.  CreateFileMap
+ * only does sanity-checks, while CloseFileMap does almost nothing.
+ *
+ **********************************************************************
+ */
+
+PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
+{
+    PRFileInfo64 info;
+
+    /* assert on PR_PROT_READWRITE which modifies the underlying file */
+    PR_ASSERT(fmap->prot == PR_PROT_READONLY ||
+              fmap->prot == PR_PROT_WRITECOPY);
+    if (fmap->prot != PR_PROT_READONLY &&
+        fmap->prot != PR_PROT_WRITECOPY) {
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (PR_GetOpenFileInfo64(fmap->fd, &info) == PR_FAILURE) {
+        return PR_FAILURE;
+    }
+    /* reject zero-byte mappings & zero-byte files */
+    if (!size || !info.size) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    /* file size rounded up to the next page boundary */
+    fmap->md.maxExtent = (info.size + 0xfff) & ~(0xfff);
+
+    return PR_SUCCESS;
+}
+
+PRInt32 _MD_GetMemMapAlignment(void)
+{
+    /* OS/2 pages are 4k */
+    return 0x1000;
+}
+
+void * _MD_MemMap(PRFileMap *fmap, PROffset64 offset, PRUint32 len)
+{
+    PRUint32 rv;
+    void *addr;
+
+    /* prevent mappings beyond EOF + remainder of page */
+    if (offset + len > fmap->md.maxExtent) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return NULL;
+    }
+    if (PR_Seek64(fmap->fd, offset, PR_SEEK_SET) == -1) {
+        return NULL;
+    }
+    /* try for high memory, fall back to low memory if hi-mem fails */
+    rv = DosAllocMem(&addr, len, OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE);
+    if (rv) {
+        rv = DosAllocMem(&addr, len, PAG_COMMIT | PAG_READ | PAG_WRITE);
+        if (rv) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, rv);
+            return NULL;
+        }
+    }
+    if (PR_Read(fmap->fd, addr, len) == -1) {
+        DosFreeMem(addr);
+        return NULL;
+    }
+    /* don't permit writes if readonly */
+    if (fmap->prot == PR_PROT_READONLY) {
+        rv = DosSetMem(addr, len, PAG_READ);
+        if (rv) {
+            DosFreeMem(addr);
+            PR_SetError(PR_UNKNOWN_ERROR, rv);
+            return NULL;
+        }
+    }
+    return addr;
+}
+
+PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
+{
+    PRUint32 rv;
+
+    /* we just have to trust that addr & len are those used by MemMap */
+    rv = DosFreeMem(addr);
+    if (rv) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _MD_CloseFileMap(PRFileMap *fmap)
+{
+    /* nothing to do except free the PRFileMap struct */
+    PR_Free(fmap);
+    return PR_SUCCESS;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2poll.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2poll.c
new file mode 100644
index 0000000..6432032
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2poll.c
@@ -0,0 +1,380 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This file implements _PR_MD_PR_POLL for OS/2.
+ */
+
+#include <sys/time.h> /* For timeval. */
+
+#include "primpl.h"
+
+#ifndef BSD_SELECT
+/* Utility functions called when using OS/2 select */
+
+PRBool IsSocketSet( PRInt32 osfd, int* socks, int start, int count )
+{
+  int i;
+  PRBool isSet = PR_FALSE;
+
+  for( i = start; i < start+count; i++ )
+  {
+    if( socks[i] == osfd )
+      isSet = PR_TRUE;
+  }
+  
+  return isSet; 
+}
+#endif
+
+PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+#ifdef BSD_SELECT
+    fd_set rd, wt, ex;
+#else
+    int rd, wt, ex;
+    int* socks;
+    unsigned long msecs;
+    int i, j;
+#endif
+    PRFileDesc *bottom;
+    PRPollDesc *pd, *epd;
+    PRInt32 maxfd = -1, ready, err;
+    PRIntervalTime remaining, elapsed, start;
+
+#ifdef BSD_SELECT
+    struct timeval tv, *tvp = NULL;
+
+    FD_ZERO(&rd);
+    FD_ZERO(&wt);
+    FD_ZERO(&ex);
+#else
+    rd = 0;
+    wt = 0;
+    ex = 0;
+    socks = (int) PR_MALLOC( npds * 3 * sizeof(int) );
+    
+    if (!socks)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+#endif
+
+    ready = 0;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            if (pd->in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+            }
+            if (pd->in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read)) ||
+                (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one's ready right now */
+                if (0 == ready)
+                {
+                    /*
+                     * We will have to return without calling the
+                     * system poll/select function.  So zero the
+                     * out_flags fields of all the poll descriptors
+                     * before this one.
+                     */
+                    PRPollDesc *prev;
+                    for (prev = pds; prev < pd; prev++)
+                    {
+                        prev->out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pd->out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pd->out_flags = 0;  /* pre-condition */
+
+                /* make sure this is an NSPR supported stack */
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom) &&
+                    (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        PRInt32 osfd = bottom->secret->md.osfd;
+                        if (osfd > maxfd) 
+                            maxfd = osfd;
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &rd);
+#else
+                            socks[rd] = osfd;
+                            rd++;              
+#endif
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &wt);
+#else
+                            socks[npds+wt] = osfd;
+                            wt++;              
+#endif
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &rd);
+#else
+                            socks[rd] = osfd;
+                            rd++;              
+#endif
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &wt);
+#else
+                            socks[npds+wt] = osfd;
+                            wt++;              
+#endif
+                        }
+                        if (pd->in_flags & PR_POLL_EXCEPT)
+                        {
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &ex);
+#else
+                            socks[npds*2+ex] = osfd;
+                            ex++;
+#endif
+                        }
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        PRPollDesc *prev;
+                        for (prev = pds; prev < pd; prev++)
+                        {
+                            prev->out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+        else
+        {
+            pd->out_flags = 0;
+        }
+    }
+
+    if (0 != ready)
+    {
+#ifndef BSD_SELECT
+        PR_Free(socks);
+#endif
+        return ready;  /* no need to block */
+    }
+
+    remaining = timeout;
+    start = PR_IntervalNow();
+
+retry:
+#ifdef BSD_SELECT
+    if (timeout != PR_INTERVAL_NO_TIMEOUT)
+    {
+        PRInt32 ticksPerSecond = PR_TicksPerSecond();
+        tv.tv_sec = remaining / ticksPerSecond;
+        tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
+        tvp = &tv;
+    }
+
+    ready = bsdselect(maxfd + 1, &rd, &wt, &ex, tvp);
+#else
+    switch (timeout)
+    {
+        case PR_INTERVAL_NO_WAIT:
+            msecs = 0;
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            msecs = -1;
+            break;
+        default:
+            msecs = PR_IntervalToMilliseconds(remaining);
+    }
+
+     /* compact array */
+    for( i = rd, j = npds; j < npds+wt; i++,j++ )
+        socks[i] = socks[j];
+    for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ )
+        socks[i] = socks[j];
+    
+    ready = os2_select(socks, rd, wt, ex, msecs);
+#endif
+
+    if (ready == -1 && errno == EINTR)
+    {
+        if (timeout == PR_INTERVAL_NO_TIMEOUT)
+            goto retry;
+        else
+        {
+            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+            if (elapsed > timeout)
+                ready = 0;  /* timed out */
+            else
+            {
+                remaining = timeout - elapsed;
+                goto retry;
+            }
+        }
+    }
+
+    /*
+    ** Now to unravel the select sets back into the client's poll
+    ** descriptor list. Is this possibly an area for pissing away
+    ** a few cycles or what?
+    */
+    if (ready > 0)
+    {
+        ready = 0;
+        for (pd = pds, epd = pd + npds; pd < epd; pd++)
+        {
+            PRInt16 out_flags = 0;
+            if ((NULL != pd->fd) && (0 != pd->in_flags))
+            {
+                PRInt32 osfd;
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);
+
+                osfd = bottom->secret->md.osfd;
+
+#ifdef BSD_SELECT
+                if (FD_ISSET(osfd, &rd))
+#else
+                if( IsSocketSet(osfd, socks, 0, rd) )        
+#endif
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+
+#ifdef BSD_SELECT
+                if (FD_ISSET(osfd, &wt))
+#else
+                if( IsSocketSet(osfd, socks, rd, wt) )        
+#endif
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+
+#ifdef BSD_SELECT
+                if (FD_ISSET(osfd, &ex))
+#else
+                if( IsSocketSet(osfd, socks, rd+wt, ex) )        
+#endif
+                {
+                    out_flags |= PR_POLL_EXCEPT;
+                }
+            }
+            pd->out_flags = out_flags;
+            if (out_flags) ready++;
+        }
+        PR_ASSERT(ready > 0);
+    }
+    else if (ready < 0)
+    {
+        err = _MD_ERRNO();
+        if (err == EBADF)
+        {
+            /* Find the bad fds */
+            int optval;
+            int optlen = sizeof(optval);
+            ready = 0;
+            for (pd = pds, epd = pd + npds; pd < epd; pd++)
+            {
+                pd->out_flags = 0;
+                if ((NULL != pd->fd) && (0 != pd->in_flags))
+                {
+                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                    if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
+                        SO_TYPE, (char *) &optval, &optlen) == -1)
+                    {
+                        PR_ASSERT(sock_errno() == ENOTSOCK);
+                        if (sock_errno() == ENOTSOCK)
+                        {
+                            pd->out_flags = PR_POLL_NVAL;
+                            ready++;
+                        }
+                    }
+                }
+            }
+            PR_ASSERT(ready > 0);
+        }
+        else
+            _PR_MD_MAP_SELECT_ERROR(err);
+    }
+
+#ifndef BSD_SELECT
+    PR_Free(socks);
+#endif
+    return ready;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2rng.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2rng.c
new file mode 100644
index 0000000..1c3a7b7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2rng.c
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#define INCL_DOS
+#define INCL_DOSERRORS
+#include <os2.h>
+#include <stdlib.h>
+#include <time.h>
+#include "primpl.h"
+
+static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow)
+{
+    APIRET rc = NO_ERROR;
+    QWORD qword = {0,0};
+
+    rc = DosTmrQueryTime(&qword);
+    if (rc != NO_ERROR)
+       return FALSE;
+
+    *phigh = qword.ulHi;
+    *plow  = qword.ulLo;
+
+    return TRUE;
+}
+
+extern PRSize _PR_MD_GetRandomNoise(void *buf, PRSize size )
+{
+    unsigned long high = 0;
+    unsigned long low  = 0;
+    clock_t val = 0;
+    int n = 0;
+    int nBytes = 0;
+    time_t sTime;
+
+    if (size <= 0)
+       return 0;
+
+    clockTickTime(&high, &low);
+
+    /* get the maximally changing bits first */
+    nBytes = sizeof(low) > size ? size : sizeof(low);
+    memcpy(buf, &low, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+       return n;
+
+    nBytes = sizeof(high) > size ? size : sizeof(high);
+    memcpy(((char *)buf) + n, &high, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+       return n;
+
+    /* get the number of milliseconds that have elapsed since application started */
+    val = clock();
+
+    nBytes = sizeof(val) > size ? size : sizeof(val);
+    memcpy(((char *)buf) + n, &val, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+       return n;
+
+    /* get the time in seconds since midnight Jan 1, 1970 */
+    time(&sTime);
+    nBytes = sizeof(sTime) > size ? size : sizeof(sTime);
+    memcpy(((char *)buf) + n, &sTime, nBytes);
+    n += nBytes;
+
+    return n;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2sem.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2sem.c
new file mode 100644
index 0000000..20b57a8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2sem.c
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * OS/2-specific semaphore handling code.
+ *
+ */
+
+#include "primpl.h"
+
+
+void
+_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value)
+{
+   int rv;
+
+    /* Our Sems don't support a value > 1 */
+    PR_ASSERT(value <= 1);
+
+    rv = DosCreateEventSem(NULL, &md->sem, 0, 0);
+    PR_ASSERT(rv == NO_ERROR);
+}
+
+void
+_PR_MD_DESTROY_SEM(_MDSemaphore *md)
+{
+   int rv;
+   rv = DosCloseEventSem(md->sem);
+   PR_ASSERT(rv == NO_ERROR);
+
+}
+
+PRStatus
+_PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks)
+{
+    int rv;
+    rv = DosWaitEventSem(md->sem, PR_IntervalToMilliseconds(ticks));
+
+    if (rv == NO_ERROR)
+        return PR_SUCCESS;
+    else
+        return PR_FAILURE;
+}
+
+PRStatus
+_PR_MD_WAIT_SEM(_MDSemaphore *md)
+{
+    return _PR_MD_TIMED_WAIT_SEM(md, PR_INTERVAL_NO_TIMEOUT);
+}
+
+void
+_PR_MD_POST_SEM(_MDSemaphore *md)
+{
+   int rv;
+   rv = DosPostEventSem(md->sem);
+   PR_ASSERT(rv == NO_ERROR); 
+}
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2sock.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2sock.c
new file mode 100644
index 0000000..6a7e3dc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2sock.c
@@ -0,0 +1,686 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* OS/2 Sockets module
+ *
+ */
+
+/*Note from DSR111297 - it should be noted that there are two flavors of select() on OS/2    */
+/*There is standard BSD (which is kind of slow) and a new flavor of select() that takes      */
+/*an integer list of sockets, the number of read sockets, write sockets, except sockets, and */
+/*a millisecond count for timeout. In the interest of performance I have choosen the OS/2    */
+/*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info.          */ 
+
+#include "primpl.h"
+
+#include <sys/time.h> /* For timeval. */
+
+#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
+#define READ_FD   1
+#define WRITE_FD  2
+
+/* --- SOCKET IO --------------------------------------------------------- */
+
+
+PRInt32
+_PR_MD_SOCKET(int domain, int type, int flags)
+{
+    PRInt32 osfd, err;
+
+    osfd = socket(domain, type, flags);
+
+    if (osfd == -1) 
+    {
+        err = sock_errno();
+        _PR_MD_MAP_SOCKET_ERROR(err);
+    }
+
+    return(osfd);
+}
+
+/*
+** _MD_CloseSocket() -- Close a socket
+**
+*/
+PRInt32
+_MD_CloseSocket(PRInt32 osfd)
+{
+    PRInt32 rv, err;
+
+    rv = soclose(osfd);
+    if (rv == -1) {
+        err = sock_errno();
+        _PR_MD_MAP_CLOSE_ERROR(err);
+    }
+    return rv;
+}
+
+PRInt32
+_MD_SocketAvailable(PRFileDesc *fd)
+{
+    PRInt32 result;
+
+    if (so_ioctl(fd->secret->md.osfd, FIONREAD, (char *) &result, sizeof(result)) < 0) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, sock_errno());
+        return -1;
+    }
+    return result;
+}
+
+static PRInt32
+socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
+{
+    PRInt32 rv = -1;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime epoch, now, elapsed, remaining;
+    PRBool wait_for_remaining;
+    PRInt32 syserror;
+#ifdef BSD_SELECT
+    struct timeval tv;
+    fd_set rd_wr;
+#else
+    int socks[1];
+    long lTimeout;
+#endif
+
+    switch (timeout) {
+        case PR_INTERVAL_NO_WAIT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            /*
+             * This is a special case of the 'default' case below.
+             * Please see the comments there.
+             */
+#ifdef BSD_SELECT
+            tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+            tv.tv_usec = 0;
+            FD_ZERO(&rd_wr);
+            do {
+                FD_SET(osfd, &rd_wr);
+                if (fd_type == READ_FD)
+                    rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv);
+                else
+                    rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv);
+#else
+            lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; 
+            do {
+                socks[0] = osfd;
+                if (fd_type == READ_FD)
+                    rv = os2_select(socks, 1, 0, 0, lTimeout);
+                else
+                    rv = os2_select(socks, 0, 1, 0, lTimeout);
+#endif                    
+                if (rv == -1 && (syserror = sock_errno()) != EINTR) {
+                    _PR_MD_MAP_SELECT_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = timeout;
+#ifdef BSD_SELECT
+            FD_ZERO(&rd_wr);
+#endif
+            do {
+                /*
+                 * We block in select for at most
+                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+                 * so that there is an upper limit on the delay
+                 * before the interrupt bit is checked.
+                 */
+#ifdef BSD_SELECT
+                wait_for_remaining = PR_TRUE;
+                tv.tv_sec = PR_IntervalToSeconds(remaining);
+                if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
+                    wait_for_remaining = PR_FALSE;
+                    tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+                    tv.tv_usec = 0;
+                } else {
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        remaining -
+                        PR_SecondsToInterval(tv.tv_sec));
+                }
+                FD_SET(osfd, &rd_wr);
+                if (fd_type == READ_FD)
+                    rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv);
+                else
+                    rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv);
+#else
+                wait_for_remaining = PR_TRUE;
+                lTimeout = PR_IntervalToMilliseconds(remaining);
+                if (lTimeout > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
+                    wait_for_remaining = PR_FALSE;
+                    lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
+                }
+                socks[0] = osfd;
+                if (fd_type == READ_FD)
+                    rv = os2_select(socks, 1, 0, 0, lTimeout);
+                else
+                    rv = os2_select(socks, 0, 1, 0, lTimeout);
+#endif
+                /*
+                 * we don't consider EINTR a real error
+                 */
+                if (rv == -1 && (syserror = sock_errno()) != EINTR) {
+                    _PR_MD_MAP_SELECT_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+                /*
+                 * We loop again if select timed out or got interrupted
+                 * by a signal, and the timeout deadline has not passed yet.
+                 */
+                if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+                    /*
+                     * If select timed out, we know how much time
+                     * we spent in blocking, so we can avoid a
+                     * PR_IntervalNow() call.
+                     */
+                    if (rv == 0) {
+                        if (wait_for_remaining) {
+                            now += remaining;
+                        } else {
+#ifdef BSD_SELECT
+                            now += PR_SecondsToInterval(tv.tv_sec)
+                                + PR_MicrosecondsToInterval(tv.tv_usec);
+#else
+                            now += PR_MillisecondsToInterval(lTimeout);
+#endif
+                        }
+                    } else {
+                        now = PR_IntervalNow();
+                    }
+                    elapsed = (PRIntervalTime) (now - epoch);
+                    if (elapsed >= timeout) {
+                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                        rv = -1;
+                        break;
+                    } else {
+                        remaining = timeout - elapsed;
+                    }
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+        }
+    return(rv);
+}
+
+PRInt32
+_MD_Accept(PRFileDesc *fd, PRNetAddr *addr,
+           PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = accept(osfd, (struct sockaddr*) addr, (int*)addrlen)) == -1)
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK) || (err == ECONNABORTED))
+        {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                    goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_ACCEPT_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, 
+               PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRNetAddr addrCopy = *addr; /* Work around a bug in OS/2 where connect
+                                 * modifies the sockaddr structure.
+                                 * See Bugzilla bug 100776. */
+
+     /*
+      * We initiate the connection setup by making a nonblocking connect()
+      * call.  If the connect() call fails, there are two cases we handle
+      * specially:
+      * 1. The connect() call was interrupted by a signal.  In this case
+      *    we simply retry connect().
+      * 2. The NSPR socket is nonblocking and connect() fails with
+      *    EINPROGRESS.  We first wait until the socket becomes writable.
+      *    Then we try to find out whether the connection setup succeeded
+      *    or failed.
+      */
+
+retry:
+    if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1)
+    {
+        err = sock_errno();
+
+        if (err == EINTR) {
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            goto retry;
+        }
+
+        if (!fd->secret->nonblocking && (err == EINPROGRESS))
+        {
+            /*
+             * socket_io_wait() may return -1 or 1.
+             */
+
+            rv = socket_io_wait(osfd, WRITE_FD, timeout);
+            if (rv == -1) {
+                return -1;
+            }
+
+            PR_ASSERT(rv == 1);
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            err = _MD_os2_get_nonblocking_connect_error(osfd);
+            if (err != 0) {
+                _PR_MD_MAP_CONNECT_ERROR(err);
+                return -1;
+            }
+            return 0;
+        }
+        
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+
+    return rv;
+}  /* _MD_connect */
+
+PRInt32
+_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv, err;
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_BIND_ERROR(err);
+    }
+    return(rv);
+}
+
+
+PRInt32
+_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv, err;
+    rv = listen(fd->secret->md.osfd, backlog);
+    if (rv < 0)  {
+        err = sock_errno();
+        _PR_MD_MAP_DEFAULT_ERROR(err);
+    }
+    return(rv);
+}
+
+
+PRInt32
+_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
+            PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = recv(osfd,buf,amount,flags)) == -1)
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = send(osfd,buf,amount,flags)) == -1)
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+
+     /*
+      * optimization; if bytes sent is less than "amount" call
+      * select before returning. This is because it is likely that
+      * the next send() call will return EWOULDBLOCK.
+      */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+        && (timeout != PR_INTERVAL_NO_WAIT))
+    {
+        if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) {
+            rv = -1;
+            goto done;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SEND_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+              const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    while ((rv = sendto(osfd, buf, amount, flags,
+           (struct sockaddr *) addr, addrlen)) == -1)
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK))
+        {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SENDTO_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+                PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while( (*addrlen = PR_NETADDR_SIZE(addr)),
+           ((rv = recvfrom(osfd, buf, amount, flags,
+             (struct sockaddr *) addr, (int *)addrlen)) == -1))
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
+              PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 index, amount = 0;
+    PRInt32 osfd = fd->secret->md.osfd;
+    struct iovec osiov[PR_MAX_IOVECTOR_SIZE];
+
+    /* Ensured by PR_Writev */
+    PR_ASSERT(iov_size <= PR_MAX_IOVECTOR_SIZE);
+
+    /*
+     * We can't pass iov to so_writev because PRIOVec and struct iovec
+     * may not be binary compatible.  Make osiov a copy of iov and
+     * pass osiov to so_writev .
+     */
+    for (index = 0; index < iov_size; index++) {
+        osiov[index].iov_base = iov[index].iov_base;
+        osiov[index].iov_len = iov[index].iov_len;
+    }
+
+     /*
+      * Calculate the total number of bytes to be sent; needed for
+      * optimization later.
+      * We could avoid this if this number was passed in; but it is
+      * probably not a big deal because iov_size is usually small (less than
+      * 3)
+      */
+    if (!fd->secret->nonblocking) {
+        for (index=0; index<iov_size; index++) {
+            amount += iov[index].iov_len;
+        }
+    }
+
+    while ((rv = so_writev(osfd, osiov, iov_size)) == -1) {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+
+     /*
+      * optimization; if bytes sent is less than "amount" call
+      * select before returning. This is because it is likely that
+      * the next writev() call will return EWOULDBLOCK.
+      */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+          && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
+            rv = -1;
+            goto done;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_WRITEV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how)
+{
+    PRInt32 rv;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0)
+        _PR_MD_MAP_SHUTDOWN_ERROR(sock_errno());
+    return rv;
+}
+
+PRInt32
+_PR_MD_SOCKETPAIR(int af, int type, int flags, PRInt32 *osfd)
+{
+    PRInt32 rv, err;
+
+    rv = socketpair(af, type, flags, osfd);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKETPAIR_ERROR(err);
+    }
+    return rv;
+}
+
+PRStatus
+_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockname(fd->secret->md.osfd,
+                     (struct sockaddr *) addr, (int *)addrlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_GETSOCKNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getpeername(fd->secret->md.osfd,
+                     (struct sockaddr *) addr, (int *)addrlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_GETPEERNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname,
+                  char* optval, PRInt32* optlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (int *)optlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_GETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname,
+                  const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv, err;
+
+    rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+void
+_MD_MakeNonblock(PRFileDesc *fd)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 err;
+    PRUint32  one = 1;
+    
+    if (osfd <= 2) {
+        /* Don't mess around with stdin, stdout or stderr */
+        return;
+    }
+
+    err = so_ioctl( osfd, FIONBIO, (char *) &one, sizeof(one));
+    if ( err != 0 )
+    {
+        err = sock_errno();
+        _PR_MD_MAP_SOCKET_ERROR(err);
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2thred.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2thred.c
new file mode 100644
index 0000000..dcd3e93
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2thred.c
@@ -0,0 +1,385 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <process.h>  /* for _beginthread() */
+#include <signal.h>
+#include <float.h>
+
+/* --- globals ------------------------------------------------ */
+_NSPR_TLS*        pThreadLocalStorage = 0;
+_PRInterruptTable             _pr_interruptTable[] = { { 0 } };
+APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
+
+void
+_PR_MD_ENSURE_TLS(void)
+{
+   if(!pThreadLocalStorage)
+   {
+      /* Allocate thread local storage (TLS).  Note, that only 32 bytes can
+       * be allocated at a time. 
+       */
+      int rc = DosAllocThreadLocalMemory(sizeof(_NSPR_TLS) / 4, (PULONG*)&pThreadLocalStorage);
+      PR_ASSERT(rc == NO_ERROR);
+      memset(pThreadLocalStorage, 0, sizeof(_NSPR_TLS));
+   }
+}
+
+void
+_PR_MD_EARLY_INIT()
+{
+   HMODULE hmod;
+
+   if (DosLoadModule(NULL, 0, "DOSCALL1", &hmod) == 0)
+       DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT",
+                        (PFN *)&QueryThreadContext);
+}
+
+static void
+_pr_SetThreadMDHandle(PRThread *thread)
+{
+   PTIB ptib;
+   PPIB ppib;
+   PRUword rc;
+
+   rc = DosGetInfoBlocks(&ptib, &ppib);
+
+   thread->md.handle = ptib->tib_ptib2->tib2_ultid;
+}
+
+/* On OS/2, some system function calls seem to change the FPU control word,
+ * such that we crash with a floating underflow exception.  The FIX_FPU() call
+ * in jsnum.c does not always work, as sometimes FIX_FPU() is called BEFORE the
+ * OS/2 system call that horks the FPU control word.  So, we set an exception
+ * handler that covers any floating point exceptions and resets the FPU CW to
+ * the required value.
+ */
+static ULONG
+_System OS2_FloatExcpHandler(PEXCEPTIONREPORTRECORD p1,
+                             PEXCEPTIONREGISTRATIONRECORD p2,
+                             PCONTEXTRECORD p3,
+                             PVOID pv)
+{
+#ifdef DEBUG_pedemonte
+    printf("Entering exception handler; ExceptionNum = %x\n", p1->ExceptionNum);
+    switch(p1->ExceptionNum) {
+        case XCPT_FLOAT_DENORMAL_OPERAND:
+            printf("got XCPT_FLOAT_DENORMAL_OPERAND\n");
+            break;
+        case XCPT_FLOAT_DIVIDE_BY_ZERO:
+            printf("got XCPT_FLOAT_DIVIDE_BY_ZERO\n");
+            break;
+        case XCPT_FLOAT_INEXACT_RESULT:
+            printf("got XCPT_FLOAT_INEXACT_RESULT\n");
+            break;
+        case XCPT_FLOAT_INVALID_OPERATION:
+            printf("got XCPT_FLOAT_INVALID_OPERATION\n");
+            break;
+        case XCPT_FLOAT_OVERFLOW:
+            printf("got XCPT_FLOAT_OVERFLOW\n");
+            break;
+        case XCPT_FLOAT_STACK_CHECK:
+            printf("got XCPT_FLOAT_STACK_CHECK\n");
+            break;
+        case XCPT_FLOAT_UNDERFLOW:
+            printf("got XCPT_FLOAT_UNDERFLOW\n");
+            break;
+    }
+#endif
+
+    switch(p1->ExceptionNum) {
+        case XCPT_FLOAT_DENORMAL_OPERAND:
+        case XCPT_FLOAT_DIVIDE_BY_ZERO:
+        case XCPT_FLOAT_INEXACT_RESULT:
+        case XCPT_FLOAT_INVALID_OPERATION:
+        case XCPT_FLOAT_OVERFLOW:
+        case XCPT_FLOAT_STACK_CHECK:
+        case XCPT_FLOAT_UNDERFLOW:
+        {
+            unsigned cw = p3->ctx_env[0];
+            if ((cw & MCW_EM) != MCW_EM) {
+                /* Mask out all floating point exceptions */
+                p3->ctx_env[0] |= MCW_EM;
+                /* Following two lines set precision to 53 bit mantissa.  See jsnum.c */
+                p3->ctx_env[0] &= ~MCW_PC;
+                p3->ctx_env[0] |= PC_53;
+                return XCPT_CONTINUE_EXECUTION;
+            }
+        }
+    }
+    return XCPT_CONTINUE_SEARCH;
+}
+
+PR_IMPLEMENT(void)
+PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg)
+{
+    /* setup the exception handler for the thread */
+    APIRET rv;
+    excpreg->ExceptionHandler = OS2_FloatExcpHandler;
+    excpreg->prev_structure = NULL;
+    rv = DosSetExceptionHandler(excpreg);
+    PR_ASSERT(rv == NO_ERROR);
+}
+
+PR_IMPLEMENT(void)
+PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg)
+{
+    /* unset exception handler */
+    APIRET rv = DosUnsetExceptionHandler(excpreg);
+    PR_ASSERT(rv == NO_ERROR);
+}
+
+PRStatus
+_PR_MD_INIT_THREAD(PRThread *thread)
+{
+   APIRET rv;
+
+   if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+      _pr_SetThreadMDHandle(thread);
+   }
+
+   /* Create the blocking IO semaphore */
+   rv = DosCreateEventSem(NULL, &(thread->md.blocked_sema), 0, 0);
+   return (rv == NO_ERROR) ? PR_SUCCESS : PR_FAILURE;
+}
+
+typedef struct param_store
+{
+    void (*start)(void *);
+    PRThread* thread;
+} PARAMSTORE;
+
+/* This is a small intermediate function that sets/unsets the exception
+   handler before calling the initial thread function */
+static void
+ExcpStartFunc(void* arg)
+{
+    EXCEPTIONREGISTRATIONRECORD excpreg;
+    PARAMSTORE params, *pParams = arg;
+
+    PR_OS2_SetFloatExcpHandler(&excpreg);
+
+    params = *pParams;
+    PR_Free(pParams);
+    params.start(params.thread);
+
+    PR_OS2_UnsetFloatExcpHandler(&excpreg);
+}
+
+PRStatus
+_PR_MD_CREATE_THREAD(PRThread *thread, 
+                  void (*start)(void *), 
+                  PRThreadPriority priority, 
+                  PRThreadScope scope, 
+                  PRThreadState state, 
+                  PRUint32 stackSize)
+{
+    PARAMSTORE* params = PR_Malloc(sizeof(PARAMSTORE));
+    params->start = start;
+    params->thread = thread;
+    thread->md.handle = thread->id = (TID) _beginthread(ExcpStartFunc,
+                                                        NULL, 
+                                                        thread->stack->stackSize,
+                                                        params);
+    if(thread->md.handle == -1) {
+        return PR_FAILURE;
+    }
+
+    /*
+     * On OS/2, a thread is created with a thread priority of
+     * THREAD_PRIORITY_NORMAL
+     */
+
+    if (priority != PR_PRIORITY_NORMAL) {
+        _PR_MD_SET_PRIORITY(&(thread->md), priority);
+    }
+
+    return PR_SUCCESS;
+}
+
+void
+_PR_MD_YIELD(void)
+{
+    /* Isn't there some problem with DosSleep(0) on OS/2? */
+    DosSleep(0);
+}
+
+void
+_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
+{
+    int nativePri = PRTYC_NOCHANGE;
+    BOOL rv;
+
+    if (newPri < PR_PRIORITY_FIRST) {
+        newPri = PR_PRIORITY_FIRST;
+    } else if (newPri > PR_PRIORITY_LAST) {
+        newPri = PR_PRIORITY_LAST;
+    }
+    switch (newPri) {
+        case PR_PRIORITY_LOW:
+        case PR_PRIORITY_NORMAL:
+            nativePri = PRTYC_REGULAR;
+            break;
+        case PR_PRIORITY_HIGH:
+            nativePri = PRTYC_FOREGROUNDSERVER;
+            break;
+        case PR_PRIORITY_URGENT:
+            nativePri = PRTYC_TIMECRITICAL;
+    }
+    rv = DosSetPriority(PRTYS_THREAD, nativePri, 0, thread->handle);
+    PR_ASSERT(rv == NO_ERROR);
+    if (rv != NO_ERROR) {
+        PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+                ("PR_SetThreadPriority: can't set thread priority\n"));
+    }
+    return;
+}
+
+void
+_PR_MD_CLEAN_THREAD(PRThread *thread)
+{
+    APIRET rv;
+
+    if (thread->md.blocked_sema) {
+        rv = DosCloseEventSem(thread->md.blocked_sema);
+        PR_ASSERT(rv == NO_ERROR);
+        thread->md.blocked_sema = 0;
+    }
+
+    if (thread->md.handle) {
+        thread->md.handle = 0;
+    }
+}
+
+void
+_PR_MD_EXIT_THREAD(PRThread *thread)
+{
+    _PR_MD_CLEAN_THREAD(thread);
+    _PR_MD_SET_CURRENT_THREAD(NULL);
+}
+
+
+void
+_PR_MD_EXIT(PRIntn status)
+{
+    _exit(status);
+}
+
+#ifdef HAVE_THREAD_AFFINITY
+PR_EXTERN(PRInt32) 
+_PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
+{
+   /* Can we do this on OS/2?  Only on SMP versions? */
+   PR_ASSERT(!"Not implemented");
+   return 0;
+
+ /* This is what windows does:
+    int rv;
+
+    rv = SetThreadAffinityMask(thread->md.handle, mask);
+
+    return rv?0:-1;
+  */
+}
+
+PR_EXTERN(PRInt32)
+_PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
+{
+   /* Can we do this on OS/2?  Only on SMP versions? */
+   PR_ASSERT(!"Not implemented");
+   return 0;
+
+ /* This is what windows does:
+    PRInt32 rv, system_mask;
+
+    rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask);
+    
+    return rv?0:-1;
+  */
+}
+#endif /* HAVE_THREAD_AFFINITY */
+
+void
+_PR_MD_SUSPEND_CPU(_PRCPU *cpu) 
+{
+    _PR_MD_SUSPEND_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_RESUME_CPU(_PRCPU *cpu)
+{
+    _PR_MD_RESUME_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_SUSPEND_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+       APIRET rc;
+
+        /* XXXMB - DosSuspendThread() is not a blocking call; how do we
+         * know when the thread is *REALLY* suspended?
+         */
+       rc = DosSuspendThread(thread->md.handle);
+       PR_ASSERT(rc == NO_ERROR);
+    }
+}
+
+void
+_PR_MD_RESUME_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        DosResumeThread(thread->md.handle);
+    }
+}
+
+
+PRThread*
+_MD_CURRENT_THREAD(void)
+{
+    PRThread *thread;
+
+    thread = _MD_GET_ATTACHED_THREAD();
+
+    if (NULL == thread) {
+        thread = _PRI_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+    }
+
+    PR_ASSERT(thread != NULL);
+    return thread;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2vaclegacy.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2vaclegacy.s
new file mode 100644
index 0000000..3bf8e80
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/os2/os2vaclegacy.s
@@ -0,0 +1,78 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ ***** BEGIN LICENSE BLOCK *****
+/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+/
+/ The contents of this file are subject to the Mozilla Public License Version
+/ 1.1 (the "License"); you may not use this file except in compliance with
+/ the License. You may obtain a copy of the License at
+/ http://www.mozilla.org/MPL/
+/
+/ Software distributed under the License is distributed on an "AS IS" basis,
+/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+/ for the specific language governing rights and limitations under the
+/ License.
+/
+/ The Original Code is the Netscape Portable Runtime (NSPR).
+/
+/ The Initial Developer of the Original Code is
+/ InnoTek Systemberatung GmbH.
+/ Portions created by the Initial Developer are Copyright (C) 2003
+/ the Initial Developer. All Rights Reserved.
+/
+/ Contributor(s):
+/   InnoTek Systemberatung GmbH / Knut St. Osmundsen
+/
+/ Alternatively, the contents of this file may be used under the terms of
+/ either the GNU General Public License Version 2 or later (the "GPL"), or
+/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+/ in which case the provisions of the GPL or the LGPL are applicable instead
+/ of those above. If you wish to allow use of your version of this file only
+/ under the terms of either the GPL or the LGPL, and not to allow others to
+/ use your version of this file under the terms of the MPL, indicate your
+/ decision by deleting the provisions above and replace them with the notice
+/ and other provisions required by the GPL or the LGPL. If you do not delete
+/ the provisions above, a recipient may use your version of this file under
+/ the terms of any one of the MPL, the GPL or the LGPL.
+/
+/ ***** END LICENSE BLOCK *****
+
+    .text
+    .align 4
+    .globl PR_NewMonitor
+PR_NewMonitor:
+    jmp _PR_NewMonitor
+
+    .align 4
+    .globl PR_EnterMonitor
+PR_EnterMonitor:
+    mov     %eax,  4(%esp) 
+    jmp _PR_EnterMonitor
+
+    .align 4
+    .globl PR_ExitMonitor 
+PR_ExitMonitor:
+    mov     %eax,  4(%esp) 
+    jmp _PR_ExitMonitor 
+
+
+    
+    .align 4
+    .globl PR_AttachThread
+PR_AttachThread:
+    mov     %eax,  4(%esp) 
+    mov     %edx,  8(%esp) 
+    mov     %ecx, 12(%esp)
+    jmp _PR_AttachThread
+    
+    .align 4
+    .globl PR_DetachThread
+PR_DetachThread:
+    jmp _PR_DetachThread
+    
+    .align 4
+    .globl PR_GetCurrentThread
+PR_GetCurrentThread:
+    jmp _PR_GetCurrentThread
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/prosdep.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/prosdep.c
new file mode 100644
index 0000000..d80256a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/prosdep.c
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prbit.h"
+#include "prsystem.h"
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#endif
+#ifdef SUNOS4
+#include "md/sunos4.h"
+#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif 
+#ifdef XP_BEOS
+#include <OS.h>
+#endif
+
+PRInt32 _pr_pageShift;
+PRInt32 _pr_pageSize;
+
+/*
+** Get system page size
+*/
+static void GetPageSize(void)
+{
+	PRInt32 pageSize;
+
+    /* Get page size */
+#ifdef XP_UNIX
+#if defined SUNOS4 || defined BSDI || defined AIX \
+        || defined LINUX || defined __GNU__ || defined __GLIBC__ \
+        || defined FREEBSD || defined NETBSD || defined OPENBSD \
+        || defined DARWIN || defined NEXTSTEP || defined SYMBIAN
+    _pr_pageSize = getpagesize();
+#elif defined(HPUX)
+    /* I have no idea. Don't get me started. --Rob */
+    _pr_pageSize = sysconf(_SC_PAGE_SIZE);
+#else
+    _pr_pageSize = sysconf(_SC_PAGESIZE);
+#endif
+#endif /* XP_UNIX */
+
+#ifdef XP_BEOS
+    _pr_pageSize = B_PAGE_SIZE;
+#endif
+
+#ifdef XP_PC
+#ifdef _WIN32
+    SYSTEM_INFO info;
+    GetSystemInfo(&info);
+    _pr_pageSize = info.dwPageSize;
+#else
+    _pr_pageSize = 4096;
+#endif
+#endif /* XP_PC */
+
+	pageSize = _pr_pageSize;
+	PR_CEILING_LOG2(_pr_pageShift, pageSize);
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetPageShift(void)
+{
+    if (!_pr_pageSize) {
+	GetPageSize();
+    }
+    return _pr_pageShift;
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetPageSize(void)
+{
+    if (!_pr_pageSize) {
+	GetPageSize();
+    }
+    return _pr_pageSize;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/Makefile.in
new file mode 100644
index 0000000..5599ce7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/Makefile.in
@@ -0,0 +1,135 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+MOD_DEPTH	= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+CSRCS =          \
+	unix.c    \
+	unix_errors.c    \
+	uxproces.c \
+	uxrng.c \
+	uxshm.c \
+	uxwrap.c \
+	$(NULL)
+
+ifneq ($(USE_PTHREADS),1)
+CSRCS += uxpoll.c
+endif
+
+ifeq ($(PTHREADS_USER),1)
+CSRCS += pthreads_user.c
+endif
+
+CSRCS += $(PR_MD_CSRCS)
+ASFILES += $(PR_MD_ASFILES)
+
+TARGETS = $(OBJS)
+
+ifeq ($(OS_ARCH),SunOS)
+	ifneq ($(OS_RELEASE),4.1.3_U1)
+		ifeq ($(CPU_ARCH),sparc)
+		ifdef USE_64
+			ULTRASPARC_ASFILES = os_SunOS_sparcv9.s
+			ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX)))
+		else
+			LIBRARY_NAME = $(ULTRASPARC_LIBRARY)
+			LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+			ULTRASPARC_ASFILES = os_SunOS_ultrasparc.s
+			ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX)))
+			TARGETS		+= $(ULTRASPARC_ASOBJS) $(SHARED_LIBRARY)
+			RELEASE_LIBS = $(SHARED_LIBRARY)
+			RELEASE_LIBS_DEST = $(RELEASE_LIB_DIR)/cpu/sparcv8plus
+			lib_subdir = cpu/sparcv8plus
+		endif
+		endif
+	endif
+endif
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+ifeq ($(OS_ARCH),SunOS)
+ifneq ($(OS_RELEASE),4.1.3_U1)
+ifeq ($(CPU_ARCH),sparc)
+
+ifdef USE_64
+$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES)
+	/usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v9 $<
+else
+$(SHARED_LIBRARY): $(ULTRASPARC_ASOBJS)
+	$(LD) -G -z text -z endfiltee -o $@ $(ULTRASPARC_ASOBJS)
+	$(INSTALL) -m 444 $@ $(dist_libdir)/cpu/sparcv8plus
+	$(INSTALL) -m 444 $@ $(dist_bindir)/cpu/sparcv8plus
+#
+# The -f $(ORIGIN)/... linker flag uses the real file, after symbolic links
+# are resolved, as the origin.  If NSDISTMODE is not "copy", libnspr4.so
+# will be installed as a symbolic link in $(dist_libdir), pointing to the
+# real libnspr4.so file in pr/src.  Therefore we need to install an
+# additional copy of libnspr_flt4.so in pr/src/cpu/sparcv8plus.
+#
+ifneq ($(NSDISTMODE),copy)
+	$(INSTALL) -m 444 $@ ../../cpu/sparcv8plus
+endif
+
+ifneq ($(NSDISTMODE),copy)
+clobber realclean clobber_all distclean::
+	rm -rf ../../cpu
+endif
+
+$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES)
+	/usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v8plus $<
+
+clean::
+	rm -rf $(ULTRASPARC_ASOBJS)
+endif
+
+endif
+endif
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/aix.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/aix.c
new file mode 100644
index 0000000..ae945b1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/aix.c
@@ -0,0 +1,333 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#ifdef AIX_HAVE_ATOMIC_OP_H
+#include <sys/atomic_op.h>
+
+PRInt32 _AIX_AtomicSet(PRInt32 *val, PRInt32 newval)
+{
+    PRIntn oldval;
+    boolean_t stored;
+    oldval = fetch_and_add((atomic_p)val, 0);
+    do
+    {
+        stored = compare_and_swap((atomic_p)val, &oldval, newval);
+    } while (!stored);
+    return oldval;
+}  /* _AIX_AtomicSet */
+#endif /* AIX_HAVE_ATOMIC_OP_H */
+
+#if defined(AIX_TIMERS)
+
+#include <sys/time.h>
+
+static PRUint32 _aix_baseline_epoch;
+
+static void _MD_AixIntervalInit(void)
+{
+    timebasestruct_t real_time;
+    read_real_time(&real_time, TIMEBASE_SZ);
+    (void)time_base_to_time(&real_time, TIMEBASE_SZ);
+    _aix_baseline_epoch = real_time.tb_high;
+}  /* _MD_AixIntervalInit */
+
+PRIntervalTime _MD_AixGetInterval(void)
+{
+    PRIntn rv;
+    PRUint64 temp;
+    timebasestruct_t real_time;
+    read_real_time(&real_time, TIMEBASE_SZ);
+    (void)time_base_to_time(&real_time, TIMEBASE_SZ);
+    /* tb_high is in seconds, tb_low in 10(-9)seconds */
+    temp = 1000000000ULL * (PRUint64)(real_time.tb_high - _aix_baseline_epoch);
+    temp += (PRUint64)real_time.tb_low;  /* everything's 10(-9) seconds */
+    temp >>= 16;  /* now it's something way different */
+    return (PRIntervalTime)temp;
+}  /* _MD_AixGetInterval */
+
+PRIntervalTime _MD_AixIntervalPerSec(void)
+{
+    return 1000000000ULL >> 16;  /* that's 15258, I think */
+}  /* _MD_AixIntervalPerSec */
+
+#endif /* defined(AIX_TIMERS) */
+
+#if !defined(PTHREADS_USER)
+
+#if defined(_PR_PTHREADS)
+
+/*
+ * AIX 4.3 has sched_yield().  AIX 4.2 has pthread_yield().
+ * So we look up the appropriate function pointer at run time.
+ */
+
+#include <dlfcn.h>
+
+int (*_PT_aix_yield_fcn)() = NULL;
+int _pr_aix_send_file_use_disabled = 0;
+
+void _MD_EarlyInit(void)
+{
+    void *main_app_handle;
+	char *evp;
+
+    main_app_handle = dlopen(NULL, RTLD_NOW);
+    PR_ASSERT(NULL != main_app_handle);
+
+    _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle, "sched_yield");
+    if (!_PT_aix_yield_fcn) {
+        _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle,"pthread_yield");
+        PR_ASSERT(NULL != _PT_aix_yield_fcn);
+    }
+    dlclose(main_app_handle);
+
+	if (evp = getenv("NSPR_AIX_SEND_FILE_USE_DISABLED")) {
+		if (1 == atoi(evp))
+			_pr_aix_send_file_use_disabled = 1;
+	}
+
+#if defined(AIX_TIMERS)
+    _MD_AixIntervalInit();
+#endif
+}
+
+#else /* _PR_PTHREADS */
+
+void _MD_EarlyInit(void)
+{
+#if defined(AIX_TIMERS)
+    _MD_AixIntervalInit();
+#endif
+}
+
+#endif /* _PR_PTHREADS */
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+PR_IMPLEMENT(void)
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for AIX */
+PR_IMPLEMENT(void)
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for AIX.");
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for AIX.");
+}
+#endif /* _PR_PTHREADS */
+#endif /* PTHREADS_USER */
+
+/*
+ * NSPR 2.0 overrides the system select() and poll() functions.
+ * On AIX 4.2, we use dlopen("/unix", RTLD_NOW) and dlsym() to get
+ * at the original system select() and poll() functions.
+ */
+
+#if !defined(AIX_RENAME_SELECT)
+
+#include <sys/select.h>
+#include <sys/poll.h>
+#include <dlfcn.h>
+
+static int (*aix_select_fcn)() = NULL;
+static int (*aix_poll_fcn)() = NULL;
+
+int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
+{
+    int rv;
+
+    if (!aix_select_fcn) {
+        void *aix_handle;
+
+	aix_handle = dlopen("/unix", RTLD_NOW);
+	if (!aix_handle) {
+	    PR_SetError(PR_UNKNOWN_ERROR, 0);
+	    return -1;
+	}
+	aix_select_fcn = (int(*)())dlsym(aix_handle,"select");
+        dlclose(aix_handle);
+	if (!aix_select_fcn) {
+	    PR_SetError(PR_UNKNOWN_ERROR, 0);
+	    return -1;
+	}
+    }
+    rv = (*aix_select_fcn)(width, r, w, e, t);
+    return rv;
+}
+
+int _MD_POLL(void *listptr, unsigned long nfds, long timeout)
+{
+    int rv;
+
+    if (!aix_poll_fcn) {
+        void *aix_handle;
+
+	aix_handle = dlopen("/unix", RTLD_NOW);
+	if (!aix_handle) {
+	    PR_SetError(PR_UNKNOWN_ERROR, 0);
+	    return -1;
+	}
+	aix_poll_fcn = (int(*)())dlsym(aix_handle,"poll");
+        dlclose(aix_handle);
+	if (!aix_poll_fcn) {
+	    PR_SetError(PR_UNKNOWN_ERROR, 0);
+	    return -1;
+	}
+    }
+    rv = (*aix_poll_fcn)(listptr, nfds, timeout);
+    return rv;
+}
+
+#else
+
+/*
+ * In AIX versions prior to 4.2, we use the two-step rename/link trick.
+ * The binary must contain at least one "poll" symbol for linker's rename
+ * to work.  So we must have this dummy function that references poll().
+ */
+#include <sys/poll.h>
+void _pr_aix_dummy()
+{
+    poll(0,0,0);
+}
+
+#endif /* !defined(AIX_RENAME_SELECT) */
+
+#ifdef _PR_HAVE_ATOMIC_CAS
+
+#include "pratom.h"
+
+#define _PR_AIX_ATOMIC_LOCK	-1
+
+PR_IMPLEMENT(void)
+PR_StackPush(PRStack *stack, PRStackElem *stack_elem)
+{
+PRStackElem *addr;
+boolean_t locked = TRUE;
+
+	/* Is it safe to cast a pointer to an int? */
+	PR_ASSERT(sizeof(int) == sizeof(PRStackElem *));
+	do {
+		while ((addr = stack->prstk_head.prstk_elem_next) ==
+											(PRStackElem *)_PR_AIX_ATOMIC_LOCK)
+			;
+		locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
+							(int) addr, _PR_AIX_ATOMIC_LOCK);
+	} while (locked == TRUE);
+	stack_elem->prstk_elem_next = addr;
+	_clear_lock((atomic_p)&stack->prstk_head.prstk_elem_next, (int)stack_elem);
+    return;
+}
+
+PR_IMPLEMENT(PRStackElem *)
+PR_StackPop(PRStack *stack)
+{
+PRStackElem *element;
+boolean_t locked = TRUE;
+
+	/* Is it safe to cast a pointer to an int? */
+	PR_ASSERT(sizeof(int) == sizeof(PRStackElem *));
+	do {
+		while ((element = stack->prstk_head.prstk_elem_next) ==
+										(PRStackElem *) _PR_AIX_ATOMIC_LOCK)
+			;
+		locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
+							(int)element, _PR_AIX_ATOMIC_LOCK);
+	} while (locked == TRUE);
+
+	if (element == NULL) {
+		_clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next, NULL);
+	} else {
+		_clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
+										(int) element->prstk_elem_next);
+	}
+	return element;
+}
+
+#endif	/* _PR_HAVE_ATOMIC_CAS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/aixwrap.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/aixwrap.c
new file mode 100644
index 0000000..d829710
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/aixwrap.c
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:		aixwrap.c
+ * Description:
+ *     This file contains a single function, _MD_SELECT(), which simply
+ *     invokes the select() function.  This file is used in an ugly
+ *     hack to override the system select() function on AIX releases
+ *     prior to 4.2.  (On AIX 4.2, we use a different mechanism to
+ *     override select().)
+ */
+
+#ifndef AIX_RENAME_SELECT
+#error aixwrap.c should only be used on AIX 3.2 or 4.1
+#else
+
+#include <sys/select.h>
+#include <sys/poll.h>
+
+int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
+{
+    return select(width, r, w, e, t);
+}
+
+int _MD_POLL(void *listptr, unsigned long nfds, long timeout)
+{
+    return poll(listptr, nfds, timeout);
+}
+
+#endif /* AIX_RENAME_SELECT */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/bsdi.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/bsdi.c
new file mode 100644
index 0000000..6467663
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/bsdi.c
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <signal.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+    *np = 0;
+    return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for BSDI */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for BSDI.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for BSDI.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/darwin.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/darwin.c
new file mode 100644
index 0000000..3a1329e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/darwin.c
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#if !defined(_PR_PTHREADS)
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#if !defined(_PR_PTHREADS)
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Darwin */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Darwin.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Darwin.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
+
+/* darwin.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/dgux.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/dgux.c
new file mode 100644
index 0000000..2874d9e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/dgux.c
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+/*
+ * using only NSPR threads here
+ *
+ *  Copied from the UnixWare implementation.  Should be kept in sync
+ *  with ../../../include/md/_dgux.h.
+ */
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+        (void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+        PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for DG/UX */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for DG/UX.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for DG/UX.");
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/freebsd.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/freebsd.c
new file mode 100644
index 0000000..dce244a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/freebsd.c
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <signal.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for FreeBSD */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for FreeBSD.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for FreeBSD.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/hpux.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/hpux.c
new file mode 100644
index 0000000..cf43e05
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/hpux.c
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <setjmp.h>
+
+#if defined(HPUX_LW_TIMER)
+
+#include <machine/inline.h>
+#include <machine/clock.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/pstat.h>
+
+int __lw_get_thread_times(int which, int64_t *sample, int64_t *time);
+
+static double msecond_per_itick;
+
+void _PR_HPUX_LW_IntervalInit(void)
+{
+    struct pst_processor psp;
+    int iticksperclktick, clk_tck;
+    int rv;
+
+    rv = pstat_getprocessor(&psp, sizeof(psp), 1, 0);
+    PR_ASSERT(rv != -1);
+
+    iticksperclktick = psp.psp_iticksperclktick;
+    clk_tck = sysconf(_SC_CLK_TCK);
+    msecond_per_itick = (1000.0)/(double)(iticksperclktick * clk_tck);
+}
+
+PRIntervalTime _PR_HPUX_LW_GetInterval(void)
+{
+    int64_t time, sample;
+
+    __lw_get_thread_times(1, &sample, &time);
+    /*
+     * Division is slower than float multiplication.
+     * return (time / iticks_per_msecond);
+     */
+    return (time * msecond_per_itick);
+}
+#endif  /* HPUX_LW_TIMER */
+
+#if !defined(PTHREADS_USER)
+
+void _MD_EarlyInit(void)
+{
+#ifndef _PR_PTHREADS
+    /*
+     * The following piece of code is taken from ns/nspr/src/md_HP-UX.c.
+     * In the comment for revision 1.6, dated 1995/09/11 23:33:34,
+     * robm says:
+     *     This version has some problems which need to be addressed.
+     *     First, intercept all system calls and prevent them from
+     *     executing the library code which performs stack switches
+     *     before normal system call invocation.  In order for library
+     *     calls which make system calls to work (like stdio), however,
+     *     we must also allocate our own stack and switch the primordial
+     *     stack to use it. This isn't so bad, except that I fudged the
+     *     backtrace length when copying the old stack to the new one.
+     *
+     * This is the original comment of robm in the code:
+     *    XXXrobm Horrific. To avoid a problem with HP's system call
+     *    code, we allocate a new stack for the primordial thread and
+     *    use it. However, we don't know how far back the original stack
+     *    goes. We should create a routine that performs a backtrace and
+     *    finds out just how much we need to copy. As a temporary measure,
+     *    I just copy an arbitrary guess.
+     *
+     * In an email to servereng dated 2 Jan 1997, Mike Patnode (mikep)
+     * suggests that this only needs to be done for HP-UX 9.
+     */
+#ifdef HPUX9
+#define PIDOOMA_STACK_SIZE 524288
+#define BACKTRACE_SIZE 8192
+    {
+        jmp_buf jb;
+        char *newstack;
+        char *oldstack;
+
+        if(!setjmp(jb)) {
+            newstack = (char *) PR_MALLOC(PIDOOMA_STACK_SIZE);
+	    oldstack = (char *) (*(((int *) jb) + 1) - BACKTRACE_SIZE);
+            memcpy(newstack, oldstack, BACKTRACE_SIZE);
+            *(((int *) jb) + 1) = (int) (newstack + BACKTRACE_SIZE);
+            longjmp(jb, 1);
+        }
+    }
+#endif  /* HPUX9 */
+#endif  /* !_PR_PTHREADS */
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for HP-UX */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for HP-UX.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for HP-UX.");
+}
+#endif /* _PR_PTHREADS */
+
+void
+_MD_suspend_thread(PRThread *thread)
+{
+#ifdef _PR_PTHREADS
+#endif
+}
+
+void
+_MD_resume_thread(PRThread *thread)
+{
+#ifdef _PR_PTHREADS
+#endif
+}
+#endif /* PTHREADS_USER */
+
+/*
+ * The HP version of strchr is buggy. It looks past the end of the
+ * string and causes a segmentation fault when our (NSPR) version
+ * of malloc is used.
+ *
+ * A better solution might be to put a cushion in our malloc just in
+ * case HP's version of strchr somehow gets used instead of this one.
+ */
+char *
+strchr(const char *s, int c)
+{
+    char ch;
+
+    if (!s) {
+        return NULL;
+    }
+
+    ch = (char) c;
+
+    while ((*s) && ((*s) != ch)) {
+        s++;
+    }
+
+    if ((*s) == ch) {
+        return (char *) s;
+    }
+
+    return NULL;
+}
+
+/*
+ * Implemementation of memcmp in HP-UX (verified on releases A.09.03,
+ * A.09.07, and B.10.10) dumps core if called with:
+ * 1. First operand with address = 1(mod 4).
+ * 2. Size = 1(mod 4)
+ * 3. Last byte of the second operand is the last byte of the page and 
+ *    next page is not accessible(not mapped or protected)
+ * Thus, using the following naive version (tons of optimizations are
+ * possible;^)
+ */
+
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+    register unsigned char *p1 = (unsigned char *) s1,
+            *p2 = (unsigned char *) s2;
+
+    while (n-- > 0) {
+        register int r = ((int) ((unsigned int) *p1)) 
+                - ((int) ((unsigned int) *p2));
+        if (r) return r;
+        p1++; p2++;
+    }
+    return 0; 
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/irix.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/irix.c
new file mode 100644
index 0000000..758e54d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/irix.c
@@ -0,0 +1,1680 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <signal.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/syssgi.h>
+#include <sys/time.h>
+#include <sys/immu.h>
+#include <sys/utsname.h>
+#include <sys/sysmp.h>
+#include <sys/pda.h>
+#include <sys/prctl.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include <sys/procfs.h>
+#include <task.h>
+#include <dlfcn.h>
+
+static void _MD_IrixIntervalInit(void);
+
+#if defined(_PR_PTHREADS)
+/*
+ * for compatibility with classic nspr
+ */
+void _PR_IRIX_CHILD_PROCESS()
+{
+}
+#else  /* defined(_PR_PTHREADS) */
+
+static void irix_detach_sproc(void);
+char *_nspr_sproc_private;    /* ptr. to private region in every sproc */
+
+extern PRUintn    _pr_numCPU;
+
+typedef struct nspr_arena {
+	PRCList links;
+	usptr_t *usarena;
+} nspr_arena;
+
+#define ARENA_PTR(qp) \
+	((nspr_arena *) ((char*) (qp) - offsetof(nspr_arena , links)))
+
+static usptr_t *alloc_new_arena(void);
+
+PRCList arena_list = PR_INIT_STATIC_CLIST(&arena_list);
+ulock_t arena_list_lock;
+nspr_arena first_arena;
+int	_nspr_irix_arena_cnt = 1;
+
+PRCList sproc_list = PR_INIT_STATIC_CLIST(&sproc_list);
+ulock_t sproc_list_lock;
+
+typedef struct sproc_data {
+	void (*entry) (void *, size_t);
+	unsigned inh;
+	void *arg;
+	caddr_t sp;
+	size_t len;
+	int *pid;
+	int creator_pid;
+} sproc_data;
+
+typedef struct sproc_params {
+	PRCList links;
+	sproc_data sd;
+} sproc_params;
+
+#define SPROC_PARAMS_PTR(qp) \
+	((sproc_params *) ((char*) (qp) - offsetof(sproc_params , links)))
+
+long	_nspr_irix_lock_cnt = 0;
+long	_nspr_irix_sem_cnt = 0;
+long	_nspr_irix_pollsem_cnt = 0;
+
+usptr_t *_pr_usArena;
+ulock_t _pr_heapLock;
+
+usema_t *_pr_irix_exit_sem;
+PRInt32 _pr_irix_exit_now = 0;
+PRInt32 _pr_irix_process_exit_code = 0;	/* exit code for PR_ProcessExit */
+PRInt32 _pr_irix_process_exit = 0; /* process exiting due to call to
+										   PR_ProcessExit */
+
+int _pr_irix_primoridal_cpu_fd[2] = { -1, -1 };
+static void (*libc_exit)(int) = NULL;
+static void *libc_handle = NULL;
+
+#define _NSPR_DEF_INITUSERS		100	/* default value of CONF_INITUSERS */
+#define _NSPR_DEF_INITSIZE		(4 * 1024 * 1024)	/* 4 MB */
+
+int _irix_initusers = _NSPR_DEF_INITUSERS;
+int _irix_initsize = _NSPR_DEF_INITSIZE;
+
+PRIntn _pr_io_in_progress, _pr_clock_in_progress;
+
+PRInt32 _pr_md_irix_sprocs_created, _pr_md_irix_sprocs_failed;
+PRInt32 _pr_md_irix_sprocs = 1;
+PRCList _pr_md_irix_sproc_list =
+PR_INIT_STATIC_CLIST(&_pr_md_irix_sproc_list);
+
+sigset_t ints_off;
+extern sigset_t timer_set;
+
+#if !defined(PR_SETABORTSIG)
+#define PR_SETABORTSIG 18
+#endif
+/*
+ * terminate the entire application if any sproc exits abnormally
+ */
+PRBool _nspr_terminate_on_error = PR_TRUE;
+
+/*
+ * exported interface to set the shared arena parameters
+ */
+void _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize)
+{
+    _irix_initusers = initusers;
+    _irix_initsize = initsize;
+}
+
+static usptr_t *alloc_new_arena()
+{
+    return(usinit("/dev/zero"));
+}
+
+static PRStatus new_poll_sem(struct _MDThread *mdthr, int val)
+{
+PRIntn _is;
+PRStatus rv = PR_SUCCESS;
+usema_t *sem = NULL;
+PRCList *qp;
+nspr_arena *arena;
+usptr_t *irix_arena;
+PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	_PR_LOCK(arena_list_lock);
+	for (qp = arena_list.next; qp != &arena_list; qp = qp->next) {
+		arena = ARENA_PTR(qp);
+		sem = usnewpollsema(arena->usarena, val);
+		if (sem != NULL) {
+			mdthr->cvar_pollsem = sem;
+			mdthr->pollsem_arena = arena->usarena;
+			break;
+		}
+	}
+	if (sem == NULL) {
+		/*
+		 * If no space left in the arena allocate a new one.
+		 */
+		if (errno == ENOMEM) {
+			arena = PR_NEWZAP(nspr_arena);
+			if (arena != NULL) {
+				irix_arena = alloc_new_arena();
+				if (irix_arena) {
+					PR_APPEND_LINK(&arena->links, &arena_list);
+					_nspr_irix_arena_cnt++;
+					arena->usarena = irix_arena;
+					sem = usnewpollsema(arena->usarena, val);
+					if (sem != NULL) {
+						mdthr->cvar_pollsem = sem;
+						mdthr->pollsem_arena = arena->usarena;
+					} else
+						rv = PR_FAILURE;
+				} else {
+					PR_DELETE(arena);
+					rv = PR_FAILURE;
+				}
+
+			} else
+				rv = PR_FAILURE;
+		} else
+			rv = PR_FAILURE;
+	}
+	_PR_UNLOCK(arena_list_lock);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+	if (rv == PR_SUCCESS)
+		_MD_ATOMIC_INCREMENT(&_nspr_irix_pollsem_cnt);
+	return rv;
+}
+
+static void free_poll_sem(struct _MDThread *mdthr)
+{
+PRIntn _is;
+PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	usfreepollsema(mdthr->cvar_pollsem, mdthr->pollsem_arena);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+	_MD_ATOMIC_DECREMENT(&_nspr_irix_pollsem_cnt);
+}
+
+static PRStatus new_lock(struct _MDLock *lockp)
+{
+PRIntn _is;
+PRStatus rv = PR_SUCCESS;
+ulock_t lock = NULL;
+PRCList *qp;
+nspr_arena *arena;
+usptr_t *irix_arena;
+PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	_PR_LOCK(arena_list_lock);
+	for (qp = arena_list.next; qp != &arena_list; qp = qp->next) {
+		arena = ARENA_PTR(qp);
+		lock = usnewlock(arena->usarena);
+		if (lock != NULL) {
+			lockp->lock = lock;
+			lockp->arena = arena->usarena;
+			break;
+		}
+	}
+	if (lock == NULL) {
+		/*
+		 * If no space left in the arena allocate a new one.
+		 */
+		if (errno == ENOMEM) {
+			arena = PR_NEWZAP(nspr_arena);
+			if (arena != NULL) {
+				irix_arena = alloc_new_arena();
+				if (irix_arena) {
+					PR_APPEND_LINK(&arena->links, &arena_list);
+					_nspr_irix_arena_cnt++;
+					arena->usarena = irix_arena;
+					lock = usnewlock(irix_arena);
+					if (lock != NULL) {
+						lockp->lock = lock;
+						lockp->arena = arena->usarena;
+					} else
+						rv = PR_FAILURE;
+				} else {
+					PR_DELETE(arena);
+					rv = PR_FAILURE;
+				}
+
+			} else
+				rv = PR_FAILURE;
+		} else
+			rv = PR_FAILURE;
+	}
+	_PR_UNLOCK(arena_list_lock);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+	if (rv == PR_SUCCESS)
+		_MD_ATOMIC_INCREMENT(&_nspr_irix_lock_cnt);
+	return rv;
+}
+
+static void free_lock(struct _MDLock *lockp)
+{
+PRIntn _is;
+PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	usfreelock(lockp->lock, lockp->arena);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+	_MD_ATOMIC_DECREMENT(&_nspr_irix_lock_cnt);
+}
+
+void _MD_FREE_LOCK(struct _MDLock *lockp)
+{
+	PRIntn _is;
+	PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	free_lock(lockp);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+}
+
+/*
+ * _MD_get_attached_thread
+ *		Return the thread pointer of the current thread if it is attached.
+ *
+ *		This function is needed for Irix because the thread-local-storage is
+ *		implemented by mmapin'g a page with the MAP_LOCAL flag. This causes the
+ *		sproc-private page to inherit contents of the page of the caller of sproc().
+ */
+PRThread *_MD_get_attached_thread(void)
+{
+
+	if (_MD_GET_SPROC_PID() == get_pid())
+		return _MD_THIS_THREAD();
+	else
+		return 0;
+}
+
+/*
+ * _MD_get_current_thread
+ *		Return the thread pointer of the current thread (attaching it if
+ *		necessary)
+ */
+PRThread *_MD_get_current_thread(void)
+{
+PRThread *me;
+
+	me = _MD_GET_ATTACHED_THREAD();
+    if (NULL == me) {
+        me = _PRI_AttachThread(
+            PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+    }
+    PR_ASSERT(me != NULL);
+	return(me);
+}
+
+/*
+ * irix_detach_sproc
+ *		auto-detach a sproc when it exits
+ */
+void irix_detach_sproc(void)
+{
+PRThread *me;
+
+	me = _MD_GET_ATTACHED_THREAD();
+	if ((me != NULL) && (me->flags & _PR_ATTACHED)) {
+		_PRI_DetachThread();
+	}
+}
+
+
+PRStatus _MD_NEW_LOCK(struct _MDLock *lockp)
+{
+    PRStatus rv;
+    PRIntn is;
+    PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(is);
+	rv = new_lock(lockp);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(is);
+	return rv;
+}
+
+static void
+sigchld_handler(int sig)
+{
+    pid_t pid;
+    int status;
+
+    /*
+     * If an sproc exited abnormally send a SIGKILL signal to all the
+     * sprocs in the process to terminate the application
+     */
+    while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
+        if (WIFSIGNALED(status) && ((WTERMSIG(status) == SIGSEGV) ||
+            (WTERMSIG(status) == SIGBUS) ||
+            (WTERMSIG(status) == SIGABRT) ||
+            (WTERMSIG(status) == SIGILL))) {
+
+				prctl(PR_SETEXITSIG, SIGKILL);
+				_exit(status);
+			}
+    }
+}
+
+static void save_context_and_block(int sig)
+{
+PRThread *me = _PR_MD_CURRENT_THREAD();
+_PRCPU *cpu = _PR_MD_CURRENT_CPU();
+
+	/*
+	 * save context
+	 */
+	(void) setjmp(me->md.jb);
+	/*
+	 * unblock the suspending thread
+	 */
+	if (me->cpu) {
+		/*
+		 * I am a cpu thread, not a user-created GLOBAL thread
+		 */
+		unblockproc(cpu->md.suspending_id);	
+	} else {
+		unblockproc(me->md.suspending_id);	
+	}
+	/*
+	 * now, block current thread
+	 */
+	blockproc(getpid());
+}
+
+/*
+** The irix kernel has a bug in it which causes async connect's which are
+** interrupted by a signal to fail terribly (EADDRINUSE is returned). 
+** We work around the bug by blocking signals during the async connect
+** attempt.
+*/
+PRInt32 _MD_irix_connect(
+    PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 rv;
+    sigset_t oldset;
+
+    sigprocmask(SIG_BLOCK, &ints_off, &oldset);
+    rv = connect(osfd, addr, addrlen);
+    sigprocmask(SIG_SETMASK, &oldset, 0);
+
+    return(rv);
+}
+
+#include "prprf.h"
+
+/********************************************************************/
+/********************************************************************/
+/*************** Various thread like things for IRIX ****************/
+/********************************************************************/
+/********************************************************************/
+
+void *_MD_GetSP(PRThread *t)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    void *sp;
+
+    if (me == t)
+        (void) setjmp(t->md.jb);
+
+    sp = (void *)(t->md.jb[JB_SP]);
+    PR_ASSERT((sp >= (void *) t->stack->stackBottom) &&
+        (sp <= (void *) (t->stack->stackBottom + t->stack->stackSize)));
+    return(sp);
+}
+
+void _MD_InitLocks()
+{
+    char buf[200];
+    char *init_users, *init_size;
+
+    PR_snprintf(buf, sizeof(buf), "/dev/zero");
+
+    if (init_users = getenv("_NSPR_IRIX_INITUSERS"))
+        _irix_initusers = atoi(init_users);
+
+    if (init_size = getenv("_NSPR_IRIX_INITSIZE"))
+        _irix_initsize = atoi(init_size);
+
+    usconfig(CONF_INITUSERS, _irix_initusers);
+    usconfig(CONF_INITSIZE, _irix_initsize);
+    usconfig(CONF_AUTOGROW, 1);
+    usconfig(CONF_AUTORESV, 1);
+	if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) {
+		perror("PR_Init: unable to config mutex arena");
+		exit(-1);
+	}
+
+    _pr_usArena = usinit(buf);
+    if (!_pr_usArena) {
+        fprintf(stderr,
+            "PR_Init: Error - unable to create lock/monitor arena\n");
+        exit(-1);
+    }
+    _pr_heapLock = usnewlock(_pr_usArena);
+	_nspr_irix_lock_cnt++;
+
+    arena_list_lock = usnewlock(_pr_usArena);
+	_nspr_irix_lock_cnt++;
+
+    sproc_list_lock = usnewlock(_pr_usArena);
+	_nspr_irix_lock_cnt++;
+
+	_pr_irix_exit_sem = usnewsema(_pr_usArena, 0);
+	_nspr_irix_sem_cnt = 1;
+
+	first_arena.usarena = _pr_usArena;
+	PR_INIT_CLIST(&first_arena.links);
+	PR_APPEND_LINK(&first_arena.links, &arena_list);
+}
+
+/* _PR_IRIX_CHILD_PROCESS is a private API for Server group */
+void _PR_IRIX_CHILD_PROCESS()
+{
+extern PRUint32 _pr_global_threads;
+
+    PR_ASSERT(_PR_MD_CURRENT_CPU() == _pr_primordialCPU);
+    PR_ASSERT(_pr_numCPU == 1);
+    PR_ASSERT(_pr_global_threads == 0);
+    /*
+     * save the new pid
+     */
+    _pr_primordialCPU->md.id = getpid();
+	_MD_SET_SPROC_PID(getpid());	
+}
+
+static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout)
+{
+    int rv;
+
+#ifdef _PR_USE_POLL
+	struct pollfd pfd;
+	int msecs;
+
+	if (timeout == PR_INTERVAL_NO_TIMEOUT)
+		msecs = -1;
+	else
+		msecs  = PR_IntervalToMilliseconds(timeout);
+#else
+    struct timeval tv, *tvp;
+    fd_set rd;
+
+	if(timeout == PR_INTERVAL_NO_TIMEOUT)
+		tvp = NULL;
+	else {
+		tv.tv_sec = PR_IntervalToSeconds(timeout);
+		tv.tv_usec = PR_IntervalToMicroseconds(
+		timeout - PR_SecondsToInterval(tv.tv_sec));
+		tvp = &tv;
+	}
+	FD_ZERO(&rd);
+	FD_SET(thread->md.cvar_pollsemfd, &rd);
+#endif
+
+    /*
+     * call uspsema only if a previous select call on this semaphore
+     * did not timeout
+     */
+    if (!thread->md.cvar_pollsem_select) {
+        rv = _PR_WAIT_SEM(thread->md.cvar_pollsem);
+		PR_ASSERT(rv >= 0);
+	} else
+        rv = 0;
+again:
+    if(!rv) {
+#ifdef _PR_USE_POLL
+		pfd.events = POLLIN;
+		pfd.fd = thread->md.cvar_pollsemfd;
+		rv = _MD_POLL(&pfd, 1, msecs);
+#else
+		rv = _MD_SELECT(thread->md.cvar_pollsemfd + 1, &rd, NULL,NULL,tvp);
+#endif
+        if ((rv == -1) && (errno == EINTR)) {
+			rv = 0;
+			goto again;
+		}
+		PR_ASSERT(rv >= 0);
+	}
+
+    if (rv > 0) {
+        /*
+         * acquired the semaphore, call uspsema next time
+         */
+        thread->md.cvar_pollsem_select = 0;
+        return PR_SUCCESS;
+    } else {
+        /*
+         * select timed out; must call select, not uspsema, when trying
+         * to acquire the semaphore the next time
+         */
+        thread->md.cvar_pollsem_select = 1;
+        return PR_FAILURE;
+    }
+}
+
+PRStatus _MD_wait(PRThread *thread, PRIntervalTime ticks)
+{
+    if ( thread->flags & _PR_GLOBAL_SCOPE ) {
+	_MD_CHECK_FOR_EXIT();
+        if (pr_cvar_wait_sem(thread, ticks) == PR_FAILURE) {
+	    _MD_CHECK_FOR_EXIT();
+            /*
+             * wait timed out
+             */
+            _PR_THREAD_LOCK(thread);
+            if (thread->wait.cvar) {
+                /*
+                 * The thread will remove itself from the waitQ
+                 * of the cvar in _PR_WaitCondVar
+                 */
+                thread->wait.cvar = NULL;
+                thread->state =  _PR_RUNNING;
+                _PR_THREAD_UNLOCK(thread);
+            }  else {
+                _PR_THREAD_UNLOCK(thread);
+                /*
+             * This thread was woken up by a notifying thread
+             * at the same time as a timeout; so, consume the
+             * extra post operation on the semaphore
+             */
+	        _MD_CHECK_FOR_EXIT();
+            pr_cvar_wait_sem(thread, PR_INTERVAL_NO_TIMEOUT);
+            }
+	    _MD_CHECK_FOR_EXIT();
+        }
+    } else {
+        _PR_MD_SWITCH_CONTEXT(thread);
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _MD_WakeupWaiter(PRThread *thread)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntn is;
+
+	PR_ASSERT(_pr_md_idle_cpus >= 0);
+    if (thread == NULL) {
+		if (_pr_md_idle_cpus)
+        	_MD_Wakeup_CPUs();
+    } else if (!_PR_IS_NATIVE_THREAD(thread)) {
+		if (_pr_md_idle_cpus)
+       		_MD_Wakeup_CPUs();
+    } else {
+		PR_ASSERT(_PR_IS_NATIVE_THREAD(thread));
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_INTSOFF(is);
+		_MD_CVAR_POST_SEM(thread);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+    } 
+    return PR_SUCCESS;
+}
+
+void create_sproc (void (*entry) (void *, size_t), unsigned inh,
+					void *arg, caddr_t sp, size_t len, int *pid)
+{
+sproc_params sparams;
+char data;
+int rv;
+PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) {
+		*pid = sprocsp(entry,		/* startup func		*/
+						inh,        /* attribute flags	*/
+						arg,     	/* thread param		*/
+						sp,         /* stack address	*/
+						len);       /* stack size		*/
+	} else {
+		sparams.sd.entry = entry;
+		sparams.sd.inh = inh;
+		sparams.sd.arg = arg;
+		sparams.sd.sp = sp;
+		sparams.sd.len = len;
+		sparams.sd.pid = pid;
+		sparams.sd.creator_pid = getpid();
+		_PR_LOCK(sproc_list_lock);
+		PR_APPEND_LINK(&sparams.links, &sproc_list);
+		rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
+		PR_ASSERT(rv == 1);
+		_PR_UNLOCK(sproc_list_lock);
+		blockproc(getpid());
+	}
+}
+
+/*
+ * _PR_MD_WAKEUP_PRIMORDIAL_CPU
+ *
+ *		wakeup cpu 0
+ */
+
+void _PR_MD_WAKEUP_PRIMORDIAL_CPU()
+{
+char data = '0';
+int rv;
+
+	rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
+	PR_ASSERT(rv == 1);
+}
+
+/*
+ * _PR_MD_primordial_cpu
+ *
+ *		process events that need to executed by the primordial cpu on each
+ *		iteration through the idle loop
+ */
+
+void _PR_MD_primordial_cpu()
+{
+PRCList *qp;
+sproc_params *sp;
+int pid;
+
+	_PR_LOCK(sproc_list_lock);
+	while ((qp = sproc_list.next) != &sproc_list) {
+		sp = SPROC_PARAMS_PTR(qp);
+		PR_REMOVE_LINK(&sp->links);
+		pid = sp->sd.creator_pid;
+		(*(sp->sd.pid)) = sprocsp(sp->sd.entry,		/* startup func    */
+							sp->sd.inh,            	/* attribute flags     */
+							sp->sd.arg,     		/* thread param     */
+							sp->sd.sp,             	/* stack address    */
+							sp->sd.len);         	/* stack size     */
+		unblockproc(pid);
+	}
+	_PR_UNLOCK(sproc_list_lock);
+}
+
+PRStatus _MD_CreateThread(PRThread *thread, 
+void (*start)(void *), 
+PRThreadPriority priority, 
+PRThreadScope scope, 
+PRThreadState state, 
+PRUint32 stackSize)
+{
+    typedef void (*SprocEntry) (void *, size_t);
+    SprocEntry spentry = (SprocEntry)start;
+    PRIntn is;
+	PRThread *me = _PR_MD_CURRENT_THREAD();	
+	PRInt32 pid;
+	PRStatus rv;
+
+	if (!_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(is);
+    thread->md.cvar_pollsem_select = 0;
+    thread->flags |= _PR_GLOBAL_SCOPE;
+
+	thread->md.cvar_pollsemfd = -1;
+	if (new_poll_sem(&thread->md,0) == PR_FAILURE) {
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+		return PR_FAILURE;
+	}
+	thread->md.cvar_pollsemfd =
+		_PR_OPEN_POLL_SEM(thread->md.cvar_pollsem);
+	if ((thread->md.cvar_pollsemfd < 0)) {
+		free_poll_sem(&thread->md);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+		return PR_FAILURE;
+	}
+
+    create_sproc(spentry,            /* startup func    */
+    			PR_SALL,            /* attribute flags     */
+    			(void *)thread,     /* thread param     */
+    			NULL,               /* stack address    */
+    			stackSize, &pid);         /* stack size     */
+    if (pid > 0) {
+        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_created);
+        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs);
+		rv = PR_SUCCESS;
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return rv;
+    } else {
+        close(thread->md.cvar_pollsemfd);
+        thread->md.cvar_pollsemfd = -1;
+		free_poll_sem(&thread->md);
+        thread->md.cvar_pollsem = NULL;
+        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_failed);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_FAILURE;
+    }
+}
+
+void _MD_CleanThread(PRThread *thread)
+{
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        close(thread->md.cvar_pollsemfd);
+        thread->md.cvar_pollsemfd = -1;
+		free_poll_sem(&thread->md);
+        thread->md.cvar_pollsem = NULL;
+    }
+}
+
+void _MD_SetPriority(_MDThread *thread, PRThreadPriority newPri)
+{
+    return;
+}
+
+extern void _MD_unix_terminate_waitpid_daemon(void);
+
+void
+_MD_CleanupBeforeExit(void)
+{
+    extern PRInt32    _pr_cpus_exit;
+
+    _MD_unix_terminate_waitpid_daemon();
+
+	_pr_irix_exit_now = 1;
+    if (_pr_numCPU > 1) {
+        /*
+         * Set a global flag, and wakeup all cpus which will notice the flag
+         * and exit.
+         */
+        _pr_cpus_exit = getpid();
+        _MD_Wakeup_CPUs();
+        while(_pr_numCPU > 1) {
+            _PR_WAIT_SEM(_pr_irix_exit_sem);
+            _pr_numCPU--;
+        }
+    }
+    /*
+     * cause global threads on the recycle list to exit
+     */
+     _PR_DEADQ_LOCK;
+     if (_PR_NUM_DEADNATIVE != 0) {
+	PRThread *thread;
+    	PRCList *ptr;
+
+        ptr = _PR_DEADNATIVEQ.next;
+        while( ptr != &_PR_DEADNATIVEQ ) {
+        	thread = _PR_THREAD_PTR(ptr);
+		_MD_CVAR_POST_SEM(thread);
+                ptr = ptr->next;
+        } 
+     }
+     _PR_DEADQ_UNLOCK;
+     while(_PR_NUM_DEADNATIVE > 1) {
+	_PR_WAIT_SEM(_pr_irix_exit_sem);
+	_PR_DEC_DEADNATIVE;
+     }
+}
+
+#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
+extern void __sgi_prda_procmask(int);
+#endif
+
+PRStatus
+_MD_InitAttachedThread(PRThread *thread, PRBool wakeup_parent)
+{
+	PRStatus rv = PR_SUCCESS;
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+		if (new_poll_sem(&thread->md,0) == PR_FAILURE) {
+			return PR_FAILURE;
+		}
+		thread->md.cvar_pollsemfd =
+			_PR_OPEN_POLL_SEM(thread->md.cvar_pollsem);
+		if ((thread->md.cvar_pollsemfd < 0)) {
+			free_poll_sem(&thread->md);
+			return PR_FAILURE;
+		}
+		if (_MD_InitThread(thread, PR_FALSE) == PR_FAILURE) {
+			close(thread->md.cvar_pollsemfd);
+			thread->md.cvar_pollsemfd = -1;
+			free_poll_sem(&thread->md);
+			thread->md.cvar_pollsem = NULL;
+			return PR_FAILURE;
+		}
+    }
+	return rv;
+}
+
+PRStatus
+_MD_InitThread(PRThread *thread, PRBool wakeup_parent)
+{
+    struct sigaction sigact;
+	PRStatus rv = PR_SUCCESS;
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+		thread->md.id = getpid();
+        setblockproccnt(thread->md.id, 0);
+		_MD_SET_SPROC_PID(getpid());	
+#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
+		/*
+		 * enable user-level processing of sigprocmask(); this is an
+		 * undocumented feature available in Irix 6.2, 6.3, 6.4 and 6.5
+		 */
+		__sgi_prda_procmask(USER_LEVEL);
+#endif
+		/*
+		 * set up SIGUSR1 handler; this is used to save state
+		 */
+		sigact.sa_handler = save_context_and_block;
+		sigact.sa_flags = SA_RESTART;
+		/*
+		 * Must mask clock interrupts
+		 */
+		sigact.sa_mask = timer_set;
+		sigaction(SIGUSR1, &sigact, 0);
+
+
+		/*
+		 * PR_SETABORTSIG is a new command implemented in a patch to
+		 * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all
+		 * sprocs in the process when one of them terminates abnormally
+		 *
+		 */
+		if (prctl(PR_SETABORTSIG, SIGKILL) < 0) {
+			/*
+			 *  if (errno == EINVAL)
+			 *
+			 *	PR_SETABORTSIG not supported under this OS.
+			 *	You may want to get a recent kernel rollup patch that
+			 *	supports this feature.
+			 */
+		}
+		/*
+		 * SIGCLD handler for detecting abormally-terminating
+		 * sprocs and for reaping sprocs
+		 */
+		sigact.sa_handler = sigchld_handler;
+		sigact.sa_flags = SA_RESTART;
+		sigact.sa_mask = ints_off;
+		sigaction(SIGCLD, &sigact, NULL);
+    }
+	return rv;
+}
+
+/*
+ * PR_Cleanup should be executed on the primordial sproc; migrate the thread
+ * to the primordial cpu
+ */
+
+void _PR_MD_PRE_CLEANUP(PRThread *me)
+{
+PRIntn is;
+_PRCPU *cpu = _pr_primordialCPU;
+
+	PR_ASSERT(cpu);
+
+	me->flags |= _PR_BOUND_THREAD;	
+
+	if (me->cpu->id != 0) {
+		_PR_INTSOFF(is);
+		_PR_RUNQ_LOCK(cpu);
+		me->cpu = cpu;
+		me->state = _PR_RUNNABLE;
+		_PR_ADD_RUNQ(me, cpu, me->priority);
+		_PR_RUNQ_UNLOCK(cpu);
+		_MD_Wakeup_CPUs();
+
+		_PR_MD_SWITCH_CONTEXT(me);
+
+		_PR_FAST_INTSON(is);
+		PR_ASSERT(me->cpu->id == 0);
+	}
+}
+
+/*
+ * process exiting
+ */
+PR_EXTERN(void ) _MD_exit(PRIntn status)
+{
+PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	/*
+	 * the exit code of the process is the exit code of the primordial
+	 * sproc
+	 */
+	if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) {
+		/*
+		 * primordial sproc case: call _exit directly
+		 * Cause SIGKILL to be sent to other sprocs
+		 */
+		prctl(PR_SETEXITSIG, SIGKILL);
+		_exit(status);
+	} else {
+		int rv;
+		char data;
+		sigset_t set;
+
+		/*
+		 * non-primordial sproc case: cause the primordial sproc, cpu 0,
+		 * to wakeup and call _exit
+		 */
+		_pr_irix_process_exit = 1;
+		_pr_irix_process_exit_code = status;
+		rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
+		PR_ASSERT(rv == 1);
+		/*
+		 * block all signals and wait for SIGKILL to terminate this sproc
+		 */
+		sigfillset(&set);
+		sigsuspend(&set);
+		/*
+		 * this code doesn't (shouldn't) execute
+		 */
+		prctl(PR_SETEXITSIG, SIGKILL);
+		_exit(status);
+	}
+}
+
+/*
+ * Override the exit() function in libc to cause the process to exit
+ * when the primodial/main nspr thread calls exit. Calls to exit by any
+ * other thread simply result in a call to the exit function in libc.
+ * The exit code of the process is the exit code of the primordial
+ * sproc.
+ */
+
+void exit(int status)
+{
+PRThread *me, *thr;
+PRCList *qp;
+
+	if (!_pr_initialized)  {
+		if (!libc_exit) {
+
+			if (!libc_handle)
+				libc_handle = dlopen("libc.so",RTLD_NOW);
+			if (libc_handle)
+				libc_exit = (void (*)(int)) dlsym(libc_handle, "exit");
+		}
+		if (libc_exit)
+			(*libc_exit)(status);
+		else
+			_exit(status);
+	}
+
+	me = _PR_MD_CURRENT_THREAD();
+
+	if (me == NULL) 		/* detached thread */
+		(*libc_exit)(status);
+
+	PR_ASSERT(_PR_IS_NATIVE_THREAD(me) ||
+						(_PR_MD_CURRENT_CPU())->id == me->cpu->id);
+
+	if (me->flags & _PR_PRIMORDIAL) {
+
+		me->flags |= _PR_BOUND_THREAD;	
+
+		PR_ASSERT((_PR_MD_CURRENT_CPU())->id == me->cpu->id);
+		if (me->cpu->id != 0) {
+			_PRCPU *cpu = _pr_primordialCPU;
+			PRIntn is;
+
+			_PR_INTSOFF(is);
+			_PR_RUNQ_LOCK(cpu);
+			me->cpu = cpu;
+			me->state = _PR_RUNNABLE;
+			_PR_ADD_RUNQ(me, cpu, me->priority);
+			_PR_RUNQ_UNLOCK(cpu);
+			_MD_Wakeup_CPUs();
+
+			_PR_MD_SWITCH_CONTEXT(me);
+
+			_PR_FAST_INTSON(is);
+		}
+
+		PR_ASSERT((_PR_MD_CURRENT_CPU())->id == 0);
+
+		if (prctl(PR_GETNSHARE) > 1) {
+#define SPROC_EXIT_WAIT_TIME 5
+			int sleep_cnt = SPROC_EXIT_WAIT_TIME;
+
+			/*
+			 * sprocs still running; caue cpus and recycled global threads
+			 * to exit
+			 */
+			_pr_irix_exit_now = 1;
+			if (_pr_numCPU > 1) {
+				_MD_Wakeup_CPUs();
+			}
+			 _PR_DEADQ_LOCK;
+			 if (_PR_NUM_DEADNATIVE != 0) {
+				PRThread *thread;
+				PRCList *ptr;
+
+				ptr = _PR_DEADNATIVEQ.next;
+				while( ptr != &_PR_DEADNATIVEQ ) {
+					thread = _PR_THREAD_PTR(ptr);
+					_MD_CVAR_POST_SEM(thread);
+					ptr = ptr->next;
+				} 
+			 }
+
+			while (sleep_cnt-- > 0) {
+				if (waitpid(0, NULL, WNOHANG) >= 0) 
+					sleep(1);
+				else
+					break;
+			}
+			prctl(PR_SETEXITSIG, SIGKILL);
+		}
+		(*libc_exit)(status);
+	} else {
+		/*
+		 * non-primordial thread; simply call exit in libc.
+		 */
+		(*libc_exit)(status);
+	}
+}
+
+
+void
+_MD_InitRunningCPU(_PRCPU *cpu)
+{
+    extern int _pr_md_pipefd[2];
+
+    _MD_unix_init_running_cpu(cpu);
+    cpu->md.id = getpid();
+	_MD_SET_SPROC_PID(getpid());	
+	if (_pr_md_pipefd[0] >= 0) {
+    	_PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0];
+#ifndef _PR_USE_POLL
+    	FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu));
+#endif
+	}
+}
+
+void
+_MD_ExitThread(PRThread *thread)
+{
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        _MD_ATOMIC_DECREMENT(&_pr_md_irix_sprocs);
+        _MD_CLEAN_THREAD(thread);
+        _MD_SET_CURRENT_THREAD(NULL);
+    }
+}
+
+void
+_MD_SuspendCPU(_PRCPU *cpu)
+{
+    PRInt32 rv;
+
+	cpu->md.suspending_id = getpid();
+	rv = kill(cpu->md.id, SIGUSR1);
+	PR_ASSERT(rv == 0);
+	/*
+	 * now, block the current thread/cpu until woken up by the suspended
+	 * thread from it's SIGUSR1 signal handler
+	 */
+	blockproc(getpid());
+
+}
+
+void
+_MD_ResumeCPU(_PRCPU *cpu)
+{
+    unblockproc(cpu->md.id);
+}
+
+#if 0
+/*
+ * save the register context of a suspended sproc
+ */
+void get_context(PRThread *thr)
+{
+    int len, fd;
+    char pidstr[24];
+    char path[24];
+
+    /*
+     * open the file corresponding to this process in procfs
+     */
+    sprintf(path,"/proc/%s","00000");
+    len = strlen(path);
+    sprintf(pidstr,"%d",thr->md.id);
+    len -= strlen(pidstr);
+    sprintf(path + len,"%s",pidstr);
+    fd = open(path,O_RDONLY);
+    if (fd >= 0) {
+        (void) ioctl(fd, PIOCGREG, thr->md.gregs);
+        close(fd);
+    }
+    return;
+}
+#endif	/* 0 */
+
+void
+_MD_SuspendThread(PRThread *thread)
+{
+    PRInt32 rv;
+
+    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
+        _PR_IS_GCABLE_THREAD(thread));
+
+	thread->md.suspending_id = getpid();
+	rv = kill(thread->md.id, SIGUSR1);
+	PR_ASSERT(rv == 0);
+	/*
+	 * now, block the current thread/cpu until woken up by the suspended
+	 * thread from it's SIGUSR1 signal handler
+	 */
+	blockproc(getpid());
+}
+
+void
+_MD_ResumeThread(PRThread *thread)
+{
+    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
+        _PR_IS_GCABLE_THREAD(thread));
+    (void)unblockproc(thread->md.id);
+}
+
+/*
+ * return the set of processors available for scheduling procs in the
+ * "mask" argument
+ */
+PRInt32 _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask)
+{
+    PRInt32 nprocs, rv;
+    struct pda_stat *pstat;
+#define MAX_PROCESSORS    32
+
+    nprocs = sysmp(MP_NPROCS);
+    if (nprocs < 0)
+        return(-1);
+    pstat = (struct pda_stat*)PR_MALLOC(sizeof(struct pda_stat) * nprocs);
+    if (pstat == NULL)
+        return(-1);
+    rv = sysmp(MP_STAT, pstat);
+    if (rv < 0) {
+        PR_DELETE(pstat);
+        return(-1);
+    }
+    /*
+     * look at the first 32 cpus
+     */
+    nprocs = (nprocs > MAX_PROCESSORS) ? MAX_PROCESSORS : nprocs;
+    *mask = 0;
+    while (nprocs) {
+        if ((pstat->p_flags & PDAF_ENABLED) &&
+            !(pstat->p_flags & PDAF_ISOLATED)) {
+            *mask |= (1 << pstat->p_cpuid);
+        }
+        nprocs--;
+        pstat++;
+    }
+    return 0;
+}
+
+static char *_thr_state[] = {
+    "UNBORN",
+    "RUNNABLE",
+    "RUNNING",
+    "LOCK_WAIT",
+    "COND_WAIT",
+    "JOIN_WAIT",
+    "IO_WAIT",
+    "SUSPENDED",
+    "DEAD"
+};
+
+void _PR_List_Threads()
+{
+    PRThread *thr;
+    void *handle;
+    struct _PRCPU *cpu;
+    PRCList *qp;
+    int len, fd;
+    char pidstr[24];
+    char path[24];
+    prpsinfo_t pinfo;
+
+
+    printf("\n%s %-s\n"," ","LOCAL Threads");
+    printf("%s %-s\n"," ","----- -------");
+    printf("%s %-14s %-10s %-12s %-3s %-10s %-10s %-12s\n\n"," ",
+        "Thread", "State", "Wait-Handle",
+        "Cpu","Stk-Base","Stk-Sz","SP");
+    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
+        qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
+        thr = _PR_ACTIVE_THREAD_PTR(qp);
+        printf("%s 0x%-12x %-10s "," ",thr,_thr_state[thr->state]);
+        if (thr->state == _PR_LOCK_WAIT)
+            handle = thr->wait.lock;
+        else if (thr->state == _PR_COND_WAIT)
+            handle = thr->wait.cvar;
+        else
+            handle = NULL;
+        if (handle)
+            printf("0x%-10x ",handle);
+        else
+            printf("%-12s "," ");
+        printf("%-3d ",thr->cpu->id);
+        printf("0x%-8x ",thr->stack->stackBottom);
+        printf("0x%-8x ",thr->stack->stackSize);
+        printf("0x%-10x\n",thr->md.jb[JB_SP]);
+    }
+
+    printf("\n%s %-s\n"," ","GLOBAL Threads");
+    printf("%s %-s\n"," ","------ -------");
+    printf("%s %-14s %-6s %-12s %-12s %-12s %-12s\n\n"," ","Thread",
+        "Pid","State","Wait-Handle",
+        "Stk-Base","Stk-Sz");
+
+    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
+        qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
+        thr = _PR_ACTIVE_THREAD_PTR(qp);
+        if (thr->cpu != NULL)
+            continue;        /* it is a cpu thread */
+        printf("%s 0x%-12x %-6d "," ",thr,thr->md.id);
+        /*
+         * check if the sproc is still running
+         * first call prctl(PR_GETSHMASK,pid) to check if
+         * the process is part of the share group (the pid
+         * could have been recycled by the OS)
+         */
+        if (prctl(PR_GETSHMASK,thr->md.id) < 0) {
+            printf("%-12s\n","TERMINATED");
+            continue;
+        }
+        /*
+         * Now, check if the sproc terminated and is in zombie
+         * state
+         */
+        sprintf(path,"/proc/pinfo/%s","00000");
+        len = strlen(path);
+        sprintf(pidstr,"%d",thr->md.id);
+        len -= strlen(pidstr);
+        sprintf(path + len,"%s",pidstr);
+        fd = open(path,O_RDONLY);
+        if (fd >= 0) {
+            if (ioctl(fd, PIOCPSINFO, &pinfo) < 0)
+                printf("%-12s ","TERMINATED");
+            else if (pinfo.pr_zomb)
+                printf("%-12s ","TERMINATED");
+            else
+                printf("%-12s ",_thr_state[thr->state]);
+            close(fd);
+        } else {
+            printf("%-12s ","TERMINATED");
+        }
+
+        if (thr->state == _PR_LOCK_WAIT)
+            handle = thr->wait.lock;
+        else if (thr->state == _PR_COND_WAIT)
+            handle = thr->wait.cvar;
+        else
+            handle = NULL;
+        if (handle)
+            printf("%-12x ",handle);
+        else
+            printf("%-12s "," ");
+        printf("0x%-10x ",thr->stack->stackBottom);
+        printf("0x%-10x\n",thr->stack->stackSize);
+    }
+
+    printf("\n%s %-s\n"," ","CPUs");
+    printf("%s %-s\n"," ","----");
+    printf("%s %-14s %-6s %-12s \n\n"," ","Id","Pid","State");
+
+
+    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
+        cpu = _PR_CPU_PTR(qp);
+        printf("%s %-14d %-6d "," ",cpu->id,cpu->md.id);
+        /*
+         * check if the sproc is still running
+         * first call prctl(PR_GETSHMASK,pid) to check if
+         * the process is part of the share group (the pid
+         * could have been recycled by the OS)
+         */
+        if (prctl(PR_GETSHMASK,cpu->md.id) < 0) {
+            printf("%-12s\n","TERMINATED");
+            continue;
+        }
+        /*
+         * Now, check if the sproc terminated and is in zombie
+         * state
+         */
+        sprintf(path,"/proc/pinfo/%s","00000");
+        len = strlen(path);
+        sprintf(pidstr,"%d",cpu->md.id);
+        len -= strlen(pidstr);
+        sprintf(path + len,"%s",pidstr);
+        fd = open(path,O_RDONLY);
+        if (fd >= 0) {
+            if (ioctl(fd, PIOCPSINFO, &pinfo) < 0)
+                printf("%-12s\n","TERMINATED");
+            else if (pinfo.pr_zomb)
+                printf("%-12s\n","TERMINATED");
+            else
+                printf("%-12s\n","RUNNING");
+            close(fd);
+        } else {
+            printf("%-12s\n","TERMINATED");
+        }
+
+    }
+    fflush(stdout);
+}
+#endif /* defined(_PR_PTHREADS) */ 
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#if !defined(_PR_PTHREADS)
+    if (isCurrent) {
+        (void) setjmp(t->md.jb);
+    }
+    *np = sizeof(t->md.jb) / sizeof(PRWord);
+    return (PRWord *) (t->md.jb);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+void _MD_EarlyInit(void)
+{
+#if !defined(_PR_PTHREADS)
+    char *eval;
+    int fd;
+	extern int __ateachexit(void (*func)(void));
+
+    sigemptyset(&ints_off);
+    sigaddset(&ints_off, SIGALRM);
+    sigaddset(&ints_off, SIGIO);
+    sigaddset(&ints_off, SIGCLD);
+
+    if (eval = getenv("_NSPR_TERMINATE_ON_ERROR"))
+        _nspr_terminate_on_error = (0 == atoi(eval) == 0) ? PR_FALSE : PR_TRUE;
+
+    fd = open("/dev/zero",O_RDWR , 0);
+    if (fd < 0) {
+        perror("open /dev/zero failed");
+        exit(1);
+    }
+    /*
+     * Set up the sproc private data area.
+     * This region exists at the same address, _nspr_sproc_private, for
+     * every sproc, but each sproc gets a private copy of the region.
+     */
+    _nspr_sproc_private = (char*)mmap(0, _pr_pageSize, PROT_READ | PROT_WRITE,
+        MAP_PRIVATE| MAP_LOCAL, fd, 0);
+    if (_nspr_sproc_private == (void*)-1) {
+        perror("mmap /dev/zero failed");
+        exit(1);
+    }
+	_MD_SET_SPROC_PID(getpid());	
+    close(fd);
+	__ateachexit(irix_detach_sproc);
+#endif
+    _MD_IrixIntervalInit();
+}  /* _MD_EarlyInit */
+
+void _MD_IrixInit(void)
+{
+#if !defined(_PR_PTHREADS)
+    struct sigaction sigact;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+	int rv;
+
+#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
+	/*
+	 * enable user-level processing of sigprocmask(); this is an undocumented
+	 * feature available in Irix 6.2, 6.3, 6.4 and 6.5
+	 */
+	__sgi_prda_procmask(USER_LEVEL);
+#endif
+
+	/*
+	 * set up SIGUSR1 handler; this is used to save state
+	 * during PR_SuspendAll
+	 */
+	sigact.sa_handler = save_context_and_block;
+	sigact.sa_flags = SA_RESTART;
+	sigact.sa_mask = ints_off;
+	sigaction(SIGUSR1, &sigact, 0);
+
+    /*
+     * Change the name of the core file from core to core.pid,
+     * This is inherited by the sprocs created by this process
+     */
+#ifdef PR_COREPID
+    prctl(PR_COREPID, 0, 1);
+#endif
+    /*
+     * Irix-specific terminate on error processing
+     */
+	/*
+	 * PR_SETABORTSIG is a new command implemented in a patch to
+	 * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all
+	 * sprocs in the process when one of them terminates abnormally
+	 *
+	 */
+	if (prctl(PR_SETABORTSIG, SIGKILL) < 0) {
+		/*
+		 *  if (errno == EINVAL)
+		 *
+		 *	PR_SETABORTSIG not supported under this OS.
+		 *	You may want to get a recent kernel rollup patch that
+		 *	supports this feature.
+		 *
+		 */
+	}
+	/*
+	 * PR_SETEXITSIG -  send the SIGCLD signal to the parent
+	 *            sproc when any sproc terminates
+	 *
+	 *    This is used to cause the entire application to
+	 *    terminate when    any sproc terminates abnormally by
+	 *     receipt of a SIGSEGV, SIGBUS or SIGABRT signal.
+	 *    If this is not done, the application may seem
+	 *     "hung" to the user because the other sprocs may be
+	 *    waiting for resources held by the
+	 *    abnormally-terminating sproc.
+	 */
+	prctl(PR_SETEXITSIG, 0);
+
+	sigact.sa_handler = sigchld_handler;
+	sigact.sa_flags = SA_RESTART;
+	sigact.sa_mask = ints_off;
+	sigaction(SIGCLD, &sigact, NULL);
+
+    /*
+     * setup stack fields for the primordial thread
+     */
+    me->stack->stackSize = prctl(PR_GETSTACKSIZE);
+    me->stack->stackBottom = me->stack->stackTop - me->stack->stackSize;
+
+    rv = pipe(_pr_irix_primoridal_cpu_fd);
+    PR_ASSERT(rv == 0);
+#ifndef _PR_USE_POLL
+    _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0];
+    FD_SET(_pr_irix_primoridal_cpu_fd[0], &_PR_FD_READ_SET(me->cpu));
+#endif
+
+	libc_handle = dlopen("libc.so",RTLD_NOW);
+	PR_ASSERT(libc_handle != NULL);
+	libc_exit = (void (*)(int)) dlsym(libc_handle, "exit");
+	PR_ASSERT(libc_exit != NULL);
+	/* dlclose(libc_handle); */
+
+#endif /* _PR_PTHREADS */
+
+    _PR_UnixInit();
+}
+
+/**************************************************************************/
+/************** code and such for NSPR 2.0's interval times ***************/
+/**************************************************************************/
+
+#define PR_PSEC_PER_SEC 1000000000000ULL  /* 10^12 */
+
+#ifndef SGI_CYCLECNTR_SIZE
+#define SGI_CYCLECNTR_SIZE      165     /* Size user needs to use to read CC */
+#endif
+
+static PRIntn mmem_fd = -1;
+static PRIntn clock_width = 0;
+static void *iotimer_addr = NULL;
+static PRUint32 pr_clock_mask = 0;
+static PRUint32 pr_clock_shift = 0;
+static PRIntervalTime pr_ticks = 0;
+static PRUint32 pr_clock_granularity = 1;
+static PRUint32 pr_previous = 0, pr_residual = 0;
+static PRUint32 pr_ticks_per_second = 0;
+
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+static void _MD_IrixIntervalInit(void)
+{
+    /*
+     * As much as I would like, the service available through this
+     * interface on R3000's (aka, IP12) just isn't going to make it.
+     * The register is only 24 bits wide, and rolls over at a verocious
+     * rate.
+     */
+    PRUint32 one_tick = 0;
+    struct utsname utsinfo;
+    uname(&utsinfo);
+    if ((strncmp("IP12", utsinfo.machine, 4) != 0)
+        && ((mmem_fd = open("/dev/mmem", O_RDONLY)) != -1))
+    {
+        int poffmask = getpagesize() - 1;
+        __psunsigned_t phys_addr, raddr, cycleval;
+
+        phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
+        raddr = phys_addr & ~poffmask;
+        iotimer_addr = mmap(
+            0, poffmask, PROT_READ, MAP_PRIVATE, mmem_fd, (__psint_t)raddr);
+
+        clock_width = syssgi(SGI_CYCLECNTR_SIZE);
+        if (clock_width < 0)
+        {
+            /* 
+             * We must be executing on a 6.0 or earlier system, since the
+             * SGI_CYCLECNTR_SIZE call is not supported.
+             * 
+             * The only pre-6.1 platforms with 64-bit counters are
+             * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
+             */
+            if (!strncmp(utsinfo.machine, "IP19", 4) ||
+                !strncmp(utsinfo.machine, "IP21", 4))
+                clock_width = 64;
+            else
+                clock_width = 32;
+        }
+
+        /*
+         * 'cycleval' is picoseconds / increment of the counter.
+         * I'm pushing for a tick to be 100 microseconds, 10^(-4).
+         * That leaves 10^(-8) left over, or 10^8 / cycleval.
+         * Did I do that right?
+         */
+
+        one_tick =  100000000UL / cycleval ;  /* 100 microseconds */
+
+        while (0 != one_tick)
+        {
+            pr_clock_shift += 1;
+            one_tick = one_tick >> 1;
+            pr_clock_granularity = pr_clock_granularity << 1;
+        }
+        pr_clock_mask = pr_clock_granularity - 1;  /* to make a mask out of it */
+        pr_ticks_per_second = PR_PSEC_PER_SEC
+                / ((PRUint64)pr_clock_granularity * (PRUint64)cycleval);
+            
+        iotimer_addr = (void*)
+            ((__psunsigned_t)iotimer_addr + (phys_addr & poffmask));
+    }
+    else
+    {
+        pr_ticks_per_second = _PR_UNIX_TicksPerSecond();
+    }
+}  /* _MD_IrixIntervalInit */
+
+PRIntervalTime _MD_IrixIntervalPerSec(void)
+{
+    return pr_ticks_per_second;
+}
+
+PRIntervalTime _MD_IrixGetInterval(void)
+{
+    if (mmem_fd != -1)
+    {
+        if (64 == clock_width)
+        {
+            PRUint64 temp = *(PRUint64*)iotimer_addr;
+            pr_ticks = (PRIntervalTime)(temp >> pr_clock_shift);
+        }
+        else
+        {
+            PRIntervalTime ticks = pr_ticks;
+            PRUint32 now = *(PRUint32*)iotimer_addr, temp;
+            PRUint32 residual = pr_residual, previous = pr_previous;
+
+            temp = now - previous + residual;
+            residual = temp & pr_clock_mask;
+            ticks += temp >> pr_clock_shift;
+
+            pr_previous = now;
+            pr_residual = residual;
+            pr_ticks = ticks;
+        }
+    }
+    else
+    {
+        /*
+         * No fast access. Use the time of day clock. This isn't the
+         * right answer since this clock can get set back, tick at odd
+         * rates, and it's expensive to acqurie.
+         */
+        pr_ticks = _PR_UNIX_GetInterval();
+    }
+    return pr_ticks;
+}  /* _MD_IrixGetInterval */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/linux.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/linux.c
new file mode 100644
index 0000000..c22618d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/linux.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifdef _PR_PTHREADS
+
+extern void _MD_unix_terminate_waitpid_daemon(void);
+
+void _MD_CleanupBeforeExit(void)
+{
+    _MD_unix_terminate_waitpid_daemon();
+}
+
+#else /* ! _PR_PTHREADS */
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	/*
+	 * set the pointers to the stack-pointer and frame-pointer words in the
+	 * context structure; this is for debugging use.
+	 */
+	thread->md.sp = _MD_GET_SP_PTR(thread);
+	thread->md.fp = _MD_GET_FP_PTR(thread);
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Linux */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Linux.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Linux.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/ncr.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/ncr.c
new file mode 100644
index 0000000..909b09e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/ncr.c
@@ -0,0 +1,395 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * NCR 3.0  - cloned from UnixWare by ruslan
+ */
+#include "primpl.h"
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+#ifdef ALARMS_BREAK_TCP /* I don't think they do */
+
+PRInt32 _MD_connect(PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _connect(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+}
+
+PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _accept(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+    return(rv);
+}
+#endif
+
+/*
+ * These are also implemented in pratom.c using NSPR locks.  Any reason
+ * this might be better or worse?  If you like this better, define
+ * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h
+ */
+#ifdef _PR_HAVE_ATOMIC_OPS
+/* Atomic operations */
+#include  <stdio.h>
+static FILE *_uw_semf;
+
+void
+_MD_INIT_ATOMIC(void)
+{
+    /* Sigh.  Sure wish SYSV semaphores weren't such a pain to use */
+    if ((_uw_semf = tmpfile()) == NULL)
+        PR_ASSERT(0);
+
+    return;
+}
+
+void
+_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)++;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    flockfile(_uw_semf);
+    (*ptr) += val;
+    unflockfile(_uw_semf);
+}
+
+
+void
+_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)--;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    flockfile(_uw_semf);
+    *val = newval;
+    unflockfile(_uw_semf);
+}
+#endif
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Unixware */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Unixware.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRUintn priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware.");
+    return PR_FAILURE;
+}
+
+/*
+ This is temp. replacement for localtime_r. Normally PR_ExplodeTime should
+ be used as to my understanding
+*/
+
+/*
+** $$$$$ THEN WHY ARE WE DOING THIS? - AOF $$$$$
+*/
+
+#define NEED_LOCALTIME_R
+#define NEED_GMTIME_R
+#define NEED_ASCTIME_R
+#define NEED_STRTOK_R
+#define NEED_CTIME_R
+
+#if defined (NEED_LOCALTIME_R) || defined (NEED_CTIME_R) || defined (NEED_ASCTIME_R) || defined (NEED_GMTIME_R) || defined (NEED_STRTOK_R)
+#include "prlock.h"
+#endif
+
+#if defined (NEED_LOCALTIME_R)
+
+static PRLock *localtime_r_monitor = NULL;
+
+struct tm *localtime_r (const time_t *clock, struct tm *result)
+{
+    struct tm *tmPtr;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+        if (localtime_r_monitor == NULL) {
+
+            localtime_r_monitor = PR_NewLock();
+        }
+        PR_Lock(localtime_r_monitor);
+    }
+
+    /*
+     * On Windows, localtime() returns a NULL pointer if 'clock'
+     * represents a time before midnight January 1, 1970.  In
+     * that case, we also return a NULL pointer and the struct tm
+     * object pointed to by 'result' is not modified.
+     */
+
+    tmPtr = localtime(clock);
+    if (tmPtr) {
+        *result = *tmPtr;
+    } else {
+        result = NULL;
+    }
+
+    if (needLock) PR_Unlock(localtime_r_monitor);
+
+    return result;
+}
+
+#endif
+
+#if defined (NEED_GMTIME_R)
+
+static PRLock *gmtime_r_monitor = NULL;
+
+struct tm *gmtime_r (const time_t *clock, struct tm *result)
+{
+    struct tm *tmPtr;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+        if (gmtime_r_monitor == NULL) {
+            gmtime_r_monitor = PR_NewLock();
+        }
+        PR_Lock(gmtime_r_monitor);
+    }
+
+    tmPtr = gmtime(clock);
+    if (tmPtr) {
+        *result = *tmPtr;
+    } else {
+        result = NULL;
+    }
+
+    if (needLock) PR_Unlock(gmtime_r_monitor);
+
+    return result;
+}
+
+#endif
+
+#if defined (NEED_CTIME_R)
+
+static PRLock *ctime_r_monitor = NULL;
+
+char  *ctime_r (const time_t *clock, char *buf, int buflen)
+{
+    char *cbuf;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+
+        if (ctime_r_monitor == NULL) {
+            ctime_r_monitor = PR_NewLock();
+        }
+        PR_Lock(ctime_r_monitor);
+    }
+
+    cbuf = ctime (clock);
+    if (cbuf) {
+        strncpy (buf, cbuf, buflen - 1);
+        buf[buflen - 1] = 0;
+    }
+
+    if (needLock) PR_Unlock(ctime_r_monitor);
+
+    return cbuf;
+}
+
+#endif
+
+#if defined (NEED_ASCTIME_R)
+
+static PRLock *asctime_r_monitor = NULL;
+
+
+char  *asctime_r (const struct tm  *tm, char *buf, int buflen)
+{
+    char *cbuf;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+        if (asctime_r_monitor == NULL) {
+            asctime_r_monitor = PR_NewLock();
+        }
+        PR_Lock(asctime_r_monitor);
+    }
+
+    cbuf = asctime (tm);
+    if (cbuf) {
+        strncpy (buf, cbuf, buflen - 1);
+        buf[buflen - 1] = 0;
+    }
+
+    if (needLock) PR_Unlock(asctime_r_monitor);
+
+    return cbuf;
+
+}
+#endif
+
+#if defined (NEED_STRTOK_R)
+
+char *
+strtok_r (s, delim, last)
+        register char *s;
+        register const char *delim;
+        register char **last;
+{
+        register char *spanp;
+        register int c, sc;
+        char *tok;
+
+
+        if (s == NULL && (s = *last) == NULL)
+                return (NULL);
+
+        /*
+         * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+         */
+cont:
+
+        c = *s++;
+        for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+                if (c == sc)
+                        goto cont;
+        }
+
+        if (c == 0) {           /* no non-delimiter characters */
+                *last = NULL;
+                return (NULL);
+        }
+        tok = s - 1;
+
+        /*
+         * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+         * Note that delim must have one NUL; we stop if we see that, too.
+         */
+        for (;;) {
+                c = *s++;
+                spanp = (char *)delim;
+                do {
+                        if ((sc = *spanp++) == c) {
+                                if (c == 0)
+                                        s = NULL;
+
+                                else
+                                        s[-1] = 0;
+                                *last = s;
+                                return (tok);
+                        }
+                } while (sc != 0);
+        }
+        /* NOTREACHED */
+}
+
+#endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nec.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nec.c
new file mode 100644
index 0000000..8c97b75
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nec.c
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for NEC */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for NEC.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NEC.");
+	return PR_FAILURE;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/netbsd.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/netbsd.c
new file mode 100644
index 0000000..fdef8d7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/netbsd.c
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <signal.h>
+#include <poll.h>
+#include <sys/syscall.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+        (void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+    *np = 0;
+    return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+        PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for NetBSD */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for NetBSD.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NetBSD.");
+    return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nextstep.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nextstep.c
new file mode 100644
index 0000000..3f87815
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nextstep.c
@@ -0,0 +1,284 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#import <mach/mach.h>
+#import <mach/mach_error.h>
+#import <mach-o/dyld.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <syscall.h>
+
+
+
+/*	These functions are hidden in NEXTSTEP, but beacuse they have syscall()
+**	entries I can wrap these into their corresponding missing function.
+*/
+caddr_t
+mmap(caddr_t addr, size_t len, int prot, int flags,
+          int fildes, off_t off)
+{
+	return (caddr_t) syscall (SYS_mmap, addr, len, prot, flags, fildes, off);
+}
+
+int
+munmap(caddr_t addr, size_t len)
+{
+	return syscall (SYS_munmap, addr, len);
+}
+
+int
+mprotect(caddr_t addr, size_t len, int prot)
+{
+	return syscall (SYS_mprotect, addr, len, prot);
+}
+
+
+/* If found the brk() symbol in the sahred libraries but no syscall() entry ...
+** I don't know whether it will work ...
+int brk(void *endds)
+{
+	return syscall ();
+}
+*/
+
+void *sbrk(int incr)
+{
+	return (void *) syscall (SYS_sbrk, incr);
+}
+
+/*	These are my mach based versions, untested and probably bad ...
+*/
+caddr_t my_mmap(caddr_t addr, size_t len, int prot, int flags,
+          int fildes, off_t off)
+{
+	kern_return_t ret_val;
+	
+	/*	First map ...
+	*/
+	ret_val = map_fd ( fildes, 					/* fd				*/
+	                  (vm_offset_t) off,		/* offset			*/
+					  (vm_offset_t*)&addr,		/* address			*/
+					  TRUE, 					/* find_space		*/
+					  (vm_size_t) len);			/* size				*/
+
+	if (ret_val != KERN_SUCCESS) {
+    	mach_error("Error calling map_fd() in mmap", ret_val );
+		return (caddr_t)0;
+	}
+	
+	/*	... then protect (this is probably bad)
+	*/
+	ret_val = vm_protect( task_self(),			/* target_task 		*/
+						 (vm_address_t)addr,	/* address			*/
+						 (vm_size_t) len,		/* size 			*/
+						 FALSE,					/* set_maximum		*/
+						 (vm_prot_t) prot);		/* new_protection	*/
+	if (ret_val != KERN_SUCCESS) {
+		mach_error("vm_protect in mmap()", ret_val );
+		return (caddr_t)0;
+	}
+	
+	return addr;
+}
+
+int my_munmap(caddr_t addr, size_t len)
+{
+	kern_return_t ret_val;
+
+	ret_val = vm_deallocate(task_self(),
+	 						(vm_address_t) addr,
+							(vm_size_t) len);
+
+	if (ret_val != KERN_SUCCESS) {
+		mach_error("vm_deallocate in munmap()", ret_val);
+		return -1;
+	}
+	
+	return 0;
+}
+
+int my_mprotect(caddr_t addr, size_t len, int prot)
+{
+	vm_prot_t mach_prot;
+	kern_return_t ret_val;
+	
+	switch (prot) {
+		case PROT_READ:		mach_prot = VM_PROT_READ;		break;
+		case PROT_WRITE:	mach_prot = VM_PROT_WRITE;		break;
+		case PROT_EXEC:		mach_prot = VM_PROT_EXECUTE;	break;
+		case PROT_NONE:		mach_prot = VM_PROT_NONE;		break;
+	}
+	
+	ret_val = vm_protect(task_self(),			/* target_task 		*/
+						 (vm_address_t)addr,	/* address			*/
+						 (vm_size_t) len,		/* size 			*/
+						 FALSE,					/* set_maximum		*/
+						 (vm_prot_t) prot);		/* new_protection	*/
+
+	if (ret_val != KERN_SUCCESS) {
+		mach_error("vm_protect in mprotect()", ret_val);
+		return -1;
+	}
+	
+	return 0;
+}
+
+char *strdup(const char *s1)
+{
+	int len = strlen (s1);
+	char *copy = (char*) malloc (len+1);
+	
+	if (copy == (char*)0)
+		return (char*)0;
+
+	strcpy (copy, s1);
+
+	return copy;
+}
+
+/* Stub rld functions
+*/
+extern NSObjectFileImageReturnCode NSCreateObjectFileImageFromFile(
+    const char *pathName,
+    NSObjectFileImage *objectFileImage)
+{
+	return NSObjectFileImageFailure;
+}
+
+extern void * NSAddressOfSymbol(
+    NSSymbol symbol)
+{
+	return NULL;
+}
+
+extern NSModule NSLinkModule(
+    NSObjectFileImage objectFileImage, 
+    const char *moduleName, /* can be NULL */
+    enum bool bindNow)
+{
+	return NULL;
+}
+
+extern NSSymbol NSLookupAndBindSymbol(
+    const char *symbolName)
+{
+	return NULL;
+}
+
+extern enum bool NSUnLinkModule(
+    NSModule module, 
+    enum bool keepMemoryMapped)
+{
+	return 0;
+}
+
+
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for NEXTSTEP */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for NEXTSTEP.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NEXTSTEP.");
+	return PR_FAILURE;
+}
+
+#endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nto.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nto.c
new file mode 100644
index 0000000..352d93e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/nto.c
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <setjmp.h>
+
+/* Fake this out */
+int socketpair (int foo, int foo2, int foo3, int sv[2])
+{
+	printf("error in socketpair\n");
+	exit (-1);
+}
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+    (void) setjmp(CONTEXT(t));
+    }
+
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/objs.mk b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/objs.mk
new file mode 100644
index 0000000..13f2d7d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/objs.mk
@@ -0,0 +1,63 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This makefile appends to the variable OBJS the platform-dependent
+# object modules that will be part of the nspr20 library.
+
+CSRCS =          \
+	unix.c    \
+	unix_errors.c \
+	uxproces.c \
+	uxrng.c \
+	uxshm.c \
+	uxwrap.c \
+	$(NULL)
+
+ifneq ($(USE_PTHREADS),1)
+CSRCS += uxpoll.c
+endif
+
+ifeq ($(PTHREADS_USER),1)
+CSRCS += pthreads_user.c
+endif
+
+CSRCS	+= $(PR_MD_CSRCS)
+ASFILES += $(PR_MD_ASFILES)
+
+OBJS += $(addprefix md/unix/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)))  \
+	$(addprefix md/unix/$(OBJDIR)/,$(ASFILES:.s=.$(OBJ_SUFFIX)))
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/openbsd.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/openbsd.c
new file mode 100644
index 0000000..1103377
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/openbsd.c
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <signal.h>
+#include <poll.h>
+#include <sys/syscall.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+        (void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+    *np = 0;
+    return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+        PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for OpenBSD */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for OpenBSD.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OpenBSD.");
+    return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_AIX.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_AIX.s
new file mode 100644
index 0000000..976349e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_AIX.s
@@ -0,0 +1,123 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4
+.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
+.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
+.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
+.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
+.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
+.set r30,30; .set r31,31
+
+
+        .rename H.10.NO_SYMBOL{PR},""
+        .rename H.18.longjmp{TC},"longjmp"
+
+        .lglobl H.10.NO_SYMBOL{PR}
+        .globl  .longjmp
+        .globl  longjmp{DS}
+        .extern .sigcleanup
+        .extern .jmprestfpr
+
+# .text section
+
+        .csect  H.10.NO_SYMBOL{PR}
+.longjmp:
+         mr   r13,r3
+         mr   r14,r4
+        stu   SP,-56(SP)
+         bl   .sigcleanup
+          l   RTOC,0x14(SP)
+        cal   SP,0x38(SP)
+         mr   r3,r13
+         mr   r4,r14
+          l   r5,0x8(r3)
+          l   SP,0xc(r3)
+          l   r7,0xf8(r3)
+         st   r7,0x0(SP)
+          l   RTOC,0x10(r3)
+         bl   .jmprestfpr
+# 1 == cr0 in disassembly
+       cmpi   1,r4,0x0  
+       mtlr   r5
+         lm   r13,0x14(r3)
+          l   r5,0x60(r3)
+      mtcrf   0x38,r5
+         mr   r3,r4
+        bne   __L1
+        lil   r3,0x1
+__L1:
+         br
+
+# traceback table
+        .long   0x00000000
+        .byte   0x00                    # VERSION=0
+        .byte   0x00                    # LANG=TB_C
+        .byte   0x20                    # IS_GL=0,IS_EPROL=0,HAS_TBOFF=1
+                                        # INT_PROC=0,HAS_CTL=0,TOCLESS=0
+                                        # FP_PRESENT=0,LOG_ABORT=0
+        .byte   0x40                    # INT_HNDL=0,NAME_PRESENT=1
+                                        # USES_ALLOCA=0,CL_DIS_INV=WALK_ONCOND
+                                        # SAVES_CR=0,SAVES_LR=0
+        .byte   0x80                    # STORES_BC=1,FPR_SAVED=0
+        .byte   0x00                    # GPR_SAVED=0
+        .byte   0x02                    # FIXEDPARMS=2
+        .byte   0x01                    # FLOATPARMS=0,PARMSONSTK=1
+        .long   0x00000000              #
+        .long   0x00000014              # TB_OFFSET
+        .short  7                       # NAME_LEN
+        .byte   "longjmp"
+        .byte   0                       # padding
+        .byte   0                       # padding
+        .byte   0                       # padding
+# End of traceback table
+        .long   0x00000000              # "\0\0\0\0"
+
+# .data section
+
+        .toc                            # 0x00000038
+T.18.longjmp:
+        .tc     H.18.longjmp{TC},longjmp{DS}
+
+        .csect  longjmp{DS}
+        .long   .longjmp                # "\0\0\0\0"
+        .long   TOC{TC0}                # "\0\0\0008"
+        .long   0x00000000              # "\0\0\0\0"
+# End   csect   longjmp{DS}
+
+# .bss section
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_BSD_386_2.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_BSD_386_2.s
new file mode 100644
index 0000000..1c21b91
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_BSD_386_2.s
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * os_BSD_386_2.s
+ * We need to define our own setjmp/longjmp on BSDI 2.x because libc's
+ * implementation does some sanity checking that defeats user level threads.
+ * This should no longer be necessary in BSDI 3.0.
+ */
+
+.globl _setjmp
+.align 2
+_setjmp:
+		movl	4(%esp),%eax
+		movl	0(%esp),%edx
+		movl	%edx, 0(%eax)           /* rta */
+		movl	%ebx, 4(%eax)
+		movl	%esp, 8(%eax)
+		movl	%ebp,12(%eax)
+		movl	%esi,16(%eax)
+		movl	%edi,20(%eax)
+		movl	$0,%eax
+		ret
+ 
+.globl _longjmp
+.align 2
+_longjmp:
+		movl	4(%esp),%edx
+		movl	8(%esp),%eax
+		movl	0(%edx),%ecx
+		movl	4(%edx),%ebx
+		movl	8(%edx),%esp
+		movl	12(%edx),%ebp
+		movl	16(%edx),%esi
+		movl	20(%edx),%edi
+		cmpl	$0,%eax
+		jne		1f
+		movl	$1,%eax
+1:		movl	%ecx,0(%esp)
+		ret
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin.s
new file mode 100644
index 0000000..ce2cc0b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin.s
@@ -0,0 +1,45 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#ifdef __i386__
+#include "os_Darwin_x86.s"
+#elif defined(__x86_64__)
+#include "os_Darwin_x86_64.s"
+#elif defined(__ppc__)
+#include "os_Darwin_ppc.s"
+#endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_ppc.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_ppc.s
new file mode 100644
index 0000000..905ba9f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_ppc.s
@@ -0,0 +1,100 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2003
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# Based on the programming examples in The PowerPC Architecture:
+# A Specification for A New Family of RISC Processors, 2nd Ed.,
+# Book I, Section E.1, "Synchronization," pp. 249-256, May 1994.
+#
+
+.text
+
+#
+# PRInt32 __PR_DarwinPPC_AtomicIncrement(PRInt32 *val);
+#
+        .align  2
+        .globl  __PR_DarwinPPC_AtomicIncrement
+        .private_extern __PR_DarwinPPC_AtomicIncrement
+__PR_DarwinPPC_AtomicIncrement:
+        lwarx   r4,0,r3
+        addi    r0,r4,1
+        stwcx.  r0,0,r3
+        bne-    __PR_DarwinPPC_AtomicIncrement
+        mr      r3,r0
+        blr
+
+#
+# PRInt32 __PR_DarwinPPC_AtomicDecrement(PRInt32 *val);
+#
+        .align  2
+        .globl  __PR_DarwinPPC_AtomicDecrement
+        .private_extern __PR_DarwinPPC_AtomicDecrement
+__PR_DarwinPPC_AtomicDecrement:
+        lwarx   r4,0,r3
+        addi    r0,r4,-1
+        stwcx.  r0,0,r3
+        bne-    __PR_DarwinPPC_AtomicDecrement
+        mr      r3,r0
+        blr
+
+#
+# PRInt32 __PR_DarwinPPC_AtomicSet(PRInt32 *val, PRInt32 newval);
+#
+        .align  2
+        .globl  __PR_DarwinPPC_AtomicSet
+        .private_extern __PR_DarwinPPC_AtomicSet
+__PR_DarwinPPC_AtomicSet:
+        lwarx   r5,0,r3
+        stwcx.  r4,0,r3
+        bne-    __PR_DarwinPPC_AtomicSet
+        mr      r3,r5
+        blr
+
+#
+# PRInt32 __PR_DarwinPPC_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#
+        .align  2
+        .globl  __PR_DarwinPPC_AtomicAdd
+        .private_extern __PR_DarwinPPC_AtomicAdd
+__PR_DarwinPPC_AtomicAdd:
+        lwarx   r5,0,r3
+        add     r0,r4,r5
+        stwcx.  r0,0,r3
+        bne-    __PR_DarwinPPC_AtomicAdd
+        mr      r3,r0
+        blr
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86.s
new file mode 100644
index 0000000..1c7ef8c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86.s
@@ -0,0 +1,113 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2003
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Josh Aas <josh@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# Based on os_Linux_x86.s
+#
+
+#
+# PRInt32 __PR_Darwin_x86_AtomicIncrement(PRInt32 *val);
+#
+# Atomically increment the integer pointed to by 'val' and return
+# the result of the increment.
+#
+    .text
+    .globl __PR_Darwin_x86_AtomicIncrement
+    .private_extern __PR_Darwin_x86_AtomicIncrement
+    .align 4
+__PR_Darwin_x86_AtomicIncrement:
+    movl 4(%esp), %ecx
+    movl $1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    incl %eax
+    ret
+
+#
+# PRInt32 __PR_Darwin_x86_AtomicDecrement(PRInt32 *val);
+#
+# Atomically decrement the integer pointed to by 'val' and return
+# the result of the decrement.
+#
+    .text
+    .globl __PR_Darwin_x86_AtomicDecrement
+    .private_extern __PR_Darwin_x86_AtomicDecrement
+    .align 4
+__PR_Darwin_x86_AtomicDecrement:
+    movl 4(%esp), %ecx
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    decl %eax
+    ret
+
+#
+# PRInt32 __PR_Darwin_x86_AtomicSet(PRInt32 *val, PRInt32 newval);
+#
+# Atomically set the integer pointed to by 'val' to the new
+# value 'newval' and return the old value.
+#
+    .text
+    .globl __PR_Darwin_x86_AtomicSet
+    .private_extern __PR_Darwin_x86_AtomicSet
+    .align 4
+__PR_Darwin_x86_AtomicSet:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    xchgl %eax, (%ecx)
+    ret
+
+#
+# PRInt32 __PR_Darwin_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#
+# Atomically add 'val' to the integer pointed to by 'ptr'
+# and return the result of the addition.
+#
+    .text
+    .globl __PR_Darwin_x86_AtomicAdd
+    .private_extern __PR_Darwin_x86_AtomicAdd
+    .align 4
+__PR_Darwin_x86_AtomicAdd:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    movl %eax, %edx
+    lock
+    xaddl %eax, (%ecx)
+    addl %edx, %eax
+    ret
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86_64.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86_64.s
new file mode 100644
index 0000000..ce41543
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86_64.s
@@ -0,0 +1,99 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1#GPL 2.0#LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http:##www.mozilla.org#MPL#
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2004
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# PRInt32 __PR_Darwin_x86_64_AtomicIncrement(PRInt32 *val)
+#
+# Atomically increment the integer pointed to by 'val' and return
+# the result of the increment.
+#
+    .text
+    .globl __PR_Darwin_x86_64_AtomicIncrement
+    .private_extern __PR_Darwin_x86_64_AtomicIncrement
+    .align 4
+__PR_Darwin_x86_64_AtomicIncrement:
+    movl $1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    incl %eax
+    ret
+
+# PRInt32 __PR_Darwin_x86_64_AtomicDecrement(PRInt32 *val)
+#
+# Atomically decrement the integer pointed to by 'val' and return
+# the result of the decrement.
+#
+    .text
+    .globl __PR_Darwin_x86_64_AtomicDecrement
+    .private_extern __PR_Darwin_x86_64_AtomicDecrement
+    .align 4
+__PR_Darwin_x86_64_AtomicDecrement:
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    decl %eax
+    ret
+
+# PRInt32 __PR_Darwin_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval)
+#
+# Atomically set the integer pointed to by 'val' to the new
+# value 'newval' and return the old value.
+#
+    .text
+    .globl __PR_Darwin_x86_64_AtomicSet
+    .private_extern __PR_Darwin_x86_64_AtomicSet
+    .align 4
+__PR_Darwin_x86_64_AtomicSet:
+    movl %esi, %eax
+    xchgl %eax, (%rdi)
+    ret
+
+# PRInt32 __PR_Darwin_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+#
+# Atomically add 'val' to the integer pointed to by 'ptr'
+# and return the result of the addition.
+#
+    .text
+    .globl __PR_Darwin_x86_64_AtomicAdd
+    .private_extern __PR_Darwin_x86_64_AtomicAdd
+    .align 4
+__PR_Darwin_x86_64_AtomicAdd:
+    movl %esi, %eax
+    lock
+    xaddl %eax, (%rdi)
+    addl %esi, %eax
+    ret
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_HPUX.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_HPUX.s
new file mode 100644
index 0000000..a3bac25
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_HPUX.s
@@ -0,0 +1,57 @@
+; 
+; ***** BEGIN LICENSE BLOCK *****
+; Version: MPL 1.1/GPL 2.0/LGPL 2.1
+;
+; The contents of this file are subject to the Mozilla Public License Version
+; 1.1 (the "License"); you may not use this file except in compliance with
+; the License. You may obtain a copy of the License at
+; http://www.mozilla.org/MPL/
+;
+; Software distributed under the License is distributed on an "AS IS" basis,
+; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+; for the specific language governing rights and limitations under the
+; License.
+;
+; The Original Code is the Netscape Portable Runtime (NSPR).
+;
+; The Initial Developer of the Original Code is
+; Netscape Communications Corporation.
+; Portions created by the Initial Developer are Copyright (C) 1998-2000
+; the Initial Developer. All Rights Reserved.
+;
+; Contributor(s):
+;
+; Alternatively, the contents of this file may be used under the terms of
+; either the GNU General Public License Version 2 or later (the "GPL"), or
+; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+; in which case the provisions of the GPL or the LGPL are applicable instead
+; of those above. If you wish to allow use of your version of this file only
+; under the terms of either the GPL or the LGPL, and not to allow others to
+; use your version of this file under the terms of the MPL, indicate your
+; decision by deleting the provisions above and replace them with the notice
+; and other provisions required by the GPL or the LGPL. If you do not delete
+; the provisions above, a recipient may use your version of this file under
+; the terms of any one of the MPL, the GPL or the LGPL.
+;
+; ***** END LICENSE BLOCK *****
+
+#ifdef __LP64__
+        .LEVEL   2.0W
+#else
+        .LEVEL   1.1
+#endif
+
+	.CODE	; equivalent to the following two lines
+;       .SPACE   $TEXT$,SORT=8
+;       .SUBSPA  $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24
+
+ret_cr16
+	.PROC
+	.CALLINFO 	FRAME=0, NO_CALLS
+	.EXPORT 	ret_cr16,ENTRY
+	.ENTRY
+	BV		%r0(%rp)
+        .EXIT
+	MFCTL		%cr16,%ret0
+        .PROCEND
+        .END
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_HPUX_ia64.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_HPUX_ia64.s
new file mode 100644
index 0000000..9c14793
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_HPUX_ia64.s
@@ -0,0 +1,112 @@
+// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// 
+// ***** BEGIN LICENSE BLOCK *****
+// Version: MPL 1.1/GPL 2.0/LGPL 2.1
+//
+// The contents of this file are subject to the Mozilla Public License Version
+// 1.1 (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+// http://www.mozilla.org/MPL/
+//
+// Software distributed under the License is distributed on an "AS IS" basis,
+// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+// for the specific language governing rights and limitations under the
+// License.
+//
+// The Original Code is the Netscape Portable Runtime (NSPR).
+//
+// The Initial Developer of the Original Code is
+// Netscape Communications Corporation.
+// Portions created by the Initial Developer are Copyright (C) 2000
+// the Initial Developer. All Rights Reserved.
+//
+// Contributor(s):
+//
+// Alternatively, the contents of this file may be used under the terms of
+// either the GNU General Public License Version 2 or later (the "GPL"), or
+// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+// in which case the provisions of the GPL or the LGPL are applicable instead
+// of those above. If you wish to allow use of your version of this file only
+// under the terms of either the GPL or the LGPL, and not to allow others to
+// use your version of this file under the terms of the MPL, indicate your
+// decision by deleting the provisions above and replace them with the notice
+// and other provisions required by the GPL or the LGPL. If you do not delete
+// the provisions above, a recipient may use your version of this file under
+// the terms of any one of the MPL, the GPL or the LGPL.
+//
+// ***** END LICENSE BLOCK *****
+
+.text
+
+// PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val)
+//
+// Atomically increment the integer pointed to by 'val' and return
+// the result of the increment.
+//
+        .align 16
+        .global _PR_ia64_AtomicIncrement#
+        .proc _PR_ia64_AtomicIncrement#
+_PR_ia64_AtomicIncrement:
+#ifndef _LP64
+        addp4 r32 = 0, r32  ;;
+#endif
+        fetchadd4.acq r8 = [r32], 1  ;;
+        adds r8 = 1, r8
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicIncrement#
+
+// PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val)
+//
+// Atomically decrement the integer pointed to by 'val' and return
+// the result of the decrement.
+//
+        .align 16
+        .global _PR_ia64_AtomicDecrement#
+        .proc _PR_ia64_AtomicDecrement#
+_PR_ia64_AtomicDecrement:
+#ifndef _LP64
+        addp4 r32 = 0, r32  ;;
+#endif
+        fetchadd4.rel r8 = [r32], -1  ;;
+        adds r8 = -1, r8
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicDecrement#
+
+// PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+//
+// Atomically add 'val' to the integer pointed to by 'ptr'
+// and return the result of the addition.
+//
+        .align 16
+        .global _PR_ia64_AtomicAdd#
+        .proc _PR_ia64_AtomicAdd#
+_PR_ia64_AtomicAdd:
+#ifndef _LP64
+        addp4 r32 = 0, r32  ;;
+#endif
+        ld4 r15 = [r32]  ;;
+.L3:
+        mov r14 = r15
+        mov ar.ccv = r15
+        add r8 = r15, r33  ;;
+        cmpxchg4.acq r15 = [r32], r8, ar.ccv  ;;
+        cmp4.ne p6, p7 =  r15, r14
+        (p6) br.cond.dptk .L3
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicAdd#
+
+// PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval)
+//
+// Atomically set the integer pointed to by 'val' to the new
+// value 'newval' and return the old value.
+//
+        .align 16
+        .global _PR_ia64_AtomicSet#
+        .proc _PR_ia64_AtomicSet#
+_PR_ia64_AtomicSet:
+#ifndef _LP64
+        addp4 r32 = 0, r32  ;;
+#endif
+        xchg4 r8 = [r32], r33
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicSet#
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Irix.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Irix.s
new file mode 100644
index 0000000..e726194
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Irix.s
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* 
+ *  Atomically add a new element to the top of the stack
+ *
+ *  usage : PR_StackPush(listp, elementp);
+ *  -----------------------
+ */
+
+#include "md/_irix.h"
+#ifdef _PR_HAVE_ATOMIC_CAS
+
+#include <sys/asm.h>
+#include <sys/regdef.h>
+
+LEAF(PR_StackPush)
+
+retry_push:
+.set noreorder
+		lw		v0,0(a0)
+		li		t1,1
+		beq		v0,t1,retry_push
+		move	t0,a1
+
+        ll      v0,0(a0)
+		beq		v0,t1,retry_push
+		nop
+		sc		t1,0(a0)	
+		beq		t1,0,retry_push
+		nop
+		sw		v0,0(a1)
+		sync
+		sw		t0,0(a0)
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		jr		ra
+		nop
+
+END(PR_StackPush)
+
+/*
+ *
+ *  Atomically remove the element at the top of the stack
+ *
+ *  usage : elemep = PR_StackPop(listp);
+ *
+ */
+
+LEAF(PR_StackPop)
+retry_pop:
+.set noreorder
+
+
+		lw		v0,0(a0)
+		li		t1,1
+		beq		v0,0,done
+		nop	
+		beq		v0,t1,retry_pop
+		nop	
+
+        ll      v0,0(a0)
+		beq		v0,0,done
+		nop
+		beq		v0,t1,retry_pop
+		nop
+		sc		t1,0(a0)	
+		beq		t1,0,retry_pop
+		nop
+		lw		t0,0(v0)
+		sw		t0,0(a0)
+done:
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		jr		ra
+		nop
+
+END(PR_StackPop)
+
+#endif /* _PR_HAVE_ATOMIC_CAS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_ia64.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_ia64.s
new file mode 100644
index 0000000..a97412d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_ia64.s
@@ -0,0 +1,103 @@
+// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// 
+// ***** BEGIN LICENSE BLOCK *****
+// Version: MPL 1.1/GPL 2.0/LGPL 2.1
+//
+// The contents of this file are subject to the Mozilla Public License Version
+// 1.1 (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+// http://www.mozilla.org/MPL/
+//
+// Software distributed under the License is distributed on an "AS IS" basis,
+// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+// for the specific language governing rights and limitations under the
+// License.
+//
+// The Original Code is the Netscape Portable Runtime (NSPR).
+//
+// The Initial Developer of the Original Code is
+// Netscape Communications Corporation.
+// Portions created by the Initial Developer are Copyright (C) 2000
+// the Initial Developer. All Rights Reserved.
+//
+// Contributor(s):
+//
+// Alternatively, the contents of this file may be used under the terms of
+// either the GNU General Public License Version 2 or later (the "GPL"), or
+// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+// in which case the provisions of the GPL or the LGPL are applicable instead
+// of those above. If you wish to allow use of your version of this file only
+// under the terms of either the GPL or the LGPL, and not to allow others to
+// use your version of this file under the terms of the MPL, indicate your
+// decision by deleting the provisions above and replace them with the notice
+// and other provisions required by the GPL or the LGPL. If you do not delete
+// the provisions above, a recipient may use your version of this file under
+// the terms of any one of the MPL, the GPL or the LGPL.
+//
+// ***** END LICENSE BLOCK *****
+
+.text
+
+// PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val)
+//
+// Atomically increment the integer pointed to by 'val' and return
+// the result of the increment.
+//
+        .align 16
+        .global _PR_ia64_AtomicIncrement#
+        .proc _PR_ia64_AtomicIncrement#
+_PR_ia64_AtomicIncrement:
+        fetchadd4.acq r8 = [r32], 1  ;;
+        adds r8 = 1, r8
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicIncrement#
+
+// PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val)
+//
+// Atomically decrement the integer pointed to by 'val' and return
+// the result of the decrement.
+//
+        .align 16
+        .global _PR_ia64_AtomicDecrement#
+        .proc _PR_ia64_AtomicDecrement#
+_PR_ia64_AtomicDecrement:
+        fetchadd4.rel r8 = [r32], -1  ;;
+        adds r8 = -1, r8
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicDecrement#
+
+// PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+//
+// Atomically add 'val' to the integer pointed to by 'ptr'
+// and return the result of the addition.
+//
+        .align 16
+        .global _PR_ia64_AtomicAdd#
+        .proc _PR_ia64_AtomicAdd#
+_PR_ia64_AtomicAdd:
+        ld4 r15 = [r32]  ;;
+.L3:
+        mov r14 = r15
+        mov ar.ccv = r15
+        add r8 = r15, r33  ;;
+        cmpxchg4.acq r15 = [r32], r8, ar.ccv  ;;
+        cmp4.ne p6, p7 =  r15, r14
+        (p6) br.cond.dptk .L3
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicAdd#
+
+// PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval)
+//
+// Atomically set the integer pointed to by 'val' to the new
+// value 'newval' and return the old value.
+//
+        .align 16
+        .global _PR_ia64_AtomicSet#
+        .proc _PR_ia64_AtomicSet#
+_PR_ia64_AtomicSet:
+        xchg4 r8 = [r32], r33
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicSet#
+
+// Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits ; .previous
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_ppc.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_ppc.s
new file mode 100644
index 0000000..0e1c195
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_ppc.s
@@ -0,0 +1,107 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2003
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# Based on the programming examples in The PowerPC Architecture:
+# A Specification for A New Family of RISC Processors, 2nd Ed.,
+# Book I, Section E.1, "Synchronization," pp. 249-256, May 1994.
+#
+
+        .section ".text"
+
+#
+# PRInt32 _PR_ppc_AtomicIncrement(PRInt32 *val);
+#
+        .align  2
+        .globl  _PR_ppc_AtomicIncrement
+        .type _PR_ppc_AtomicIncrement,@function
+_PR_ppc_AtomicIncrement:
+.Lfd1:  lwarx   4,0,3
+        addi    0,4,1
+        stwcx.  0,0,3
+        bne-    .Lfd1
+        mr      3,0
+        blr
+.Lfe1:  .size _PR_ppc_AtomicIncrement,.Lfe1-_PR_ppc_AtomicIncrement
+
+#
+# PRInt32 _PR_ppc_AtomicDecrement(PRInt32 *val);
+#
+        .align  2
+        .globl  _PR_ppc_AtomicDecrement
+        .type _PR_ppc_AtomicDecrement,@function
+_PR_ppc_AtomicDecrement:
+.Lfd2:  lwarx   4,0,3
+        addi    0,4,-1
+        stwcx.  0,0,3
+        bne-    .Lfd2
+        mr      3,0
+        blr
+.Lfe2:  .size _PR_ppc_AtomicDecrement,.Lfe2-_PR_ppc_AtomicDecrement
+
+#
+# PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval);
+#
+        .align  2
+        .globl  _PR_ppc_AtomicSet
+        .type _PR_ppc_AtomicSet,@function
+_PR_ppc_AtomicSet:
+.Lfd3:  lwarx   5,0,3
+        stwcx.  4,0,3
+        bne-    .Lfd3
+        mr      3,5
+        blr
+.Lfe3:  .size _PR_ppc_AtomicSet,.Lfe3-_PR_ppc_AtomicSet
+
+#
+# PRInt32 _PR_ppc_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#
+        .align  2
+        .globl  _PR_ppc_AtomicAdd
+        .type _PR_ppc_AtomicAdd,@function
+_PR_ppc_AtomicAdd:
+.Lfd4:  lwarx   5,0,3
+        add     0,4,5
+        stwcx.  0,0,3
+        bne-    .Lfd4
+        mr      3,0
+        blr
+.Lfe4:  .size _PR_ppc_AtomicAdd,.Lfe4-_PR_ppc_AtomicAdd
+
+# Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits ; .previous
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s
new file mode 100644
index 0000000..5ae21aa
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s
@@ -0,0 +1,117 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ ***** BEGIN LICENSE BLOCK *****
+/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+/
+/ The contents of this file are subject to the Mozilla Public License Version
+/ 1.1 (the "License"); you may not use this file except in compliance with
+/ the License. You may obtain a copy of the License at
+/ http://www.mozilla.org/MPL/
+/
+/ Software distributed under the License is distributed on an "AS IS" basis,
+/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+/ for the specific language governing rights and limitations under the
+/ License.
+/
+/ The Original Code is the Netscape Portable Runtime (NSPR).
+/
+/ The Initial Developer of the Original Code is
+/ Netscape Communications Corporation.
+/ Portions created by the Initial Developer are Copyright (C) 2000
+/ the Initial Developer. All Rights Reserved.
+/
+/ Contributor(s):
+/
+/ Alternatively, the contents of this file may be used under the terms of
+/ either the GNU General Public License Version 2 or later (the "GPL"), or
+/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+/ in which case the provisions of the GPL or the LGPL are applicable instead
+/ of those above. If you wish to allow use of your version of this file only
+/ under the terms of either the GPL or the LGPL, and not to allow others to
+/ use your version of this file under the terms of the MPL, indicate your
+/ decision by deleting the provisions above and replace them with the notice
+/ and other provisions required by the GPL or the LGPL. If you do not delete
+/ the provisions above, a recipient may use your version of this file under
+/ the terms of any one of the MPL, the GPL or the LGPL.
+/
+/ ***** END LICENSE BLOCK *****
+
+/ PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl _PR_x86_AtomicIncrement
+    .align 4
+_PR_x86_AtomicIncrement:
+    movl 4(%esp), %ecx
+    movl $1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    incl %eax
+    ret
+
+/ PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl _PR_x86_AtomicDecrement
+    .align 4
+_PR_x86_AtomicDecrement:
+    movl 4(%esp), %ecx
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    decl %eax
+    ret
+
+/ PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+/ An alternative implementation:
+/   .text
+/   .globl _PR_x86_AtomicSet
+/   .align 4
+/_PR_x86_AtomicSet:
+/   movl 4(%esp), %ecx
+/   movl 8(%esp), %edx
+/   movl (%ecx), %eax
+/retry:
+/   lock
+/   cmpxchgl %edx, (%ecx)
+/   jne retry
+/   ret
+/
+    .text
+    .globl _PR_x86_AtomicSet
+    .align 4
+_PR_x86_AtomicSet:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    xchgl %eax, (%ecx)
+    ret
+
+/ PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl _PR_x86_AtomicAdd
+    .align 4
+_PR_x86_AtomicAdd:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    movl %eax, %edx
+    lock
+    xaddl %eax, (%ecx)
+    addl %edx, %eax
+    ret
+
+/ Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits ; .previous
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86_64.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86_64.s
new file mode 100644
index 0000000..8de0457
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86_64.s
@@ -0,0 +1,106 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ ***** BEGIN LICENSE BLOCK *****
+/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+/
+/ The contents of this file are subject to the Mozilla Public License Version
+/ 1.1 (the "License"); you may not use this file except in compliance with
+/ the License. You may obtain a copy of the License at
+/ http://www.mozilla.org/MPL/
+/
+/ Software distributed under the License is distributed on an "AS IS" basis,
+/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+/ for the specific language governing rights and limitations under the
+/ License.
+/
+/ The Original Code is the Netscape Portable Runtime (NSPR).
+/
+/ The Initial Developer of the Original Code is
+/ Netscape Communications Corporation.
+/ Portions created by the Initial Developer are Copyright (C) 2004
+/ the Initial Developer. All Rights Reserved.
+/
+/ Contributor(s):
+/
+/ Alternatively, the contents of this file may be used under the terms of
+/ either the GNU General Public License Version 2 or later (the "GPL"), or
+/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+/ in which case the provisions of the GPL or the LGPL are applicable instead
+/ of those above. If you wish to allow use of your version of this file only
+/ under the terms of either the GPL or the LGPL, and not to allow others to
+/ use your version of this file under the terms of the MPL, indicate your
+/ decision by deleting the provisions above and replace them with the notice
+/ and other provisions required by the GPL or the LGPL. If you do not delete
+/ the provisions above, a recipient may use your version of this file under
+/ the terms of any one of the MPL, the GPL or the LGPL.
+/
+/ ***** END LICENSE BLOCK *****
+
+/ PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl _PR_x86_64_AtomicIncrement
+    .type _PR_x86_64_AtomicIncrement, @function
+    .align 4
+_PR_x86_64_AtomicIncrement:
+    movl $1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    incl %eax
+    ret
+    .size _PR_x86_64_AtomicIncrement, .-_PR_x86_64_AtomicIncrement
+
+/ PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl _PR_x86_64_AtomicDecrement
+    .type _PR_x86_64_AtomicDecrement, @function
+    .align 4
+_PR_x86_64_AtomicDecrement:
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    decl %eax
+    ret
+    .size _PR_x86_64_AtomicDecrement, .-_PR_x86_64_AtomicDecrement
+
+/ PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+    .text
+    .globl _PR_x86_64_AtomicSet
+    .type _PR_x86_64_AtomicSet, @function
+    .align 4
+_PR_x86_64_AtomicSet:
+    movl %esi, %eax
+    xchgl %eax, (%rdi)
+    ret
+    .size _PR_x86_64_AtomicSet, .-_PR_x86_64_AtomicSet
+
+/ PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl _PR_x86_64_AtomicAdd
+    .type _PR_x86_64_AtomicAdd, @function
+    .align 4
+_PR_x86_64_AtomicAdd:
+    movl %esi, %eax
+    lock
+    xaddl %eax, (%rdi)
+    addl %esi, %eax
+    ret
+    .size _PR_x86_64_AtomicAdd, .-_PR_x86_64_AtomicAdd
+
+/ Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits ; .previous
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_ReliantUNIX.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_ReliantUNIX.s
new file mode 100644
index 0000000..7aef248
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_ReliantUNIX.s
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* We want position independent code */
+#define PIC
+
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#include <sys/syscall.h>
+
+	.file 1 "os_ReliantUNIX.s"
+	.option pic2
+	.text
+
+	.align	2
+	.globl	getcxt
+	.ent	getcxt
+getcxt:
+	.frame	sp,0,$31		# vars= 0, regs= 0/0, args= 0, extra= 0
+	# saved integer regs
+	sw	ra,180(a0)	# gpregs[CXT_EPC]
+	sw	gp,152(a0)	# gpregs[CXT_GP]
+	sw	sp,156(a0)	# gpregs[CXT_SP]
+	sw	s8,160(a0)	# gpregs[CXT_S8]
+	sw	s0,104(a0)	# gpregs[CXT_S0]
+	sw	s1,108(a0)	# gpregs[CXT_S1]
+	sw	s2,112(a0)	# gpregs[CXT_S2]
+	sw	s3,116(a0)	# gpregs[CXT_S3]
+	sw	s4,120(a0)	# gpregs[CXT_S4]
+	sw	s5,124(a0)	# gpregs[CXT_S5]
+	sw	s6,128(a0)	# gpregs[CXT_S6]
+	sw	s7,132(a0)	# gpregs[CXT_S7]
+	# csr
+	cfc1	v0,$31
+	# saved float regs
+	s.d	$f20,264(a0)	# fpregs.fp_r.fp_dregs[10]
+	s.d	$f22,272(a0)	# fpregs.fp_r.fp_dregs[11]
+	s.d	$f24,280(a0)	# fpregs.fp_r.fp_dregs[12]
+	s.d	$f26,288(a0)	# fpregs.fp_r.fp_dregs[13]
+	s.d	$f28,296(a0)	# fpregs.fp_r.fp_dregs[14]
+	s.d	$f30,304(a0)	# fpregs.fp_r.fp_dregs[15]
+	sw	v0,312(a0)	# fpregs.fp_csr
+
+	# give no illusions about the contents
+	li	v0,0x0c		# UC_CPU | UC_MAU
+	sw	v0,0(a0)	# uc_flags
+
+	move	v0,zero
+	j	ra
+	.end	getcxt
+
+	.align	2
+	.globl	setcxt
+	.ent	setcxt
+setcxt:
+	.frame	sp,0,$31		# vars= 0, regs= 0/0, args= 0, extra= 0
+	lw	v0,312(a0)	# fpregs.fp_csr
+	li	v1,0xfffc0fff	# mask out exception cause bits
+	and	v0,v0,v1
+	# saved integer regs
+	lw	t9,180(a0)	# gpregs[CXT_EPC]
+	lw	ra,180(a0)	# gpregs[CXT_EPC]
+	lw	gp,152(a0)	# gpregs[CXT_GP]
+	lw	sp,156(a0)	# gpregs[CXT_SP]
+	ctc1	v0,$31		# fp_csr
+	lw	s8,160(a0)	# gpregs[CXT_S8]
+	lw	s0,104(a0)	# gpregs[CXT_S0]
+	lw	s1,108(a0)	# gpregs[CXT_S1]
+	lw	s2,112(a0)	# gpregs[CXT_S2]
+	lw	s3,116(a0)	# gpregs[CXT_S3]
+	lw	s4,120(a0)	# gpregs[CXT_S4]
+	lw	s5,124(a0)	# gpregs[CXT_S5]
+	lw	s6,128(a0)	# gpregs[CXT_S6]
+	lw	s7,132(a0)	# gpregs[CXT_S7]
+	# saved float regs
+	l.d	$f20,264(a0)	# fpregs.fp_r.fp_dregs[10]
+	l.d	$f22,272(a0)	# fpregs.fp_r.fp_dregs[11]
+	l.d	$f24,280(a0)	# fpregs.fp_r.fp_dregs[12]
+	l.d	$f26,288(a0)	# fpregs.fp_r.fp_dregs[13]
+	l.d	$f28,296(a0)	# fpregs.fp_r.fp_dregs[14]
+	l.d	$f30,304(a0)	# fpregs.fp_r.fp_dregs[15]
+
+	# load these, too
+	# they were not saved, but maybe the user modified them...
+	lw	v0,48(a0)
+	lw	v1,52(a0)
+	lw	a1,60(a0)
+	lw	a2,64(a0)
+	lw	a3,68(a0)
+	lw	a0,56(a0)	# there is no way back
+
+	j	ra
+
+	.end	setcxt
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s
new file mode 100644
index 0000000..d3f1e69
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s
@@ -0,0 +1,205 @@
+! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+! 
+! ***** BEGIN LICENSE BLOCK *****
+! Version: MPL 1.1/GPL 2.0/LGPL 2.1
+!
+! The contents of this file are subject to the Mozilla Public License Version
+! 1.1 (the "License"); you may not use this file except in compliance with
+! the License. You may obtain a copy of the License at
+! http://www.mozilla.org/MPL/
+!
+! Software distributed under the License is distributed on an "AS IS" basis,
+! WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+! for the specific language governing rights and limitations under the
+! License.
+!
+! The Original Code is the Netscape Portable Runtime (NSPR).
+!
+! The Initial Developer of the Original Code is
+! Netscape Communications Corporation.
+! Portions created by the Initial Developer are Copyright (C) 1998-2000
+! the Initial Developer. All Rights Reserved.
+!
+! Contributor(s):
+!
+! Alternatively, the contents of this file may be used under the terms of
+! either the GNU General Public License Version 2 or later (the "GPL"), or
+! the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+! in which case the provisions of the GPL or the LGPL are applicable instead
+! of those above. If you wish to allow use of your version of this file only
+! under the terms of either the GPL or the LGPL, and not to allow others to
+! use your version of this file under the terms of the MPL, indicate your
+! decision by deleting the provisions above and replace them with the notice
+! and other provisions required by the GPL or the LGPL. If you do not delete
+! the provisions above, a recipient may use your version of this file under
+! the terms of any one of the MPL, the GPL or the LGPL.
+!
+! ***** END LICENSE BLOCK *****
+
+!
+!  atomic increment, decrement and swap routines for V8+ sparc (ultrasparc)
+!  using CAS (compare-and-swap) atomic instructions
+!
+!  this MUST be compiled with an ultrasparc-aware assembler
+!
+!  standard asm linkage macros; this module must be compiled
+!  with the -P option (use C preprocessor)
+
+#include <sys/asm_linkage.h>
+
+!  ======================================================================
+!
+!  Perform the sequence a = a + 1 atomically with respect to other
+!  fetch-and-adds to location a in a wait-free fashion.
+!
+!  usage : val = PR_AtomicIncrement(address)
+!  return: current value (you'd think this would be old val)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [local]   - work register
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(_MD_AtomicIncrement)      ! standard assembler/ELF prologue
+
+retryAI:
+        ld      [%o0], %o2              ! set o2 to the current value
+        add     %o2, 0x1, %o3           ! calc the new value
+        mov     %o3, %o1                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAI                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o1, %o0                ! set the return code to the new value
+
+        SET_SIZE(_MD_AtomicIncrement)   ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = a - 1 atomically with respect to other
+!  fetch-and-decs to location a in a wait-free fashion.
+!
+!  usage : val = PR_AtomicDecrement(address)
+!  return: current value (you'd think this would be old val)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [local]   - work register
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(_MD_AtomicDecrement)      ! standard assembler/ELF prologue
+
+retryAD:
+        ld      [%o0], %o2              ! set o2 to the current value
+        sub     %o2, 0x1, %o3           ! calc the new value
+        mov     %o3, %o1                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAD                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o1, %o0                ! set the return code to the new value
+
+        SET_SIZE(_MD_AtomicDecrement)   ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = b atomically with respect to other
+!  fetch-and-stores to location a in a wait-free fashion.
+!
+!  usage : old_val = PR_AtomicSet(address, newval)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [input]   - the new value to set for [%o0]
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(_MD_AtomicSet)            ! standard assembler/ELF prologue
+
+retryAS:
+        ld      [%o0], %o2              ! set o2 to the current value
+        mov     %o1, %o3                ! set up the new value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAS                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o3, %o0                ! set the return code to the prev value
+
+        SET_SIZE(_MD_AtomicSet)         ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = a + b atomically with respect to other
+!  fetch-and-adds to location a in a wait-free fashion.
+!
+!  usage : newval = PR_AtomicAdd(address, val)
+!  return: the value after addition
+!
+        ENTRY(_MD_AtomicAdd)      ! standard assembler/ELF prologue
+
+retryAA:
+        ld      [%o0], %o2              ! set o2 to the current value
+        add     %o2, %o1, %o3           ! calc the new value
+        mov     %o3, %o4                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAA                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o4, %o0                ! set the return code to the new value
+
+        SET_SIZE(_MD_AtomicAdd)    		! standard assembler/ELF epilogue
+
+!
+!  end
+!
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s
new file mode 100644
index 0000000..08c8e07
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s
@@ -0,0 +1,205 @@
+! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+! 
+! ***** BEGIN LICENSE BLOCK *****
+! Version: MPL 1.1/GPL 2.0/LGPL 2.1
+!
+! The contents of this file are subject to the Mozilla Public License Version
+! 1.1 (the "License"); you may not use this file except in compliance with
+! the License. You may obtain a copy of the License at
+! http://www.mozilla.org/MPL/
+!
+! Software distributed under the License is distributed on an "AS IS" basis,
+! WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+! for the specific language governing rights and limitations under the
+! License.
+!
+! The Original Code is the Netscape Portable Runtime (NSPR).
+!
+! The Initial Developer of the Original Code is
+! Netscape Communications Corporation.
+! Portions created by the Initial Developer are Copyright (C) 1998-2000
+! the Initial Developer. All Rights Reserved.
+!
+! Contributor(s):
+!
+! Alternatively, the contents of this file may be used under the terms of
+! either the GNU General Public License Version 2 or later (the "GPL"), or
+! the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+! in which case the provisions of the GPL or the LGPL are applicable instead
+! of those above. If you wish to allow use of your version of this file only
+! under the terms of either the GPL or the LGPL, and not to allow others to
+! use your version of this file under the terms of the MPL, indicate your
+! decision by deleting the provisions above and replace them with the notice
+! and other provisions required by the GPL or the LGPL. If you do not delete
+! the provisions above, a recipient may use your version of this file under
+! the terms of any one of the MPL, the GPL or the LGPL.
+!
+! ***** END LICENSE BLOCK *****
+
+!
+!  atomic increment, decrement and swap routines for V8+ sparc (ultrasparc)
+!  using CAS (compare-and-swap) atomic instructions
+!
+!  this MUST be compiled with an ultrasparc-aware assembler
+!
+!  standard asm linkage macros; this module must be compiled
+!  with the -P option (use C preprocessor)
+
+#include <sys/asm_linkage.h>
+
+!  ======================================================================
+!
+!  Perform the sequence a = a + 1 atomically with respect to other
+!  fetch-and-adds to location a in a wait-free fashion.
+!
+!  usage : val = PR_AtomicIncrement(address)
+!  return: current value (you'd think this would be old val)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [local]   - work register
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(PR_AtomicIncrement)       ! standard assembler/ELF prologue
+
+retryAI:
+        ld      [%o0], %o2              ! set o2 to the current value
+        add     %o2, 0x1, %o3           ! calc the new value
+        mov     %o3, %o1                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAI                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o1, %o0                ! set the return code to the new value
+
+        SET_SIZE(PR_AtomicIncrement)    ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = a - 1 atomically with respect to other
+!  fetch-and-decs to location a in a wait-free fashion.
+!
+!  usage : val = PR_AtomicDecrement(address)
+!  return: current value (you'd think this would be old val)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [local]   - work register
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(PR_AtomicDecrement)       ! standard assembler/ELF prologue
+
+retryAD:
+        ld      [%o0], %o2              ! set o2 to the current value
+        sub     %o2, 0x1, %o3           ! calc the new value
+        mov     %o3, %o1                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAD                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o1, %o0                ! set the return code to the new value
+
+        SET_SIZE(PR_AtomicDecrement)    ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = b atomically with respect to other
+!  fetch-and-stores to location a in a wait-free fashion.
+!
+!  usage : old_val = PR_AtomicSet(address, newval)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [input]   - the new value to set for [%o0]
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(PR_AtomicSet)             ! standard assembler/ELF prologue
+
+retryAS:
+        ld      [%o0], %o2              ! set o2 to the current value
+        mov     %o1, %o3                ! set up the new value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAS                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o3, %o0                ! set the return code to the prev value
+
+        SET_SIZE(PR_AtomicSet)          ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = a + b atomically with respect to other
+!  fetch-and-adds to location a in a wait-free fashion.
+!
+!  usage : newval = PR_AtomicAdd(address, val)
+!  return: the value after addition
+!
+        ENTRY(PR_AtomicAdd)       ! standard assembler/ELF prologue
+
+retryAA:
+        ld      [%o0], %o2              ! set o2 to the current value
+        add     %o2, %o1, %o3           ! calc the new value
+        mov     %o3, %o4                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAA                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o4, %o0                ! set the return code to the new value
+
+        SET_SIZE(PR_AtomicAdd)    		! standard assembler/ELF epilogue
+
+!
+!  end
+!
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86.s
new file mode 100644
index 0000000..75ddfa6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86.s
@@ -0,0 +1,158 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ ***** BEGIN LICENSE BLOCK *****
+/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+/
+/ The contents of this file are subject to the Mozilla Public License Version
+/ 1.1 (the "License"); you may not use this file except in compliance with
+/ the License. You may obtain a copy of the License at
+/ http://www.mozilla.org/MPL/
+/
+/ Software distributed under the License is distributed on an "AS IS" basis,
+/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+/ for the specific language governing rights and limitations under the
+/ License.
+/
+/ The Original Code is the Netscape Portable Runtime (NSPR).
+/
+/ The Initial Developer of the Original Code is
+/ Netscape Communications Corporation.
+/ Portions created by the Initial Developer are Copyright (C) 1998-2000
+/ the Initial Developer. All Rights Reserved.
+/
+/ Contributor(s):
+/
+/ Alternatively, the contents of this file may be used under the terms of
+/ either the GNU General Public License Version 2 or later (the "GPL"), or
+/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+/ in which case the provisions of the GPL or the LGPL are applicable instead
+/ of those above. If you wish to allow use of your version of this file only
+/ under the terms of either the GPL or the LGPL, and not to allow others to
+/ use your version of this file under the terms of the MPL, indicate your
+/ decision by deleting the provisions above and replace them with the notice
+/ and other provisions required by the GPL or the LGPL. If you do not delete
+/ the provisions above, a recipient may use your version of this file under
+/ the terms of any one of the MPL, the GPL or the LGPL.
+/
+/ ***** END LICENSE BLOCK *****
+
+	.text
+
+	.globl	getedi
+getedi:
+	movl	%edi,%eax
+	ret
+	.type	getedi,@function
+	.size	getedi,.-getedi
+ 
+	.globl	setedi
+setedi:
+	movl	4(%esp),%edi
+	ret
+	.type	setedi,@function
+	.size	setedi,.-setedi
+
+	.globl	__MD_FlushRegisterWindows
+	.globl _MD_FlushRegisterWindows
+
+__MD_FlushRegisterWindows:
+_MD_FlushRegisterWindows:
+
+	ret
+
+/
+/ sol_getsp()
+/
+/ Return the current sp (for debugging)
+/
+	.globl sol_getsp
+sol_getsp:
+	movl	%esp, %eax
+	ret
+
+/
+/ sol_curthread()
+/
+/ Return a unique identifier for the currently active thread.
+/
+	.globl sol_curthread
+sol_curthread:
+	movl	%ecx, %eax
+	ret
+
+/ PRInt32 _MD_AtomicIncrement(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl _MD_AtomicIncrement
+    .align 4
+_MD_AtomicIncrement:
+    movl 4(%esp), %ecx
+    movl $1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    incl %eax
+    ret
+
+/ PRInt32 _MD_AtomicDecrement(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl _MD_AtomicDecrement
+    .align 4
+_MD_AtomicDecrement:
+    movl 4(%esp), %ecx
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    decl %eax
+    ret
+
+/ PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+/ An alternative implementation:
+/   .text
+/   .globl _MD_AtomicSet
+/   .align 4
+/_MD_AtomicSet:
+/   movl 4(%esp), %ecx
+/   movl 8(%esp), %edx
+/   movl (%ecx), %eax
+/retry:
+/   lock
+/   cmpxchgl %edx, (%ecx)
+/   jne retry
+/   ret
+/
+    .text
+    .globl _MD_AtomicSet
+    .align 4
+_MD_AtomicSet:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    xchgl %eax, (%ecx)
+    ret
+
+/ PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl _MD_AtomicAdd
+    .align 4
+_MD_AtomicAdd:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    movl %eax, %edx
+    lock
+    xaddl %eax, (%ecx)
+    addl %edx, %eax
+    ret
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s
new file mode 100644
index 0000000..3c5ac39
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s
@@ -0,0 +1,95 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ ***** BEGIN LICENSE BLOCK *****
+/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+/
+/ The contents of this file are subject to the Mozilla Public License Version
+/ 1.1 (the "License"); you may not use this file except in compliance with
+/ the License. You may obtain a copy of the License at
+/ http://www.mozilla.org/MPL/
+/
+/ Software distributed under the License is distributed on an "AS IS" basis,
+/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+/ for the specific language governing rights and limitations under the
+/ License.
+/
+/ The Original Code is the Netscape Portable Runtime (NSPR).
+/
+/ The Initial Developer of the Original Code is
+/ Netscape Communications Corporation.
+/ Portions created by the Initial Developer are Copyright (C) 2004
+/ the Initial Developer. All Rights Reserved.
+/
+/ Contributor(s):
+/
+/ Alternatively, the contents of this file may be used under the terms of
+/ either the GNU General Public License Version 2 or later (the "GPL"), or
+/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+/ in which case the provisions of the GPL or the LGPL are applicable instead
+/ of those above. If you wish to allow use of your version of this file only
+/ under the terms of either the GPL or the LGPL, and not to allow others to
+/ use your version of this file under the terms of the MPL, indicate your
+/ decision by deleting the provisions above and replace them with the notice
+/ and other provisions required by the GPL or the LGPL. If you do not delete
+/ the provisions above, a recipient may use your version of this file under
+/ the terms of any one of the MPL, the GPL or the LGPL.
+/
+/ ***** END LICENSE BLOCK *****
+
+/ PRInt32 _MD_AtomicIncrement(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl _MD_AtomicIncrement
+    .align 4
+_MD_AtomicIncrement:
+    movl $1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    incl %eax
+    ret
+
+/ PRInt32 _MD_AtomicDecrement(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl _MD_AtomicDecrement
+    .align 4
+_MD_AtomicDecrement:
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    decl %eax
+    ret
+
+/ PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+    .text
+    .globl _MD_AtomicSet
+    .align 4
+_MD_AtomicSet:
+    movl %esi, %eax
+    xchgl %eax, (%rdi)
+    ret
+
+/ PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl _MD_AtomicAdd
+    .align 4
+_MD_AtomicAdd:
+    movl %esi, %eax
+    lock
+    xaddl %eax, (%rdi)
+    addl %esi, %eax
+    ret
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/osf1.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/osf1.c
new file mode 100644
index 0000000..a4cd6a5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/osf1.c
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for OSF1 */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for OSF1.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OSF1.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/pthreads_user.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/pthreads_user.c
new file mode 100644
index 0000000..21e5f0b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/pthreads_user.c
@@ -0,0 +1,480 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+
+
+sigset_t ints_off;
+pthread_mutex_t	_pr_heapLock;
+pthread_key_t current_thread_key;
+pthread_key_t current_cpu_key;
+pthread_key_t last_thread_key;
+pthread_key_t intsoff_key;
+
+
+PRInt32 _pr_md_pthreads_created, _pr_md_pthreads_failed;
+PRInt32 _pr_md_pthreads = 1;
+
+void _MD_EarlyInit(void)
+{
+extern PRInt32 _nspr_noclock;
+
+	if (pthread_key_create(&current_thread_key, NULL) != 0) {
+		perror("pthread_key_create failed");
+		exit(1);
+	}
+	if (pthread_key_create(&current_cpu_key, NULL) != 0) {
+		perror("pthread_key_create failed");
+		exit(1);
+	}
+	if (pthread_key_create(&last_thread_key, NULL) != 0) {
+		perror("pthread_key_create failed");
+		exit(1);
+	}
+	if (pthread_key_create(&intsoff_key, NULL) != 0) {
+		perror("pthread_key_create failed");
+		exit(1);
+	}
+
+	sigemptyset(&ints_off);
+	sigaddset(&ints_off, SIGALRM);
+	sigaddset(&ints_off, SIGIO);
+	sigaddset(&ints_off, SIGCLD);
+
+	/*
+	 * disable clock interrupts
+	 */
+	_nspr_noclock = 1;
+
+}
+
+void _MD_InitLocks()
+{
+	if (pthread_mutex_init(&_pr_heapLock, NULL) != 0) {
+		perror("pthread_mutex_init failed");
+		exit(1);
+	}
+}
+
+PR_IMPLEMENT(void) _MD_FREE_LOCK(struct _MDLock *lockp)
+{
+	PRIntn _is;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	pthread_mutex_destroy(&lockp->mutex);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+}
+
+
+
+PR_IMPLEMENT(PRStatus) _MD_NEW_LOCK(struct _MDLock *lockp)
+{
+    PRStatus rv;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(is);
+	rv = pthread_mutex_init(&lockp->mutex, NULL);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(is);
+	return (rv == 0) ? PR_SUCCESS : PR_FAILURE;
+}
+
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+PR_IMPLEMENT(void)
+_MD_SetPriority(_MDThread *thread, PRThreadPriority newPri)
+{
+	/*
+	 * XXX - to be implemented
+	 */
+    return;
+}
+
+PR_IMPLEMENT(PRStatus) _MD_InitThread(struct PRThread *thread)
+{
+    struct sigaction sigact;
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        thread->md.pthread = pthread_self();
+#if 0
+		/*
+		 * set up SIGUSR1 handler; this is used to save state
+		 * during PR_SuspendAll
+		 */
+		sigact.sa_handler = save_context_and_block;
+		sigact.sa_flags = SA_RESTART;
+		/*
+		 * Must mask clock interrupts
+		 */
+		sigact.sa_mask = timer_set;
+		sigaction(SIGUSR1, &sigact, 0);
+#endif
+    }
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(void) _MD_ExitThread(struct PRThread *thread)
+{
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        _MD_CLEAN_THREAD(thread);
+        _MD_SET_CURRENT_THREAD(NULL);
+    }
+}
+
+PR_IMPLEMENT(void) _MD_CleanThread(struct PRThread *thread)
+{
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+		pthread_mutex_destroy(&thread->md.pthread_mutex);
+		pthread_cond_destroy(&thread->md.pthread_cond);
+    }
+}
+
+PR_IMPLEMENT(void) _MD_SuspendThread(struct PRThread *thread)
+{
+    PRInt32 rv;
+
+    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
+        _PR_IS_GCABLE_THREAD(thread));
+#if 0
+	thread->md.suspending_id = getpid();
+	rv = kill(thread->md.id, SIGUSR1);
+	PR_ASSERT(rv == 0);
+	/*
+	 * now, block the current thread/cpu until woken up by the suspended
+	 * thread from it's SIGUSR1 signal handler
+	 */
+	blockproc(getpid());
+#endif
+}
+
+PR_IMPLEMENT(void) _MD_ResumeThread(struct PRThread *thread)
+{
+    PRInt32 rv;
+
+    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
+        _PR_IS_GCABLE_THREAD(thread));
+#if 0
+    rv = unblockproc(thread->md.id);
+#endif
+}
+
+PR_IMPLEMENT(void) _MD_SuspendCPU(struct _PRCPU *thread)
+{
+    PRInt32 rv;
+
+#if 0
+	cpu->md.suspending_id = getpid();
+	rv = kill(cpu->md.id, SIGUSR1);
+	PR_ASSERT(rv == 0);
+	/*
+	 * now, block the current thread/cpu until woken up by the suspended
+	 * thread from it's SIGUSR1 signal handler
+	 */
+	blockproc(getpid());
+#endif
+}
+
+PR_IMPLEMENT(void) _MD_ResumeCPU(struct _PRCPU *thread)
+{
+#if 0
+	unblockproc(cpu->md.id);
+#endif
+}
+
+
+#define PT_NANOPERMICRO 1000UL
+#define PT_BILLION 1000000000UL
+
+PR_IMPLEMENT(PRStatus)
+_pt_wait(PRThread *thread, PRIntervalTime timeout)
+{
+int rv;
+struct timeval now;
+struct timespec tmo;
+PRUint32 ticks = PR_TicksPerSecond();
+
+
+	if (timeout != PR_INTERVAL_NO_TIMEOUT) {
+		tmo.tv_sec = timeout / ticks;
+		tmo.tv_nsec = timeout - (tmo.tv_sec * ticks);
+		tmo.tv_nsec = PR_IntervalToMicroseconds(PT_NANOPERMICRO *
+											tmo.tv_nsec);
+
+		/* pthreads wants this in absolute time, off we go ... */
+		(void)GETTIMEOFDAY(&now);
+		/* that one's usecs, this one's nsecs - grrrr! */
+		tmo.tv_sec += now.tv_sec;
+		tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
+		tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
+		tmo.tv_nsec %= PT_BILLION;
+	}
+
+	pthread_mutex_lock(&thread->md.pthread_mutex);
+	thread->md.wait--;
+	if (thread->md.wait < 0) {
+		if (timeout != PR_INTERVAL_NO_TIMEOUT) {
+			rv = pthread_cond_timedwait(&thread->md.pthread_cond,
+					&thread->md.pthread_mutex, &tmo);
+        }
+		else
+			rv = pthread_cond_wait(&thread->md.pthread_cond,
+					&thread->md.pthread_mutex);
+		if (rv != 0) {
+			thread->md.wait++;
+		}
+	} else
+		rv = 0;
+	pthread_mutex_unlock(&thread->md.pthread_mutex);
+
+	return (rv == 0) ? PR_SUCCESS : PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_wait(PRThread *thread, PRIntervalTime ticks)
+{
+    if ( thread->flags & _PR_GLOBAL_SCOPE ) {
+		_MD_CHECK_FOR_EXIT();
+        if (_pt_wait(thread, ticks) == PR_FAILURE) {
+	    	_MD_CHECK_FOR_EXIT();
+            /*
+             * wait timed out
+             */
+            _PR_THREAD_LOCK(thread);
+            if (thread->wait.cvar) {
+                /*
+                 * The thread will remove itself from the waitQ
+                 * of the cvar in _PR_WaitCondVar
+                 */
+                thread->wait.cvar = NULL;
+                thread->state =  _PR_RUNNING;
+                _PR_THREAD_UNLOCK(thread);
+            }  else {
+        		_pt_wait(thread, PR_INTERVAL_NO_TIMEOUT);
+                _PR_THREAD_UNLOCK(thread);
+            }
+        }
+    } else {
+		_PR_MD_SWITCH_CONTEXT(thread);
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_WakeupWaiter(PRThread *thread)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 pid, rv;
+    PRIntn is;
+
+	PR_ASSERT(_pr_md_idle_cpus >= 0);
+    if (thread == NULL) {
+		if (_pr_md_idle_cpus)
+        	_MD_Wakeup_CPUs();
+    } else if (!_PR_IS_NATIVE_THREAD(thread)) {
+		/*
+		 * If the thread is on my cpu's runq there is no need to
+		 * wakeup any cpus
+		 */
+		if (!_PR_IS_NATIVE_THREAD(me)) {
+			if (me->cpu != thread->cpu) {
+				if (_pr_md_idle_cpus)
+        			_MD_Wakeup_CPUs();
+			}
+		} else {
+			if (_pr_md_idle_cpus)
+        		_MD_Wakeup_CPUs();
+		}
+    } else {
+		PR_ASSERT(_PR_IS_NATIVE_THREAD(thread));
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_INTSOFF(is);
+
+		pthread_mutex_lock(&thread->md.pthread_mutex);
+		thread->md.wait++;
+		rv = pthread_cond_signal(&thread->md.pthread_cond);
+		PR_ASSERT(rv == 0);
+		pthread_mutex_unlock(&thread->md.pthread_mutex);
+
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+    } 
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for AIX */
+PR_IMPLEMENT(void)
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for AIX.");
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_CreateThread(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PRIntn is;
+    int rv;
+	PRThread *me = _PR_MD_CURRENT_THREAD();	
+	pthread_attr_t attr;
+
+	if (!_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(is);
+
+	if (pthread_mutex_init(&thread->md.pthread_mutex, NULL) != 0) {
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_FAILURE;
+	}
+
+	if (pthread_cond_init(&thread->md.pthread_cond, NULL) != 0) {
+		pthread_mutex_destroy(&thread->md.pthread_mutex);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_FAILURE;
+	}
+    thread->flags |= _PR_GLOBAL_SCOPE;
+
+	pthread_attr_init(&attr); /* initialize attr with default attributes */
+	if (pthread_attr_setstacksize(&attr, (size_t) stackSize) != 0) {
+		pthread_mutex_destroy(&thread->md.pthread_mutex);
+		pthread_cond_destroy(&thread->md.pthread_cond);
+		pthread_attr_destroy(&attr);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_FAILURE;
+	}
+
+	thread->md.wait = 0;
+    rv = pthread_create(&thread->md.pthread, &attr, start, (void *)thread);
+    if (0 == rv) {
+        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_created);
+        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_SUCCESS;
+    } else {
+		pthread_mutex_destroy(&thread->md.pthread_mutex);
+		pthread_cond_destroy(&thread->md.pthread_cond);
+		pthread_attr_destroy(&attr);
+        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_failed);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, rv);
+        return PR_FAILURE;
+    }
+}
+
+PR_IMPLEMENT(void)
+_MD_InitRunningCPU(struct _PRCPU *cpu)
+{
+    extern int _pr_md_pipefd[2];
+
+    _MD_unix_init_running_cpu(cpu);
+    cpu->md.pthread = pthread_self();
+	if (_pr_md_pipefd[0] >= 0) {
+    	_PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0];
+#ifndef _PR_USE_POLL
+    	FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu));
+#endif
+	}
+}
+
+
+void
+_MD_CleanupBeforeExit(void)
+{
+#if 0
+    extern PRInt32    _pr_cpus_exit;
+
+	_pr_irix_exit_now = 1;
+    if (_pr_numCPU > 1) {
+        /*
+         * Set a global flag, and wakeup all cpus which will notice the flag
+         * and exit.
+         */
+        _pr_cpus_exit = getpid();
+        _MD_Wakeup_CPUs();
+        while(_pr_numCPU > 1) {
+            _PR_WAIT_SEM(_pr_irix_exit_sem);
+            _pr_numCPU--;
+        }
+    }
+    /*
+     * cause global threads on the recycle list to exit
+     */
+     _PR_DEADQ_LOCK;
+     if (_PR_NUM_DEADNATIVE != 0) {
+	PRThread *thread;
+    	PRCList *ptr;
+
+        ptr = _PR_DEADNATIVEQ.next;
+        while( ptr != &_PR_DEADNATIVEQ ) {
+        	thread = _PR_THREAD_PTR(ptr);
+		_MD_CVAR_POST_SEM(thread);
+                ptr = ptr->next;
+        } 
+     }
+     _PR_DEADQ_UNLOCK;
+     while(_PR_NUM_DEADNATIVE > 1) {
+	_PR_WAIT_SEM(_pr_irix_exit_sem);
+	_PR_DEC_DEADNATIVE;
+     }
+#endif
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/qnx.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/qnx.c
new file mode 100644
index 0000000..be86e5b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/qnx.c
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Unixware */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Unixware.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRUintn priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware.");
+    return PR_FAILURE;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/reliantunix.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/reliantunix.c
new file mode 100644
index 0000000..efe2108
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/reliantunix.c
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * SINIX (ReliantUNIX) 5.4 - copied from unixware.c by chrisk 040497
+ */
+#include "primpl.h"
+
+#include <ucontext.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) _GETCONTEXT(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+#ifdef ALARMS_BREAK_TCP /* I don't think they do */
+
+PRInt32 _MD_connect(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _connect(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+}
+
+PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _accept(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+    return(rv);
+}
+#endif
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for SINIX */
+/* Why? Just copied it from UNIXWARE... flying-by-night, chrisk 040497 */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for SINIX.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRUintn priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SINIX.");
+#if defined(SNI) && !defined(__GNUC__)
+    /* make compiler happy */
+    return (PRStatus)NULL;
+#endif
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/riscos.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/riscos.c
new file mode 100644
index 0000000..eee94d3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/riscos.c
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Peter Naulls <peter@chocky.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifdef _PR_PTHREADS
+
+void _MD_CleanupBeforeExit(void)
+{
+}
+
+#else /* ! _PR_PTHREADS */
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	/*
+	 * set the pointers to the stack-pointer and frame-pointer words in the
+	 * context structure; this is for debugging use.
+	 */
+	thread->md.sp = _MD_GET_SP_PTR(thread);
+	thread->md.fp = _MD_GET_FP_PTR(thread);
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for RISC OS */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for RISC OS.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for RISC OS.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/scoos.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/scoos.c
new file mode 100644
index 0000000..766bf91
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/scoos.c
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * SCO ODT 5.0 - originally created by mikep
+ */
+#include "primpl.h"
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+#ifdef ALARMS_BREAK_TCP /* I don't think they do */
+
+PRInt32 _MD_connect(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _connect(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+}
+
+PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _accept(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+    return(rv);
+}
+#endif
+
+/*
+ * These are also implemented in pratom.c using NSPR locks.  Any reason
+ * this might be better or worse?  If you like this better, define
+ * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h
+ */
+#ifdef _PR_HAVE_ATOMIC_OPS
+/* Atomic operations */
+#include  <stdio.h>
+static FILE *_uw_semf;
+
+void
+_MD_INIT_ATOMIC(void)
+{
+    /* Sigh.  Sure wish SYSV semaphores weren't such a pain to use */
+    if ((_uw_semf = tmpfile()) == NULL)
+        PR_ASSERT(0);
+
+    return;
+}
+
+void
+_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)++;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    flockfile(_uw_semf);
+    (*ptr) += val;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)--;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    flockfile(_uw_semf);
+    *val = newval;
+    unflockfile(_uw_semf);
+}
+#endif
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for SCO */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for SCO.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SCO.");
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/solaris.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/solaris.c
new file mode 100644
index 0000000..6acffed
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/solaris.c
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+
+extern PRBool suspendAllOn;
+extern PRThread *suspendAllThread;
+
+extern void _MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
+
+PRIntervalTime _MD_Solaris_TicksPerSecond(void)
+{
+    /*
+     * Ticks have a 10-microsecond resolution.  So there are
+     * 100000 ticks per second.
+     */
+    return 100000UL;
+}
+
+/* Interval timers, implemented using gethrtime() */
+
+PRIntervalTime _MD_Solaris_GetInterval(void)
+{
+    union {
+	hrtime_t hrt;  /* hrtime_t is a 64-bit (long long) integer */
+	PRInt64 pr64;
+    } time;
+    PRInt64 resolution;
+    PRIntervalTime ticks;
+
+    time.hrt = gethrtime();  /* in nanoseconds */
+    /*
+     * Convert from nanoseconds to ticks.  A tick's resolution is
+     * 10 microseconds, or 10000 nanoseconds.
+     */
+    LL_I2L(resolution, 10000);
+    LL_DIV(time.pr64, time.pr64, resolution);
+    LL_L2UI(ticks, time.pr64);
+    return ticks;
+}
+
+#ifdef _PR_PTHREADS
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)
+{
+	*np = 0;
+	return NULL;
+}
+#endif /* _PR_PTHREADS */
+
+#if defined(_PR_LOCAL_THREADS_ONLY)
+
+void _MD_EarlyInit(void)
+{
+}
+
+void _MD_SolarisInit()
+{
+    _PR_UnixInit();
+}
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+	PR_ASSERT((thread == NULL) || (!(thread->flags & _PR_GLOBAL_SCOPE)));
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Solaris */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Solaris");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Solaris");
+	return(PR_FAILURE);
+}
+
+#ifdef USE_SETJMP
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+		(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+#else
+PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)
+{
+    if (isCurrent) {
+		(void) getcontext(CONTEXT(t));
+    }
+    *np = NGREG;
+    return (PRWord*) &t->md.context.uc_mcontext.gregs[0];
+}
+#endif  /* USE_SETJMP */
+
+#endif  /* _PR_LOCAL_THREADS_ONLY */
+
+#ifndef _PR_PTHREADS
+#if defined(i386) && defined(SOLARIS2_4)
+/* 
+ * Because clock_gettime() on Solaris/x86 2.4 always generates a
+ * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
+ * which is implemented using gettimeofday().
+ */
+
+int
+_pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp)
+{
+    struct timeval tv;
+
+    if (clock_id != CLOCK_REALTIME) {
+	errno = EINVAL;
+	return -1;
+    }
+
+    gettimeofday(&tv, NULL);
+    tp->tv_sec = tv.tv_sec;
+    tp->tv_nsec = tv.tv_usec * 1000;
+    return 0;
+}
+#endif  /* i386 && SOLARIS2_4 */
+#endif  /* _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/sony.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/sony.c
new file mode 100644
index 0000000..dacb4fd
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/sony.c
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <signal.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Sony */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for SONY.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SONY.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/sunos4.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/sunos4.c
new file mode 100644
index 0000000..d3b40c1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/sunos4.c
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <setjmp.h>
+#include "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRStatus _MD_CREATE_THREAD(PRThread *thread, 
+					void (*start)(void *), 
+					PRThreadPriority priority,
+					PRThreadScope scope, 
+					PRThreadState state, 
+					PRUint32 stackSize) 
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SunOS 4.1.3.");
+    return PR_FAILURE;
+}
+
+void _MD_SET_PRIORITY(_MDThread *md_thread, PRUintn newPri)
+{
+    PR_NOT_REACHED("_MD_SET_PRIORITY should not be called for user-level threads.");
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for SunOS 4.1.3.");
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/symbian.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/symbian.c
new file mode 100644
index 0000000..08e5f5c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/symbian.c
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    *np = 0;
+    return NULL;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix.c
new file mode 100644
index 0000000..771f25a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix.c
@@ -0,0 +1,3765 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+#ifdef _PR_POLL_AVAILABLE
+#include <poll.h>
+#endif
+
+/* To get FIONREAD */
+#if defined(NCR) || defined(UNIXWARE) || defined(NEC) || defined(SNI) \
+        || defined(SONY)
+#include <sys/filio.h>
+#endif
+
+#if defined(NTO)
+#include <sys/statvfs.h>
+#endif
+
+/*
+ * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
+ * PRInt32* pointer to a _PRSockLen_t* pointer.
+ */
+#if defined(HAVE_SOCKLEN_T) \
+    || (defined(__GLIBC__) && __GLIBC__ >= 2)
+#define _PRSockLen_t socklen_t
+#elif defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \
+    || defined(AIX4_1) || defined(LINUX) || defined(SONY) \
+    || defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \
+    || defined(SUNOS4) || defined(NCR) || defined(DARWIN) \
+    || defined(NEXTSTEP) || defined(QNX)
+#define _PRSockLen_t int
+#elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
+    || defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \
+    || defined(DGUX) || defined(NTO) || defined(RISCOS)
+#define _PRSockLen_t size_t
+#else
+#error "Cannot determine architecture"
+#endif
+
+/*
+** Global lock variable used to bracket calls into rusty libraries that
+** aren't thread safe (like libc, libX, etc).
+*/
+static PRLock *_pr_rename_lock = NULL;
+static PRMonitor *_pr_Xfe_mon = NULL;
+
+static PRInt64 minus_one;
+
+sigset_t timer_set;
+
+#if !defined(_PR_PTHREADS)
+
+static sigset_t empty_set;
+
+#ifdef SOLARIS
+#include <sys/file.h>
+#include <sys/filio.h>
+#endif
+
+#ifndef PIPE_BUF
+#define PIPE_BUF 512
+#endif
+
+/*
+ * _nspr_noclock - if set clock interrupts are disabled
+ */
+int _nspr_noclock = 1;
+
+#ifdef IRIX
+extern PRInt32 _nspr_terminate_on_error;
+#endif
+
+/*
+ * There is an assertion in this code that NSPR's definition of PRIOVec
+ * is bit compatible with UNIX' definition of a struct iovec. This is
+ * applicable to the 'writev()' operations where the types are casually
+ * cast to avoid warnings.
+ */
+
+int _pr_md_pipefd[2] = { -1, -1 };
+static char _pr_md_pipebuf[PIPE_BUF];
+static PRInt32 local_io_wait(PRInt32 osfd, PRInt32 wait_flag,
+							PRIntervalTime timeout);
+
+_PRInterruptTable _pr_interruptTable[] = {
+    { 
+        "clock", _PR_MISSED_CLOCK, _PR_ClockInterrupt,     },
+    { 
+        0     }
+};
+
+void _MD_unix_init_running_cpu(_PRCPU *cpu)
+{
+    PR_INIT_CLIST(&(cpu->md.md_unix.ioQ));
+    cpu->md.md_unix.ioq_max_osfd = -1;
+    cpu->md.md_unix.ioq_timeout = PR_INTERVAL_NO_TIMEOUT;
+}
+
+PRStatus _MD_open_dir(_MDDir *d, const char *name)
+{
+int err;
+
+    d->d = opendir(name);
+    if (!d->d) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_OPENDIR_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRInt32 _MD_close_dir(_MDDir *d)
+{
+int rv = 0, err;
+
+    if (d->d) {
+        rv = closedir(d->d);
+        if (rv == -1) {
+                err = _MD_ERRNO();
+                _PR_MD_MAP_CLOSEDIR_ERROR(err);
+        }
+    }
+    return rv;
+}
+
+char * _MD_read_dir(_MDDir *d, PRIntn flags)
+{
+struct dirent *de;
+int err;
+
+    for (;;) {
+        /*
+          * XXX: readdir() is not MT-safe. There is an MT-safe version
+          * readdir_r() on some systems.
+          */
+        _MD_ERRNO() = 0;
+        de = readdir(d->d);
+        if (!de) {
+            err = _MD_ERRNO();
+            _PR_MD_MAP_READDIR_ERROR(err);
+            return 0;
+        }        
+        if ((flags & PR_SKIP_DOT) &&
+            (de->d_name[0] == '.') && (de->d_name[1] == 0))
+            continue;
+        if ((flags & PR_SKIP_DOT_DOT) &&
+            (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
+            (de->d_name[2] == 0))
+            continue;
+        if ((flags & PR_SKIP_HIDDEN) && (de->d_name[0] == '.'))
+            continue;
+        break;
+    }
+    return de->d_name;
+}
+
+PRInt32 _MD_delete(const char *name)
+{
+PRInt32 rv, err;
+#ifdef UNIXWARE
+    sigset_t set, oset;
+#endif
+
+#ifdef UNIXWARE
+    sigfillset(&set);
+    sigprocmask(SIG_SETMASK, &set, &oset);
+#endif
+    rv = unlink(name);
+#ifdef UNIXWARE
+    sigprocmask(SIG_SETMASK, &oset, NULL);
+#endif
+    if (rv == -1) {
+            err = _MD_ERRNO();
+            _PR_MD_MAP_UNLINK_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_rename(const char *from, const char *to)
+{
+    PRInt32 rv = -1, err;
+
+    /*
+    ** This is trying to enforce the semantics of WINDOZE' rename
+    ** operation. That means one is not allowed to rename over top
+    ** of an existing file. Holding a lock across these two function
+    ** and the open function is known to be a bad idea, but ....
+    */
+    if (NULL != _pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+    if (0 == access(to, F_OK))
+        PR_SetError(PR_FILE_EXISTS_ERROR, 0);
+    else
+    {
+        rv = rename(from, to);
+        if (rv < 0) {
+            err = _MD_ERRNO();
+            _PR_MD_MAP_RENAME_ERROR(err);
+        }
+    }
+    if (NULL != _pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+    return rv;
+}
+
+PRInt32 _MD_access(const char *name, PRAccessHow how)
+{
+PRInt32 rv, err;
+int amode;
+
+    switch (how) {
+        case PR_ACCESS_WRITE_OK:
+            amode = W_OK;
+            break;
+        case PR_ACCESS_READ_OK:
+            amode = R_OK;
+            break;
+        case PR_ACCESS_EXISTS:
+            amode = F_OK;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = -1;
+            goto done;
+    }
+    rv = access(name, amode);
+
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_ACCESS_ERROR(err);
+    }
+
+done:
+    return(rv);
+}
+
+PRInt32 _MD_mkdir(const char *name, PRIntn mode)
+{
+int rv, err;
+
+    /*
+    ** This lock is used to enforce rename semantics as described
+    ** in PR_Rename. Look there for more fun details.
+    */
+    if (NULL !=_pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+    rv = mkdir(name, mode);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_MKDIR_ERROR(err);
+    }
+    if (NULL !=_pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+    return rv;
+}
+
+PRInt32 _MD_rmdir(const char *name)
+{
+int rv, err;
+
+    rv = rmdir(name);
+    if (rv == -1) {
+            err = _MD_ERRNO();
+            _PR_MD_MAP_RMDIR_ERROR(err);
+    }
+    return rv;
+}
+
+PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+PRThread *me = _PR_MD_CURRENT_THREAD();
+PRInt32 rv, err;
+#ifndef _PR_USE_POLL
+fd_set rd;
+#else
+struct pollfd pfd;
+#endif /* _PR_USE_POLL */
+PRInt32 osfd = fd->secret->md.osfd;
+
+#ifndef _PR_USE_POLL
+    FD_ZERO(&rd);
+    FD_SET(osfd, &rd);
+#else
+    pfd.fd = osfd;
+    pfd.events = POLLIN;
+#endif /* _PR_USE_POLL */
+    while ((rv = read(osfd,buf,amount)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ,
+										PR_INTERVAL_NO_TIMEOUT)) < 0)
+					goto done;								
+            } else {
+#ifndef _PR_USE_POLL
+                while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL))
+                        == -1 && (err = _MD_ERRNO()) == EINTR) {
+                    /* retry _MD_SELECT() if it is interrupted */
+                }
+#else /* _PR_USE_POLL */
+                while ((rv = _MD_POLL(&pfd, 1, -1))
+                        == -1 && (err = _MD_ERRNO()) == EINTR) {
+                    /* retry _MD_POLL() if it is interrupted */
+                }
+#endif /* _PR_USE_POLL */
+                if (rv == -1) {
+                    break;
+                }
+            }
+            if (_PR_PENDING_INTERRUPT(me))
+                break;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            _PR_MD_MAP_READ_ERROR(err);
+        }
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+PRThread *me = _PR_MD_CURRENT_THREAD();
+PRInt32 rv, err;
+#ifndef _PR_USE_POLL
+fd_set wd;
+#else
+struct pollfd pfd;
+#endif /* _PR_USE_POLL */
+PRInt32 osfd = fd->secret->md.osfd;
+
+#ifndef _PR_USE_POLL
+    FD_ZERO(&wd);
+    FD_SET(osfd, &wd);
+#else
+    pfd.fd = osfd;
+    pfd.events = POLLOUT;
+#endif /* _PR_USE_POLL */
+    while ((rv = write(osfd,buf,amount)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE,
+										PR_INTERVAL_NO_TIMEOUT)) < 0)
+                    goto done;
+            } else {
+#ifndef _PR_USE_POLL
+                while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL))
+                        == -1 && (err = _MD_ERRNO()) == EINTR) {
+                    /* retry _MD_SELECT() if it is interrupted */
+                }
+#else /* _PR_USE_POLL */
+                while ((rv = _MD_POLL(&pfd, 1, -1))
+                        == -1 && (err = _MD_ERRNO()) == EINTR) {
+                    /* retry _MD_POLL() if it is interrupted */
+                }
+#endif /* _PR_USE_POLL */
+                if (rv == -1) {
+                    break;
+                }
+            }
+            if (_PR_PENDING_INTERRUPT(me))
+                break;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            _PR_MD_MAP_WRITE_ERROR(err);
+        }
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_fsync(PRFileDesc *fd)
+{
+PRInt32 rv, err;
+
+    rv = fsync(fd->secret->md.osfd);
+    if (rv == -1) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_FSYNC_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_close(PRInt32 osfd)
+{
+PRInt32 rv, err;
+
+    rv = close(osfd);
+    if (rv == -1) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_CLOSE_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
+{
+    PRInt32 osfd, err;
+
+    osfd = socket(domain, type, proto);
+
+    if (osfd == -1) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKET_ERROR(err);
+        return(osfd);
+    }
+
+    return(osfd);
+}
+
+PRInt32 _MD_socketavailable(PRFileDesc *fd)
+{
+    PRInt32 result;
+
+    if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+        _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO());
+        return -1;
+    }
+    return result;
+}
+
+PRInt64 _MD_socketavailable64(PRFileDesc *fd)
+{
+    PRInt64 result;
+    LL_I2L(result, _MD_socketavailable(fd));
+    return result;
+}  /* _MD_socketavailable64 */
+
+#define READ_FD        1
+#define WRITE_FD    2
+
+/*
+ * socket_io_wait --
+ *
+ * wait for socket i/o, periodically checking for interrupt
+ *
+ * The first implementation uses select(), for platforms without
+ * poll().  The second (preferred) implementation uses poll().
+ */
+
+#ifndef _PR_USE_POLL
+
+static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
+    PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    struct timeval tv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime epoch, now, elapsed, remaining;
+    PRBool wait_for_remaining;
+    PRInt32 syserror;
+    fd_set rd_wr;
+
+    switch (timeout) {
+        case PR_INTERVAL_NO_WAIT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            /*
+             * This is a special case of the 'default' case below.
+             * Please see the comments there.
+             */
+            tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+            tv.tv_usec = 0;
+            FD_ZERO(&rd_wr);
+            do {
+                FD_SET(osfd, &rd_wr);
+                if (fd_type == READ_FD)
+                    rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
+                else
+                    rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
+                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+                    _PR_MD_MAP_SELECT_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = timeout;
+            FD_ZERO(&rd_wr);
+            do {
+                /*
+                 * We block in _MD_SELECT for at most
+                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+                 * so that there is an upper limit on the delay
+                 * before the interrupt bit is checked.
+                 */
+                wait_for_remaining = PR_TRUE;
+                tv.tv_sec = PR_IntervalToSeconds(remaining);
+                if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
+                    wait_for_remaining = PR_FALSE;
+                    tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+                    tv.tv_usec = 0;
+                } else {
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        remaining -
+                        PR_SecondsToInterval(tv.tv_sec));
+                }
+                FD_SET(osfd, &rd_wr);
+                if (fd_type == READ_FD)
+                    rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
+                else
+                    rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
+                /*
+                 * we don't consider EINTR a real error
+                 */
+                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+                    _PR_MD_MAP_SELECT_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+                /*
+                 * We loop again if _MD_SELECT timed out or got interrupted
+                 * by a signal, and the timeout deadline has not passed yet.
+                 */
+                if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+                    /*
+                     * If _MD_SELECT timed out, we know how much time
+                     * we spent in blocking, so we can avoid a
+                     * PR_IntervalNow() call.
+                     */
+                    if (rv == 0) {
+                        if (wait_for_remaining) {
+                            now += remaining;
+                        } else {
+                            now += PR_SecondsToInterval(tv.tv_sec)
+                                + PR_MicrosecondsToInterval(tv.tv_usec);
+                        }
+                    } else {
+                        now = PR_IntervalNow();
+                    }
+                    elapsed = (PRIntervalTime) (now - epoch);
+                    if (elapsed >= timeout) {
+                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                        rv = -1;
+                        break;
+                    } else {
+                        remaining = timeout - elapsed;
+                    }
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+    }
+    return(rv);
+}
+
+#else /* _PR_USE_POLL */
+
+static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
+    PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    int msecs;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime epoch, now, elapsed, remaining;
+    PRBool wait_for_remaining;
+    PRInt32 syserror;
+    struct pollfd pfd;
+
+    switch (timeout) {
+        case PR_INTERVAL_NO_WAIT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            /*
+             * This is a special case of the 'default' case below.
+             * Please see the comments there.
+             */
+            msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
+            pfd.fd = osfd;
+            if (fd_type == READ_FD) {
+                pfd.events = POLLIN;
+            } else {
+                pfd.events = POLLOUT;
+            }
+            do {
+                rv = _MD_POLL(&pfd, 1, msecs);
+                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+                    _PR_MD_MAP_POLL_ERROR(syserror);
+                    break;
+                }
+				/*
+				 * If POLLERR is set, don't process it; retry the operation
+				 */
+                if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) {
+					rv = -1;
+                    _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = timeout;
+            pfd.fd = osfd;
+            if (fd_type == READ_FD) {
+                pfd.events = POLLIN;
+            } else {
+                pfd.events = POLLOUT;
+            }
+            do {
+                /*
+                 * We block in _MD_POLL for at most
+                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+                 * so that there is an upper limit on the delay
+                 * before the interrupt bit is checked.
+                 */
+                wait_for_remaining = PR_TRUE;
+                msecs = PR_IntervalToMilliseconds(remaining);
+                if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
+                    wait_for_remaining = PR_FALSE;
+                    msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
+                }
+                rv = _MD_POLL(&pfd, 1, msecs);
+                /*
+                 * we don't consider EINTR a real error
+                 */
+                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+                    _PR_MD_MAP_POLL_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+				/*
+				 * If POLLERR is set, don't process it; retry the operation
+				 */
+                if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) {
+					rv = -1;
+                    _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents);
+                    break;
+                }
+                /*
+                 * We loop again if _MD_POLL timed out or got interrupted
+                 * by a signal, and the timeout deadline has not passed yet.
+                 */
+                if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+                    /*
+                     * If _MD_POLL timed out, we know how much time
+                     * we spent in blocking, so we can avoid a
+                     * PR_IntervalNow() call.
+                     */
+                    if (rv == 0) {
+                        if (wait_for_remaining) {
+                            now += remaining;
+                        } else {
+                            now += PR_MillisecondsToInterval(msecs);
+                        }
+                    } else {
+                        now = PR_IntervalNow();
+                    }
+                    elapsed = (PRIntervalTime) (now - epoch);
+                    if (elapsed >= timeout) {
+                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                        rv = -1;
+                        break;
+                    } else {
+                        remaining = timeout - elapsed;
+                    }
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+    }
+    return(rv);
+}
+
+#endif /* _PR_USE_POLL */
+
+static PRInt32 local_io_wait(
+    PRInt32 osfd,
+    PRInt32 wait_flag,
+    PRIntervalTime timeout)
+{
+    _PRUnixPollDesc pd;
+    PRInt32 rv;
+
+    PR_LOG(_pr_io_lm, PR_LOG_MIN,
+       ("waiting to %s on osfd=%d",
+        (wait_flag == _PR_UNIX_POLL_READ) ? "read" : "write",
+        osfd));
+
+    if (timeout == PR_INTERVAL_NO_WAIT) return 0;
+
+    pd.osfd = osfd;
+    pd.in_flags = wait_flag;
+    pd.out_flags = 0;
+
+    rv = _PR_WaitForMultipleFDs(&pd, 1, timeout);
+
+    if (rv == 0) {
+        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        rv = -1;
+    }
+    return rv;
+}
+
+
+PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+                                PRInt32 flags, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+/*
+ * Many OS's (Solaris, Unixware) have a broken recv which won't read
+ * from socketpairs.  As long as we don't use flags on socketpairs, this
+ * is a decent fix. - mikep
+ */
+#if defined(UNIXWARE) || defined(SOLARIS) || defined(NCR)
+    while ((rv = read(osfd,buf,amount)) == -1) {
+#else
+    while ((rv = recv(osfd,buf,amount,flags)) == -1) {
+#endif
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+				if ((rv = local_io_wait(osfd,_PR_UNIX_POLL_READ,timeout)) < 0)
+					goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+                        PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((*addrlen = PR_NETADDR_SIZE(addr)),
+                ((rv = recvfrom(osfd, buf, amount, flags,
+                        (struct sockaddr *) addr, (_PRSockLen_t *)addrlen)) == -1)) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0)
+                    goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+done:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv != -1) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    return(rv);
+}
+
+PRInt32 _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+                            PRInt32 flags, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+#if defined(SOLARIS)
+	PRInt32 tmp_amount = amount;
+#endif
+
+    /*
+     * On pre-2.6 Solaris, send() is much slower than write().
+     * On 2.6 and beyond, with in-kernel sockets, send() and
+     * write() are fairly equivalent in performance.
+     */
+#if defined(SOLARIS)
+    PR_ASSERT(0 == flags);
+    while ((rv = write(osfd,buf,tmp_amount)) == -1) {
+#else
+    while ((rv = send(osfd,buf,amount,flags)) == -1) {
+#endif
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
+                    goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+#if defined(SOLARIS)
+			/*
+			 * The write system call has been reported to return the ERANGE
+			 * error on occasion. Try to write in smaller chunks to workaround
+			 * this bug.
+			 */
+			if (err == ERANGE) {
+				if (tmp_amount > 1) {
+					tmp_amount = tmp_amount/2;	/* half the bytes */
+					continue;
+				}
+			}
+#endif
+            break;
+        }
+    }
+        /*
+         * optimization; if bytes sent is less than "amount" call
+         * select before returning. This is because it is likely that
+         * the next send() call will return EWOULDBLOCK.
+         */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+            && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (_PR_IS_NATIVE_THREAD(me)) {
+			if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) {
+				rv = -1;
+				goto done;
+			}
+        } else {
+			if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) {
+				rv = -1;
+				goto done;
+			}
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SEND_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_sendto(
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+    const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+
+    while ((rv = sendto(osfd, buf, amount, flags,
+            (struct sockaddr *) &addrCopy, addrlen)) == -1) {
+#else
+    while ((rv = sendto(osfd, buf, amount, flags,
+            (struct sockaddr *) addr, addrlen)) == -1) {
+#endif
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
+					goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SENDTO_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_writev(
+    PRFileDesc *fd, const PRIOVec *iov,
+    PRInt32 iov_size, PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 index, amount = 0;
+    PRInt32 osfd = fd->secret->md.osfd;
+
+    /*
+     * Calculate the total number of bytes to be sent; needed for
+     * optimization later.
+     * We could avoid this if this number was passed in; but it is
+     * probably not a big deal because iov_size is usually small (less than
+     * 3)
+     */
+    if (!fd->secret->nonblocking) {
+        for (index=0; index<iov_size; index++) {
+            amount += iov[index].iov_len;
+        }
+    }
+
+    while ((rv = writev(osfd, (const struct iovec*)iov, iov_size)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
+					goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    /*
+     * optimization; if bytes sent is less than "amount" call
+     * select before returning. This is because it is likely that
+     * the next writev() call will return EWOULDBLOCK.
+     */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+            && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (_PR_IS_NATIVE_THREAD(me)) {
+            if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
+				rv = -1;
+                goto done;
+			}
+        } else {
+			if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) {
+				rv = -1;
+				goto done;
+			}
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_WRITEV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr,
+                            PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = accept(osfd, (struct sockaddr *) addr,
+                                        (_PRSockLen_t *)addrlen)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK) || (err == ECONNABORTED)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0)
+					goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_ACCEPT_ERROR(err);
+    }
+done:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv != -1) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    return(rv);
+}
+
+extern int _connect (int s, const struct sockaddr *name, int namelen);
+PRInt32 _MD_connect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 osfd = fd->secret->md.osfd;
+#ifdef IRIX
+extern PRInt32 _MD_irix_connect(
+        PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout);
+#endif
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+#endif
+
+    /*
+     * We initiate the connection setup by making a nonblocking connect()
+     * call.  If the connect() call fails, there are two cases we handle
+     * specially:
+     * 1. The connect() call was interrupted by a signal.  In this case
+     *    we simply retry connect().
+     * 2. The NSPR socket is nonblocking and connect() fails with
+     *    EINPROGRESS.  We first wait until the socket becomes writable.
+     *    Then we try to find out whether the connection setup succeeded
+     *    or failed.
+     */
+
+retry:
+#ifdef IRIX
+    if ((rv = _MD_irix_connect(osfd, addr, addrlen, timeout)) == -1) {
+#else
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) {
+#else
+    if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {
+#endif
+#endif
+        err = _MD_ERRNO();
+
+        if (err == EINTR) {
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            goto retry;
+        }
+
+        if (!fd->secret->nonblocking && (err == EINPROGRESS)) {
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+
+				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
+                    return -1;
+            } else {
+                /*
+                 * socket_io_wait() may return -1 or 1.
+                 */
+
+                rv = socket_io_wait(osfd, WRITE_FD, timeout);
+                if (rv == -1) {
+                    return -1;
+                }
+            }
+
+            PR_ASSERT(rv == 1);
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            err = _MD_unix_get_nonblocking_connect_error(osfd);
+            if (err != 0) {
+                _PR_MD_MAP_CONNECT_ERROR(err);
+                return -1;
+            }
+            return 0;
+        }
+
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+
+    return rv;
+}  /* _MD_connect */
+
+PRInt32 _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv, err;
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen);
+#else
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);
+#endif
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_BIND_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv, err;
+
+    rv = listen(fd->secret->md.osfd, backlog);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_LISTEN_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_shutdown(PRFileDesc *fd, PRIntn how)
+{
+    PRInt32 rv, err;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SHUTDOWN_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_socketpair(int af, int type, int flags,
+                                                        PRInt32 *osfd)
+{
+    PRInt32 rv, err;
+
+    rv = socketpair(af, type, flags, osfd);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKETPAIR_ERROR(err);
+    }
+    return rv;
+}
+
+PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
+                                                PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockname(fd->secret->md.osfd,
+            (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv == 0) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETSOCKNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
+                                        PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getpeername(fd->secret->md.osfd,
+            (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv == 0) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETPEERNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level,
+                        PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (_PRSockLen_t *)optlen);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level,   
+                    PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv, err;
+
+    rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable)
+{
+    int rv;
+
+    rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);
+    if (-1 == rv) {
+        PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported)
+{
+    if (imported) {
+        fd->secret->inheritable = _PR_TRI_UNKNOWN;
+    } else {
+        /* By default, a Unix fd is not closed on exec. */
+#ifdef DEBUG
+        {
+            int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
+            PR_ASSERT(0 == flags);
+        }
+#endif
+        fd->secret->inheritable = _PR_TRI_TRUE;
+    }
+}
+
+/************************************************************************/
+#if !defined(_PR_USE_POLL)
+
+/*
+** Scan through io queue and find any bad fd's that triggered the error
+** from _MD_SELECT
+*/
+static void FindBadFDs(void)
+{
+    PRCList *q;
+    PRThread *me = _MD_CURRENT_THREAD();
+
+    PR_ASSERT(!_PR_IS_NATIVE_THREAD(me));
+    q = (_PR_IOQ(me->cpu)).next;
+    _PR_IOQ_MAX_OSFD(me->cpu) = -1;
+    _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
+    while (q != &_PR_IOQ(me->cpu)) {
+        PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+        PRBool notify = PR_FALSE;
+        _PRUnixPollDesc *pds = pq->pds;
+        _PRUnixPollDesc *epds = pds + pq->npds;
+        PRInt32 pq_max_osfd = -1;
+
+        q = q->next;
+        for (; pds < epds; pds++) {
+            PRInt32 osfd = pds->osfd;
+            pds->out_flags = 0;
+            PR_ASSERT(osfd >= 0 || pds->in_flags == 0);
+            if (pds->in_flags == 0) {
+                continue;  /* skip this fd */
+            }
+            if (fcntl(osfd, F_GETFL, 0) == -1) {
+                /* Found a bad descriptor, remove it from the fd_sets. */
+                PR_LOG(_pr_io_lm, PR_LOG_MAX,
+                    ("file descriptor %d is bad", osfd));
+                pds->out_flags = _PR_UNIX_POLL_NVAL;
+                notify = PR_TRUE;
+            }
+            if (osfd > pq_max_osfd) {
+                pq_max_osfd = osfd;
+            }
+        }
+
+        if (notify) {
+            PRIntn pri;
+            PR_REMOVE_LINK(&pq->links);
+            pq->on_ioq = PR_FALSE;
+
+            /*
+         * Decrement the count of descriptors for each desciptor/event
+         * because this I/O request is being removed from the
+         * ioq
+         */
+            pds = pq->pds;
+            for (; pds < epds; pds++) {
+                PRInt32 osfd = pds->osfd;
+                PRInt16 in_flags = pds->in_flags;
+                PR_ASSERT(osfd >= 0 || in_flags == 0);
+                if (in_flags & _PR_UNIX_POLL_READ) {
+                    if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                }
+                if (in_flags & _PR_UNIX_POLL_WRITE) {
+                    if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                }
+                if (in_flags & _PR_UNIX_POLL_EXCEPT) {
+                    if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                }
+            }
+
+            _PR_THREAD_LOCK(pq->thr);
+            if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+                _PRCPU *cpu = pq->thr->cpu;
+                _PR_SLEEPQ_LOCK(pq->thr->cpu);
+                _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
+                _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
+
+				if (pq->thr->flags & _PR_SUSPENDING) {
+				    /*
+				     * set thread state to SUSPENDED;
+				     * a Resume operation on the thread
+				     * will move it to the runQ
+				     */
+				    pq->thr->state = _PR_SUSPENDED;
+				    _PR_MISCQ_LOCK(pq->thr->cpu);
+				    _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
+				    _PR_MISCQ_UNLOCK(pq->thr->cpu);
+				} else {
+				    pri = pq->thr->priority;
+				    pq->thr->state = _PR_RUNNABLE;
+
+				    _PR_RUNQ_LOCK(cpu);
+				    _PR_ADD_RUNQ(pq->thr, cpu, pri);
+				    _PR_RUNQ_UNLOCK(cpu);
+				}
+            }
+            _PR_THREAD_UNLOCK(pq->thr);
+        } else {
+            if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
+                _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
+                _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
+        }
+    }
+    if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+        if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
+            _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+    }
+}
+#endif  /* !defined(_PR_USE_POLL) */
+
+/************************************************************************/
+
+/*
+** Called by the scheduler when there is nothing to do. This means that
+** all threads are blocked on some monitor somewhere.
+**
+** Note: this code doesn't release the scheduler lock.
+*/
+/*
+** Pause the current CPU. longjmp to the cpu's pause stack
+**
+** This must be called with the scheduler locked
+*/
+void _MD_PauseCPU(PRIntervalTime ticks)
+{
+    PRThread *me = _MD_CURRENT_THREAD();
+#ifdef _PR_USE_POLL
+    int timeout;
+    struct pollfd *pollfds;    /* an array of pollfd structures */
+    struct pollfd *pollfdPtr;    /* a pointer that steps through the array */
+    unsigned long npollfds;     /* number of pollfd structures in array */
+    unsigned long pollfds_size;
+    int nfd;                    /* to hold the return value of poll() */
+#else
+    struct timeval timeout, *tvp;
+    fd_set r, w, e;
+    fd_set *rp, *wp, *ep;
+    PRInt32 max_osfd, nfd;
+#endif  /* _PR_USE_POLL */
+    PRInt32 rv;
+    PRCList *q;
+    PRUint32 min_timeout;
+    sigset_t oldset;
+#ifdef IRIX
+extern sigset_t ints_off;
+#endif
+
+    PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
+
+    _PR_MD_IOQ_LOCK();
+
+#ifdef _PR_USE_POLL
+    /* Build up the pollfd structure array to wait on */
+
+    /* Find out how many pollfd structures are needed */
+    npollfds = _PR_IOQ_OSFD_CNT(me->cpu);
+    PR_ASSERT(npollfds >= 0);
+
+    /*
+     * We use a pipe to wake up a native thread.  An fd is needed
+     * for the pipe and we poll it for reading.
+     */
+    if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+        npollfds++;
+#ifdef	IRIX
+		/*
+		 * On Irix, a second pipe is used to cause the primordial cpu to
+		 * wakeup and exit, when the process is exiting because of a call
+		 * to exit/PR_ProcessExit.
+		 */
+		if (me->cpu->id == 0) {
+        	npollfds++;
+		}
+#endif
+	}
+
+    /*
+     * if the cpu's pollfd array is not big enough, release it and allocate a new one
+     */
+    if (npollfds > _PR_IOQ_POLLFDS_SIZE(me->cpu)) {
+        if (_PR_IOQ_POLLFDS(me->cpu) != NULL)
+            PR_DELETE(_PR_IOQ_POLLFDS(me->cpu));
+        pollfds_size =  PR_MAX(_PR_IOQ_MIN_POLLFDS_SIZE(me->cpu), npollfds);
+        pollfds = (struct pollfd *) PR_MALLOC(pollfds_size * sizeof(struct pollfd));
+        _PR_IOQ_POLLFDS(me->cpu) = pollfds;
+        _PR_IOQ_POLLFDS_SIZE(me->cpu) = pollfds_size;
+    } else {
+        pollfds = _PR_IOQ_POLLFDS(me->cpu);
+    }
+    pollfdPtr = pollfds;
+
+    /*
+     * If we need to poll the pipe for waking up a native thread,
+     * the pipe's fd is the first element in the pollfds array.
+     */
+    if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+        pollfdPtr->fd = _pr_md_pipefd[0];
+        pollfdPtr->events = POLLIN;
+        pollfdPtr++;
+#ifdef	IRIX
+		/*
+		 * On Irix, the second element is the exit pipe
+		 */
+		if (me->cpu->id == 0) {
+			pollfdPtr->fd = _pr_irix_primoridal_cpu_fd[0];
+			pollfdPtr->events = POLLIN;
+			pollfdPtr++;
+		}
+#endif
+    }
+
+    min_timeout = PR_INTERVAL_NO_TIMEOUT;
+    for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) {
+        PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+        _PRUnixPollDesc *pds = pq->pds;
+        _PRUnixPollDesc *epds = pds + pq->npds;
+
+        if (pq->timeout < min_timeout) {
+            min_timeout = pq->timeout;
+        }
+        for (; pds < epds; pds++, pollfdPtr++) {
+            /*
+         * Assert that the pollfdPtr pointer does not go
+         * beyond the end of the pollfds array
+         */
+            PR_ASSERT(pollfdPtr < pollfds + npollfds);
+            pollfdPtr->fd = pds->osfd;
+            /* direct copy of poll flags */
+            pollfdPtr->events = pds->in_flags;
+        }
+    }
+    _PR_IOQ_TIMEOUT(me->cpu) = min_timeout;
+#else
+    /*
+     * assigment of fd_sets
+     */
+    r = _PR_FD_READ_SET(me->cpu);
+    w = _PR_FD_WRITE_SET(me->cpu);
+    e = _PR_FD_EXCEPTION_SET(me->cpu);
+
+    rp = &r;
+    wp = &w;
+    ep = &e;
+
+    max_osfd = _PR_IOQ_MAX_OSFD(me->cpu) + 1;
+    min_timeout = _PR_IOQ_TIMEOUT(me->cpu);
+#endif  /* _PR_USE_POLL */
+    /*
+    ** Compute the minimum timeout value: make it the smaller of the
+    ** timeouts specified by the i/o pollers or the timeout of the first
+    ** sleeping thread.
+    */
+    q = _PR_SLEEPQ(me->cpu).next;
+
+    if (q != &_PR_SLEEPQ(me->cpu)) {
+        PRThread *t = _PR_THREAD_PTR(q);
+
+        if (t->sleep < min_timeout) {
+            min_timeout = t->sleep;
+        }
+    }
+    if (min_timeout > ticks) {
+        min_timeout = ticks;
+    }
+
+#ifdef _PR_USE_POLL
+    if (min_timeout == PR_INTERVAL_NO_TIMEOUT)
+        timeout = -1;
+    else
+        timeout = PR_IntervalToMilliseconds(min_timeout);
+#else
+    if (min_timeout == PR_INTERVAL_NO_TIMEOUT) {
+        tvp = NULL;
+    } else {
+        timeout.tv_sec = PR_IntervalToSeconds(min_timeout);
+        timeout.tv_usec = PR_IntervalToMicroseconds(min_timeout)
+            % PR_USEC_PER_SEC;
+        tvp = &timeout;
+    }
+#endif  /* _PR_USE_POLL */
+
+    _PR_MD_IOQ_UNLOCK();
+    _MD_CHECK_FOR_EXIT();
+    /*
+     * check for i/o operations
+     */
+#ifndef _PR_NO_CLOCK_TIMER
+    /*
+     * Disable the clock interrupts while we are in select, if clock interrupts
+     * are enabled. Otherwise, when the select/poll calls are interrupted, the
+     * timer value starts ticking from zero again when the system call is restarted.
+     */
+#ifdef IRIX
+    /*
+     * SIGCHLD signal is used on Irix to detect he termination of an
+     * sproc by SIGSEGV, SIGBUS or SIGABRT signals when
+     * _nspr_terminate_on_error is set.
+     */
+    if ((!_nspr_noclock) || (_nspr_terminate_on_error))
+#else
+        if (!_nspr_noclock)
+#endif    /* IRIX */
+#ifdef IRIX
+    sigprocmask(SIG_BLOCK, &ints_off, &oldset);
+#else
+    PR_ASSERT(sigismember(&timer_set, SIGALRM));
+    sigprocmask(SIG_BLOCK, &timer_set, &oldset);
+#endif    /* IRIX */
+#endif  /* !_PR_NO_CLOCK_TIMER */
+
+#ifndef _PR_USE_POLL
+    PR_ASSERT(FD_ISSET(_pr_md_pipefd[0],rp));
+    nfd = _MD_SELECT(max_osfd, rp, wp, ep, tvp);
+#else
+    nfd = _MD_POLL(pollfds, npollfds, timeout);
+#endif  /* !_PR_USE_POLL */
+
+#ifndef _PR_NO_CLOCK_TIMER
+#ifdef IRIX
+    if ((!_nspr_noclock) || (_nspr_terminate_on_error))
+#else
+        if (!_nspr_noclock)
+#endif    /* IRIX */
+    sigprocmask(SIG_SETMASK, &oldset, 0);
+#endif  /* !_PR_NO_CLOCK_TIMER */
+
+    _MD_CHECK_FOR_EXIT();
+
+#ifdef IRIX
+	_PR_MD_primordial_cpu();
+#endif
+
+    _PR_MD_IOQ_LOCK();
+    /*
+    ** Notify monitors that are associated with the selected descriptors.
+    */
+#ifdef _PR_USE_POLL
+    if (nfd > 0) {
+        pollfdPtr = pollfds;
+        if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+            /*
+			 * Assert that the pipe is the first element in the
+			 * pollfds array.
+			 */
+            PR_ASSERT(pollfds[0].fd == _pr_md_pipefd[0]);
+            if ((pollfds[0].revents & POLLIN) && (nfd == 1)) {
+                /*
+				 * woken up by another thread; read all the data
+				 * in the pipe to empty the pipe
+				 */
+                while ((rv = read(_pr_md_pipefd[0], _pr_md_pipebuf,
+                    PIPE_BUF)) == PIPE_BUF){
+                }
+                PR_ASSERT((rv > 0) || ((rv == -1) && (errno == EAGAIN)));
+            }
+            pollfdPtr++;
+#ifdef	IRIX
+			/*
+			 * On Irix, check to see if the primordial cpu needs to exit
+			 * to cause the process to terminate
+			 */
+			if (me->cpu->id == 0) {
+            	PR_ASSERT(pollfds[1].fd == _pr_irix_primoridal_cpu_fd[0]);
+				if (pollfdPtr->revents & POLLIN) {
+					if (_pr_irix_process_exit) {
+						/*
+						 * process exit due to a call to PR_ProcessExit
+						 */
+						prctl(PR_SETEXITSIG, SIGKILL);
+						_exit(_pr_irix_process_exit_code);
+					} else {
+						while ((rv = read(_pr_irix_primoridal_cpu_fd[0],
+							_pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) {
+						}
+						PR_ASSERT(rv > 0);
+					}
+				}
+				pollfdPtr++;
+			}
+#endif
+        }
+        for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) {
+            PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+            PRBool notify = PR_FALSE;
+            _PRUnixPollDesc *pds = pq->pds;
+            _PRUnixPollDesc *epds = pds + pq->npds;
+
+            for (; pds < epds; pds++, pollfdPtr++) {
+                /*
+                  * Assert that the pollfdPtr pointer does not go beyond
+                  * the end of the pollfds array.
+                  */
+                PR_ASSERT(pollfdPtr < pollfds + npollfds);
+                /*
+                 * Assert that the fd's in the pollfds array (stepped
+                 * through by pollfdPtr) are in the same order as
+                 * the fd's in _PR_IOQ() (stepped through by q and pds).
+                 * This is how the pollfds array was created earlier.
+                 */
+                PR_ASSERT(pollfdPtr->fd == pds->osfd);
+                pds->out_flags = pollfdPtr->revents;
+                /* Negative fd's are ignored by poll() */
+                if (pds->osfd >= 0 && pds->out_flags) {
+                    notify = PR_TRUE;
+                }
+            }
+            if (notify) {
+                PRIntn pri;
+                PRThread *thred;
+
+                PR_REMOVE_LINK(&pq->links);
+                pq->on_ioq = PR_FALSE;
+
+                thred = pq->thr;
+                _PR_THREAD_LOCK(thred);
+                if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+                    _PRCPU *cpu = pq->thr->cpu;
+                    _PR_SLEEPQ_LOCK(pq->thr->cpu);
+                    _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
+                    _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
+
+					if (pq->thr->flags & _PR_SUSPENDING) {
+					    /*
+					     * set thread state to SUSPENDED;
+					     * a Resume operation on the thread
+					     * will move it to the runQ
+					     */
+					    pq->thr->state = _PR_SUSPENDED;
+					    _PR_MISCQ_LOCK(pq->thr->cpu);
+					    _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
+					    _PR_MISCQ_UNLOCK(pq->thr->cpu);
+					} else {
+						pri = pq->thr->priority;
+						pq->thr->state = _PR_RUNNABLE;
+
+						_PR_RUNQ_LOCK(cpu);
+						_PR_ADD_RUNQ(pq->thr, cpu, pri);
+						_PR_RUNQ_UNLOCK(cpu);
+						if (_pr_md_idle_cpus > 1)
+							_PR_MD_WAKEUP_WAITER(thred);
+					}
+                }
+                _PR_THREAD_UNLOCK(thred);
+                _PR_IOQ_OSFD_CNT(me->cpu) -= pq->npds;
+                PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
+            }
+        }
+    } else if (nfd == -1) {
+        PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno));
+    }
+
+#else
+    if (nfd > 0) {
+        q = _PR_IOQ(me->cpu).next;
+        _PR_IOQ_MAX_OSFD(me->cpu) = -1;
+        _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
+        while (q != &_PR_IOQ(me->cpu)) {
+            PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+            PRBool notify = PR_FALSE;
+            _PRUnixPollDesc *pds = pq->pds;
+            _PRUnixPollDesc *epds = pds + pq->npds;
+            PRInt32 pq_max_osfd = -1;
+
+            q = q->next;
+            for (; pds < epds; pds++) {
+                PRInt32 osfd = pds->osfd;
+                PRInt16 in_flags = pds->in_flags;
+                PRInt16 out_flags = 0;
+                PR_ASSERT(osfd >= 0 || in_flags == 0);
+                if ((in_flags & _PR_UNIX_POLL_READ) && FD_ISSET(osfd, rp)) {
+                    out_flags |= _PR_UNIX_POLL_READ;
+                }
+                if ((in_flags & _PR_UNIX_POLL_WRITE) && FD_ISSET(osfd, wp)) {
+                    out_flags |= _PR_UNIX_POLL_WRITE;
+                }
+                if ((in_flags & _PR_UNIX_POLL_EXCEPT) && FD_ISSET(osfd, ep)) {
+                    out_flags |= _PR_UNIX_POLL_EXCEPT;
+                }
+                pds->out_flags = out_flags;
+                if (out_flags) {
+                    notify = PR_TRUE;
+                }
+                if (osfd > pq_max_osfd) {
+                    pq_max_osfd = osfd;
+                }
+            }
+            if (notify == PR_TRUE) {
+                PRIntn pri;
+                PRThread *thred;
+
+                PR_REMOVE_LINK(&pq->links);
+                pq->on_ioq = PR_FALSE;
+
+                /*
+                 * Decrement the count of descriptors for each desciptor/event
+                 * because this I/O request is being removed from the
+                 * ioq
+                 */
+                pds = pq->pds;
+                for (; pds < epds; pds++) {
+                    PRInt32 osfd = pds->osfd;
+                    PRInt16 in_flags = pds->in_flags;
+                    PR_ASSERT(osfd >= 0 || in_flags == 0);
+                    if (in_flags & _PR_UNIX_POLL_READ) {
+                        if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                    }
+                    if (in_flags & _PR_UNIX_POLL_WRITE) {
+                        if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                    }
+                    if (in_flags & _PR_UNIX_POLL_EXCEPT) {
+                        if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                    }
+                }
+
+                /*
+                 * Because this thread can run on a different cpu right
+                 * after being added to the run queue, do not dereference
+                 * pq
+                 */
+                 thred = pq->thr;
+                _PR_THREAD_LOCK(thred);
+                if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+                    _PRCPU *cpu = thred->cpu;
+                    _PR_SLEEPQ_LOCK(pq->thr->cpu);
+                    _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
+                    _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
+
+					if (pq->thr->flags & _PR_SUSPENDING) {
+					    /*
+					     * set thread state to SUSPENDED;
+					     * a Resume operation on the thread
+					     * will move it to the runQ
+					     */
+					    pq->thr->state = _PR_SUSPENDED;
+					    _PR_MISCQ_LOCK(pq->thr->cpu);
+					    _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
+					    _PR_MISCQ_UNLOCK(pq->thr->cpu);
+					} else {
+						pri = pq->thr->priority;
+						pq->thr->state = _PR_RUNNABLE;
+
+						pq->thr->cpu = cpu;
+						_PR_RUNQ_LOCK(cpu);
+						_PR_ADD_RUNQ(pq->thr, cpu, pri);
+						_PR_RUNQ_UNLOCK(cpu);
+						if (_pr_md_idle_cpus > 1)
+							_PR_MD_WAKEUP_WAITER(thred);
+					}
+                }
+                _PR_THREAD_UNLOCK(thred);
+            } else {
+                if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
+                    _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
+                if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
+                    _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
+            }
+        }
+        if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+            if ((FD_ISSET(_pr_md_pipefd[0], rp)) && (nfd == 1)) {
+                /*
+             * woken up by another thread; read all the data
+             * in the pipe to empty the pipe
+             */
+                while ((rv =
+                    read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF))
+                    == PIPE_BUF){
+                }
+                PR_ASSERT((rv > 0) ||
+                    ((rv == -1) && (errno == EAGAIN)));
+            }
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
+                _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+#ifdef	IRIX
+			if ((me->cpu->id == 0) && 
+						(FD_ISSET(_pr_irix_primoridal_cpu_fd[0], rp))) {
+				if (_pr_irix_process_exit) {
+					/*
+					 * process exit due to a call to PR_ProcessExit
+					 */
+					prctl(PR_SETEXITSIG, SIGKILL);
+					_exit(_pr_irix_process_exit_code);
+				} else {
+						while ((rv = read(_pr_irix_primoridal_cpu_fd[0],
+							_pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) {
+						}
+						PR_ASSERT(rv > 0);
+				}
+			}
+			if (me->cpu->id == 0) {
+				if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_irix_primoridal_cpu_fd[0])
+					_PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0];
+			}
+#endif
+        }
+    } else if (nfd < 0) {
+        if (errno == EBADF) {
+            FindBadFDs();
+        } else {
+            PR_LOG(_pr_io_lm, PR_LOG_MAX, ("select() failed with errno %d",
+                errno));
+        }
+    } else {
+        PR_ASSERT(nfd == 0);
+        /*
+         * compute the new value of _PR_IOQ_TIMEOUT
+         */
+        q = _PR_IOQ(me->cpu).next;
+        _PR_IOQ_MAX_OSFD(me->cpu) = -1;
+        _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
+        while (q != &_PR_IOQ(me->cpu)) {
+            PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+            _PRUnixPollDesc *pds = pq->pds;
+            _PRUnixPollDesc *epds = pds + pq->npds;
+            PRInt32 pq_max_osfd = -1;
+
+            q = q->next;
+            for (; pds < epds; pds++) {
+                if (pds->osfd > pq_max_osfd) {
+                    pq_max_osfd = pds->osfd;
+                }
+            }
+            if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
+                _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
+                _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
+        }
+        if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
+                _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+        }
+    }
+#endif  /* _PR_USE_POLL */
+    _PR_MD_IOQ_UNLOCK();
+}
+
+void _MD_Wakeup_CPUs()
+{
+    PRInt32 rv, data;
+
+    data = 0;
+    rv = write(_pr_md_pipefd[1], &data, 1);
+
+    while ((rv < 0) && (errno == EAGAIN)) {
+        /*
+         * pipe full, read all data in pipe to empty it
+         */
+        while ((rv =
+            read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF))
+            == PIPE_BUF) {
+        }
+        PR_ASSERT((rv > 0) ||
+            ((rv == -1) && (errno == EAGAIN)));
+        rv = write(_pr_md_pipefd[1], &data, 1);
+    }
+}
+
+
+void _MD_InitCPUS()
+{
+    PRInt32 rv, flags;
+    PRThread *me = _MD_CURRENT_THREAD();
+
+    rv = pipe(_pr_md_pipefd);
+    PR_ASSERT(rv == 0);
+    _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+#ifndef _PR_USE_POLL
+    FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu));
+#endif
+
+    flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0);
+    fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK);
+    flags = fcntl(_pr_md_pipefd[1], F_GETFL, 0);
+    fcntl(_pr_md_pipefd[1], F_SETFL, flags | O_NONBLOCK);
+}
+
+/*
+** Unix SIGALRM (clock) signal handler
+*/
+static void ClockInterruptHandler()
+{
+    int olderrno;
+    PRUintn pri;
+    _PRCPU *cpu = _PR_MD_CURRENT_CPU();
+    PRThread *me = _MD_CURRENT_THREAD();
+
+#ifdef SOLARIS
+    if (!me || _PR_IS_NATIVE_THREAD(me)) {
+        _pr_primordialCPU->u.missed[_pr_primordialCPU->where] |= _PR_MISSED_CLOCK;
+        return;
+    }
+#endif
+
+    if (_PR_MD_GET_INTSOFF() != 0) {
+        cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK;
+        return;
+    }
+    _PR_MD_SET_INTSOFF(1);
+
+    olderrno = errno;
+    _PR_ClockInterrupt();
+    errno = olderrno;
+
+    /*
+    ** If the interrupt wants a resched or if some other thread at
+    ** the same priority needs the cpu, reschedule.
+    */
+    pri = me->priority;
+    if ((cpu->u.missed[3] || (_PR_RUNQREADYMASK(me->cpu) >> pri))) {
+#ifdef _PR_NO_PREEMPT
+        cpu->resched = PR_TRUE;
+        if (pr_interruptSwitchHook) {
+            (*pr_interruptSwitchHook)(pr_interruptSwitchHookArg);
+        }
+#else /* _PR_NO_PREEMPT */
+        /*
+    ** Re-enable unix interrupts (so that we can use
+    ** setjmp/longjmp for context switching without having to
+    ** worry about the signal state)
+    */
+        sigprocmask(SIG_SETMASK, &empty_set, 0);
+        PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock caused context switch"));
+
+        if(!(me->flags & _PR_IDLE_THREAD)) {
+            _PR_THREAD_LOCK(me);
+            me->state = _PR_RUNNABLE;
+            me->cpu = cpu;
+            _PR_RUNQ_LOCK(cpu);
+            _PR_ADD_RUNQ(me, cpu, pri);
+            _PR_RUNQ_UNLOCK(cpu);
+            _PR_THREAD_UNLOCK(me);
+        } else
+            me->state = _PR_RUNNABLE;
+        _MD_SWITCH_CONTEXT(me);
+        PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock back from context switch"));
+#endif /* _PR_NO_PREEMPT */
+    }
+    /*
+     * Because this thread could be running on a different cpu after
+     * a context switch the current cpu should be accessed and the
+     * value of the 'cpu' variable should not be used.
+     */
+    _PR_MD_SET_INTSOFF(0);
+}
+
+/*
+ * On HP-UX 9, we have to use the sigvector() interface to restart
+ * interrupted system calls, because sigaction() does not have the
+ * SA_RESTART flag.
+ */
+
+#ifdef HPUX9
+static void HPUX9_ClockInterruptHandler(
+    int sig,
+    int code,
+    struct sigcontext *scp)
+{
+    ClockInterruptHandler();
+    scp->sc_syscall_action = SIG_RESTART;
+}
+#endif /* HPUX9 */
+
+/* # of milliseconds per clock tick that we will use */
+#define MSEC_PER_TICK    50
+
+
+void _MD_StartInterrupts()
+{
+    char *eval;
+
+    if ((eval = getenv("NSPR_NOCLOCK")) != NULL) {
+        if (atoi(eval) == 0)
+            _nspr_noclock = 0;
+        else
+            _nspr_noclock = 1;
+    }
+
+#ifndef _PR_NO_CLOCK_TIMER
+    if (!_nspr_noclock) {
+        _MD_EnableClockInterrupts();
+    }
+#endif
+}
+
+void _MD_StopInterrupts()
+{
+    sigprocmask(SIG_BLOCK, &timer_set, 0);
+}
+
+void _MD_EnableClockInterrupts()
+{
+    struct itimerval itval;
+    extern PRUintn _pr_numCPU;
+#ifdef HPUX9
+    struct sigvec vec;
+
+    vec.sv_handler = (void (*)()) HPUX9_ClockInterruptHandler;
+    vec.sv_mask = 0;
+    vec.sv_flags = 0;
+    sigvector(SIGALRM, &vec, 0);
+#else
+    struct sigaction vtact;
+
+    vtact.sa_handler = (void (*)()) ClockInterruptHandler;
+    sigemptyset(&vtact.sa_mask);
+    vtact.sa_flags = SA_RESTART;
+    sigaction(SIGALRM, &vtact, 0);
+#endif /* HPUX9 */
+
+    PR_ASSERT(_pr_numCPU == 1);
+	itval.it_interval.tv_sec = 0;
+	itval.it_interval.tv_usec = MSEC_PER_TICK * PR_USEC_PER_MSEC;
+	itval.it_value = itval.it_interval;
+	setitimer(ITIMER_REAL, &itval, 0);
+}
+
+void _MD_DisableClockInterrupts()
+{
+    struct itimerval itval;
+    extern PRUintn _pr_numCPU;
+
+    PR_ASSERT(_pr_numCPU == 1);
+	itval.it_interval.tv_sec = 0;
+	itval.it_interval.tv_usec = 0;
+	itval.it_value = itval.it_interval;
+	setitimer(ITIMER_REAL, &itval, 0);
+}
+
+void _MD_BlockClockInterrupts()
+{
+    sigprocmask(SIG_BLOCK, &timer_set, 0);
+}
+
+void _MD_UnblockClockInterrupts()
+{
+    sigprocmask(SIG_UNBLOCK, &timer_set, 0);
+}
+
+void _MD_MakeNonblock(PRFileDesc *fd)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    int flags;
+
+    if (osfd <= 2) {
+        /* Don't mess around with stdin, stdout or stderr */
+        return;
+    }
+    flags = fcntl(osfd, F_GETFL, 0);
+
+    /*
+     * Use O_NONBLOCK (POSIX-style non-blocking I/O) whenever possible.
+     * On SunOS 4, we must use FNDELAY (BSD-style non-blocking I/O),
+     * otherwise connect() still blocks and can be interrupted by SIGALRM.
+     */
+
+#ifdef SUNOS4
+    fcntl(osfd, F_SETFL, flags | FNDELAY);
+#else
+    fcntl(osfd, F_SETFL, flags | O_NONBLOCK);
+#endif
+    }
+
+PRInt32 _MD_open(const char *name, PRIntn flags, PRIntn mode)
+{
+    PRInt32 osflags;
+    PRInt32 rv, err;
+
+    if (flags & PR_RDWR) {
+        osflags = O_RDWR;
+    } else if (flags & PR_WRONLY) {
+        osflags = O_WRONLY;
+    } else {
+        osflags = O_RDONLY;
+    }
+
+    if (flags & PR_EXCL)
+        osflags |= O_EXCL;
+    if (flags & PR_APPEND)
+        osflags |= O_APPEND;
+    if (flags & PR_TRUNCATE)
+        osflags |= O_TRUNC;
+    if (flags & PR_SYNC) {
+#if defined(O_SYNC)
+        osflags |= O_SYNC;
+#elif defined(O_FSYNC)
+        osflags |= O_FSYNC;
+#else
+#error "Neither O_SYNC nor O_FSYNC is defined on this platform"
+#endif
+    }
+
+    /*
+    ** On creations we hold the 'create' lock in order to enforce
+    ** the semantics of PR_Rename. (see the latter for more details)
+    */
+    if (flags & PR_CREATE_FILE)
+    {
+        osflags |= O_CREAT;
+        if (NULL !=_pr_rename_lock)
+            PR_Lock(_pr_rename_lock);
+    }
+
+    rv = _md_iovector._open64(name, osflags, mode);
+
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_OPEN_ERROR(err);
+    }
+
+    if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
+        PR_Unlock(_pr_rename_lock);
+    return rv;
+}
+
+PRIntervalTime intr_timeout_ticks;
+
+#if defined(SOLARIS) || defined(IRIX)
+static void sigsegvhandler() {
+    fprintf(stderr,"Received SIGSEGV\n");
+    fflush(stderr);
+    pause();
+}
+
+static void sigaborthandler() {
+    fprintf(stderr,"Received SIGABRT\n");
+    fflush(stderr);
+    pause();
+}
+
+static void sigbushandler() {
+    fprintf(stderr,"Received SIGBUS\n");
+    fflush(stderr);
+    pause();
+}
+#endif /* SOLARIS, IRIX */
+
+#endif  /* !defined(_PR_PTHREADS) */
+
+void _MD_query_fd_inheritable(PRFileDesc *fd)
+{
+    int flags;
+
+    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+    flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
+    PR_ASSERT(-1 != flags);
+    fd->secret->inheritable = (flags & FD_CLOEXEC) ?
+        _PR_TRI_FALSE : _PR_TRI_TRUE;
+}
+
+PROffset32 _MD_lseek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
+{
+    PROffset32 rv, where;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            where = SEEK_SET;
+            break;
+        case PR_SEEK_CUR:
+            where = SEEK_CUR;
+            break;
+        case PR_SEEK_END:
+            where = SEEK_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = -1;
+            goto done;
+    }
+    rv = lseek(fd->secret->md.osfd,offset,where);
+    if (rv == -1)
+    {
+        PRInt32 syserr = _MD_ERRNO();
+        _PR_MD_MAP_LSEEK_ERROR(syserr);
+    }
+done:
+    return(rv);
+}
+
+PROffset64 _MD_lseek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
+{
+    PRInt32 where;
+    PROffset64 rv;
+
+    switch (whence)
+    {
+        case PR_SEEK_SET:
+            where = SEEK_SET;
+            break;
+        case PR_SEEK_CUR:
+            where = SEEK_CUR;
+            break;
+        case PR_SEEK_END:
+            where = SEEK_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = minus_one;
+            goto done;
+    }
+    rv = _md_iovector._lseek64(fd->secret->md.osfd, offset, where);
+    if (LL_EQ(rv, minus_one))
+    {
+        PRInt32 syserr = _MD_ERRNO();
+        _PR_MD_MAP_LSEEK_ERROR(syserr);
+    }
+done:
+    return rv;
+}  /* _MD_lseek64 */
+
+/*
+** _MD_set_fileinfo_times --
+**     Set the modifyTime and creationTime of the PRFileInfo
+**     structure using the values in struct stat.
+**
+** _MD_set_fileinfo64_times --
+**     Set the modifyTime and creationTime of the PRFileInfo64
+**     structure using the values in _MDStat64.
+*/
+
+#if defined(_PR_STAT_HAS_ST_ATIM)
+/*
+** struct stat has st_atim, st_mtim, and st_ctim fields of
+** type timestruc_t.
+*/
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtim.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtim.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctim.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctim.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtim.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtim.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctim.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctim.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+#elif defined(_PR_STAT_HAS_ST_ATIM_UNION)
+/*
+** The st_atim, st_mtim, and st_ctim fields in struct stat are
+** unions with a st__tim union member of type timestruc_t.
+*/
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtim.st__tim.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtim.st__tim.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctim.st__tim.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctim.st__tim.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtim.st__tim.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtim.st__tim.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctim.st__tim.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctim.st__tim.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+#elif defined(_PR_STAT_HAS_ST_ATIMESPEC)
+/*
+** struct stat has st_atimespec, st_mtimespec, and st_ctimespec
+** fields of type struct timespec.
+*/
+#if defined(_PR_TIMESPEC_HAS_TS_SEC)
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtimespec.ts_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtimespec.ts_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctimespec.ts_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctimespec.ts_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtimespec.ts_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtimespec.ts_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctimespec.ts_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctimespec.ts_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+#else /* _PR_TIMESPEC_HAS_TS_SEC */
+/*
+** The POSIX timespec structure has tv_sec and tv_nsec.
+*/
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtimespec.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtimespec.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctimespec.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctimespec.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtimespec.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtimespec.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctimespec.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctimespec.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+#endif /* _PR_TIMESPEC_HAS_TS_SEC */
+#elif defined(_PR_STAT_HAS_ONLY_ST_ATIME)
+/*
+** struct stat only has st_atime, st_mtime, and st_ctime fields
+** of type time_t.
+*/
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 s, s2us;
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, sb->st_mtime);
+    LL_MUL(s, s, s2us);
+    info->modifyTime = s;
+    LL_I2L(s, sb->st_ctime);
+    LL_MUL(s, s, s2us);
+    info->creationTime = s;
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 s, s2us;
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, sb->st_mtime);
+    LL_MUL(s, s, s2us);
+    info->modifyTime = s;
+    LL_I2L(s, sb->st_ctime);
+    LL_MUL(s, s, s2us);
+    info->creationTime = s;
+}
+#else
+#error "I don't know yet"
+#endif
+
+static int _MD_convert_stat_to_fileinfo(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    if (S_IFREG & sb->st_mode)
+        info->type = PR_FILE_FILE;
+    else if (S_IFDIR & sb->st_mode)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_OTHER;
+
+#if defined(_PR_HAVE_LARGE_OFF_T)
+    if (0x7fffffffL < sb->st_size)
+    {
+        PR_SetError(PR_FILE_TOO_BIG_ERROR, 0);
+        return -1;
+    }
+#endif /* defined(_PR_HAVE_LARGE_OFF_T) */
+    info->size = sb->st_size;
+
+    _MD_set_fileinfo_times(sb, info);
+    return 0;
+}  /* _MD_convert_stat_to_fileinfo */
+
+static int _MD_convert_stat64_to_fileinfo64(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    if (S_IFREG & sb->st_mode)
+        info->type = PR_FILE_FILE;
+    else if (S_IFDIR & sb->st_mode)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_OTHER;
+
+    LL_I2L(info->size, sb->st_size);
+
+    _MD_set_fileinfo64_times(sb, info);
+    return 0;
+}  /* _MD_convert_stat64_to_fileinfo64 */
+
+PRInt32 _MD_getfileinfo(const char *fn, PRFileInfo *info)
+{
+    PRInt32 rv;
+    struct stat sb;
+
+    rv = stat(fn, &sb);
+    if (rv < 0)
+        _PR_MD_MAP_STAT_ERROR(_MD_ERRNO());
+    else if (NULL != info)
+        rv = _MD_convert_stat_to_fileinfo(&sb, info);
+    return rv;
+}
+
+PRInt32 _MD_getfileinfo64(const char *fn, PRFileInfo64 *info)
+{
+    _MDStat64 sb;
+    PRInt32 rv = _md_iovector._stat64(fn, &sb);
+    if (rv < 0)
+        _PR_MD_MAP_STAT_ERROR(_MD_ERRNO());
+    else if (NULL != info)
+        rv = _MD_convert_stat64_to_fileinfo64(&sb, info);
+    return rv;
+}
+
+PRInt32 _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info)
+{
+    struct stat sb;
+    PRInt32 rv = fstat(fd->secret->md.osfd, &sb);
+    if (rv < 0)
+        _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO());
+    else if (NULL != info)
+        rv = _MD_convert_stat_to_fileinfo(&sb, info);
+    return rv;
+}
+
+PRInt32 _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    _MDStat64 sb;
+    PRInt32 rv = _md_iovector._fstat64(fd->secret->md.osfd, &sb);
+    if (rv < 0)
+        _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO());
+    else if (NULL != info)
+        rv = _MD_convert_stat64_to_fileinfo64(&sb, info);
+    return rv;
+}
+
+/*
+ * _md_iovector._open64 must be initialized to 'open' so that _PR_InitLog can
+ * open the log file during NSPR initialization, before _md_iovector is
+ * initialized by _PR_MD_FINAL_INIT.  This means the log file cannot be a
+ * large file on some platforms.
+ */
+#ifdef SYMBIAN
+struct _MD_IOVector _md_iovector; /* Will crash if NSPR_LOG_FILE is set. */
+#else
+struct _MD_IOVector _md_iovector = { open };
+#endif
+
+/*
+** These implementations are to emulate large file routines on systems that
+** don't have them. Their goal is to check in case overflow occurs. Otherwise
+** they will just operate as normal using 32-bit file routines.
+**
+** The checking might be pre- or post-op, depending on the semantics.
+*/
+
+#if defined(SOLARIS2_5)
+
+static PRIntn _MD_solaris25_fstat64(PRIntn osfd, _MDStat64 *buf)
+{
+    PRInt32 rv;
+    struct stat sb;
+
+    rv = fstat(osfd, &sb);
+    if (rv >= 0)
+    {
+        /*
+        ** I'm only copying the fields that are immediately needed.
+        ** If somebody else calls this function, some of the fields
+        ** may not be defined.
+        */
+        (void)memset(buf, 0, sizeof(_MDStat64));
+        buf->st_mode = sb.st_mode;
+        buf->st_ctim = sb.st_ctim;
+        buf->st_mtim = sb.st_mtim;
+        buf->st_size = sb.st_size;
+    }
+    return rv;
+}  /* _MD_solaris25_fstat64 */
+
+static PRIntn _MD_solaris25_stat64(const char *fn, _MDStat64 *buf)
+{
+    PRInt32 rv;
+    struct stat sb;
+
+    rv = stat(fn, &sb);
+    if (rv >= 0)
+    {
+        /*
+        ** I'm only copying the fields that are immediately needed.
+        ** If somebody else calls this function, some of the fields
+        ** may not be defined.
+        */
+        (void)memset(buf, 0, sizeof(_MDStat64));
+        buf->st_mode = sb.st_mode;
+        buf->st_ctim = sb.st_ctim;
+        buf->st_mtim = sb.st_mtim;
+        buf->st_size = sb.st_size;
+    }
+    return rv;
+}  /* _MD_solaris25_stat64 */
+#endif /* defined(SOLARIS2_5) */
+
+#if defined(_PR_NO_LARGE_FILES) || defined(SOLARIS2_5)
+
+static PROffset64 _MD_Unix_lseek64(PRIntn osfd, PROffset64 offset, PRIntn whence)
+{
+    PRUint64 maxoff;
+    PROffset64 rv = minus_one;
+    LL_I2L(maxoff, 0x7fffffff);
+    if (LL_CMP(offset, <=, maxoff))
+    {
+        off_t off;
+        LL_L2I(off, offset);
+        LL_I2L(rv, lseek(osfd, off, whence));
+    }
+    else errno = EFBIG;  /* we can't go there */
+    return rv;
+}  /* _MD_Unix_lseek64 */
+
+static void* _MD_Unix_mmap64(
+    void *addr, PRSize len, PRIntn prot, PRIntn flags,
+    PRIntn fildes, PRInt64 offset)
+{
+    PR_SetError(PR_FILE_TOO_BIG_ERROR, 0);
+    return NULL;
+}  /* _MD_Unix_mmap64 */
+#endif /* defined(_PR_NO_LARGE_FILES) || defined(SOLARIS2_5) */
+
+#if defined(OSF1) && defined(__GNUC__)
+
+/*
+ * On OSF1 V5.0A, <sys/stat.h> defines stat and fstat as
+ * macros when compiled under gcc, so it is rather tricky to
+ * take the addresses of the real functions the macros expend
+ * to.  A simple solution is to define forwarder functions
+ * and take the addresses of the forwarder functions instead.
+ */
+
+static int stat_forwarder(const char *path, struct stat *buffer)
+{
+    return stat(path, buffer);
+}
+
+static int fstat_forwarder(int filedes, struct stat *buffer)
+{
+    return fstat(filedes, buffer);
+}
+
+#endif
+
+static void _PR_InitIOV(void)
+{
+#if defined(SOLARIS2_5)
+    PRLibrary *lib;
+    void *open64_func;
+
+    open64_func = PR_FindSymbolAndLibrary("open64", &lib);
+    if (NULL != open64_func)
+    {
+        PR_ASSERT(NULL != lib);
+        _md_iovector._open64 = (_MD_Open64)open64_func;
+        _md_iovector._mmap64 = (_MD_Mmap64)PR_FindSymbol(lib, "mmap64");
+        _md_iovector._fstat64 = (_MD_Fstat64)PR_FindSymbol(lib, "fstat64");
+        _md_iovector._stat64 = (_MD_Stat64)PR_FindSymbol(lib, "stat64");
+        _md_iovector._lseek64 = (_MD_Lseek64)PR_FindSymbol(lib, "lseek64");
+        (void)PR_UnloadLibrary(lib);
+    }
+    else
+    {
+        _md_iovector._open64 = open;
+        _md_iovector._mmap64 = _MD_Unix_mmap64;
+        _md_iovector._fstat64 = _MD_solaris25_fstat64;
+        _md_iovector._stat64 = _MD_solaris25_stat64;
+        _md_iovector._lseek64 = _MD_Unix_lseek64;
+    }
+#elif defined(_PR_NO_LARGE_FILES)
+    _md_iovector._open64 = open;
+    _md_iovector._mmap64 = _MD_Unix_mmap64;
+    _md_iovector._fstat64 = fstat;
+    _md_iovector._stat64 = stat;
+    _md_iovector._lseek64 = _MD_Unix_lseek64;
+#elif defined(_PR_HAVE_OFF64_T)
+#if defined(IRIX5_3)
+    _md_iovector._open64 = open;
+#else
+    _md_iovector._open64 = open64;
+#endif
+    _md_iovector._mmap64 = mmap64;
+    _md_iovector._fstat64 = fstat64;
+    _md_iovector._stat64 = stat64;
+    _md_iovector._lseek64 = lseek64;
+#elif defined(_PR_HAVE_LARGE_OFF_T)
+    _md_iovector._open64 = open;
+    _md_iovector._mmap64 = mmap;
+#if defined(OSF1) && defined(__GNUC__)
+    _md_iovector._fstat64 = fstat_forwarder;
+    _md_iovector._stat64 = stat_forwarder;
+#else
+    _md_iovector._fstat64 = fstat;
+    _md_iovector._stat64 = stat;
+#endif
+    _md_iovector._lseek64 = lseek;
+#else
+#error "I don't know yet"
+#endif
+    LL_I2L(minus_one, -1);
+}  /* _PR_InitIOV */
+
+void _PR_UnixInit(void)
+{
+    struct sigaction sigact;
+    int rv;
+
+    sigemptyset(&timer_set);
+
+#if !defined(_PR_PTHREADS)
+
+    sigaddset(&timer_set, SIGALRM);
+    sigemptyset(&empty_set);
+    intr_timeout_ticks =
+            PR_SecondsToInterval(_PR_INTERRUPT_CHECK_INTERVAL_SECS);
+
+#if defined(SOLARIS) || defined(IRIX)
+
+    if (getenv("NSPR_SIGSEGV_HANDLE")) {
+        sigact.sa_handler = sigsegvhandler;
+        sigact.sa_flags = 0;
+        sigact.sa_mask = timer_set;
+        sigaction(SIGSEGV, &sigact, 0);
+    }
+
+    if (getenv("NSPR_SIGABRT_HANDLE")) {
+        sigact.sa_handler = sigaborthandler;
+        sigact.sa_flags = 0;
+        sigact.sa_mask = timer_set;
+        sigaction(SIGABRT, &sigact, 0);
+    }
+
+    if (getenv("NSPR_SIGBUS_HANDLE")) {
+        sigact.sa_handler = sigbushandler;
+        sigact.sa_flags = 0;
+        sigact.sa_mask = timer_set;
+        sigaction(SIGBUS, &sigact, 0);
+    }
+
+#endif
+#endif  /* !defined(_PR_PTHREADS) */
+
+    /*
+     * Under HP-UX DCE threads, sigaction() installs a per-thread
+     * handler, so we use sigvector() to install a process-wide
+     * handler.
+     */
+#if defined(HPUX) && defined(_PR_DCETHREADS)
+    {
+        struct sigvec vec;
+
+        vec.sv_handler = SIG_IGN;
+        vec.sv_mask = 0;
+        vec.sv_flags = 0;
+        rv = sigvector(SIGPIPE, &vec, NULL);
+        PR_ASSERT(0 == rv);
+    }
+#else
+    sigact.sa_handler = SIG_IGN;
+    sigemptyset(&sigact.sa_mask);
+    sigact.sa_flags = 0;
+    rv = sigaction(SIGPIPE, &sigact, 0);
+    PR_ASSERT(0 == rv);
+#endif /* HPUX && _PR_DCETHREADS */
+
+    _pr_rename_lock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_rename_lock);
+    _pr_Xfe_mon = PR_NewMonitor();
+    PR_ASSERT(NULL != _pr_Xfe_mon);
+
+    _PR_InitIOV();  /* one last hack */
+}
+
+void _PR_UnixCleanup(void)
+{
+    if (_pr_rename_lock) {
+        PR_DestroyLock(_pr_rename_lock);
+        _pr_rename_lock = NULL;
+    }
+    if (_pr_Xfe_mon) {
+        PR_DestroyMonitor(_pr_Xfe_mon);
+        _pr_Xfe_mon = NULL;
+    }
+}
+
+#if !defined(_PR_PTHREADS)
+
+/*
+ * Variables used by the GC code, initialized in _MD_InitSegs().
+ */
+static PRInt32 _pr_zero_fd = -1;
+static PRLock *_pr_md_lock = NULL;
+
+/*
+ * _MD_InitSegs --
+ *
+ * This is Unix's version of _PR_MD_INIT_SEGS(), which is
+ * called by _PR_InitSegs(), which in turn is called by
+ * PR_Init().
+ */
+void _MD_InitSegs(void)
+{
+#ifdef DEBUG
+    /*
+    ** Disable using mmap(2) if NSPR_NO_MMAP is set
+    */
+    if (getenv("NSPR_NO_MMAP")) {
+        _pr_zero_fd = -2;
+        return;
+    }
+#endif
+    _pr_zero_fd = open("/dev/zero",O_RDWR , 0);
+    /* Prevent the fd from being inherited by child processes */
+    fcntl(_pr_zero_fd, F_SETFD, FD_CLOEXEC);
+    _pr_md_lock = PR_NewLock();
+}
+
+PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr)
+{
+    static char *lastaddr = (char*) _PR_STACK_VMBASE;
+    PRStatus retval = PR_SUCCESS;
+    int prot;
+    void *rv;
+
+    PR_ASSERT(seg != 0);
+    PR_ASSERT(size != 0);
+
+    PR_Lock(_pr_md_lock);
+    if (_pr_zero_fd < 0) {
+from_heap:
+        seg->vaddr = PR_MALLOC(size);
+        if (!seg->vaddr) {
+            retval = PR_FAILURE;
+        }
+        else {
+            seg->size = size;
+        }
+        goto exit;
+    }
+
+    prot = PROT_READ|PROT_WRITE;
+    /*
+     * On Alpha Linux, the user-level thread stack needs
+     * to be made executable because longjmp/signal seem
+     * to put machine instructions on the stack.
+     */
+#if defined(LINUX) && defined(__alpha)
+    prot |= PROT_EXEC;
+#endif
+    rv = mmap((vaddr != 0) ? vaddr : lastaddr, size, prot,
+        _MD_MMAP_FLAGS,
+        _pr_zero_fd, 0);
+    if (rv == (void*)-1) {
+        goto from_heap;
+    }
+    lastaddr += size;
+    seg->vaddr = rv;
+    seg->size = size;
+    seg->flags = _PR_SEG_VM;
+
+exit:
+    PR_Unlock(_pr_md_lock);
+    return retval;
+}
+
+void _MD_FreeSegment(PRSegment *seg)
+{
+    if (seg->flags & _PR_SEG_VM)
+        (void) munmap(seg->vaddr, seg->size);
+    else
+        PR_DELETE(seg->vaddr);
+}
+
+#endif /* _PR_PTHREADS */
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the Unix
+ *     implementation.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+    struct timeval tv;
+    PRInt64 s, us, s2us;
+
+    GETTIMEOFDAY(&tv);
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, tv.tv_sec);
+    LL_I2L(us, tv.tv_usec);
+    LL_MUL(s, s, s2us);
+    LL_ADD(s, s, us);
+    return s;
+}
+
+PRIntervalTime _PR_UNIX_GetInterval()
+{
+#if defined(XP_MACOSX)
+    struct timeval time;
+    PRIntervalTime ticks;
+
+    (void)GETTIMEOFDAY(&time);  /* fallicy of course */
+    ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
+    ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
+#else
+    struct timespec time;
+    PRIntervalTime ticks;
+
+    (void)clock_gettime(CLOCK_MONOTONIC, &time);
+    ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
+    ticks += (PRUint32)((PRUint64)time.tv_nsec / PR_NSEC_PER_MSEC);  /* so's that */
+#endif
+    return ticks;
+}  /* _PR_SUNOS_GetInterval */
+
+PRIntervalTime _PR_UNIX_TicksPerSecond()
+{
+    return 1000;  /* this needs some work :) */
+}
+
+#if !defined(_PR_PTHREADS)
+/*
+ * Wait for I/O on multiple descriptors.
+ *
+ * Return 0 if timed out, return -1 if interrupted,
+ * else return the number of ready descriptors.
+ */
+PRInt32 _PR_WaitForMultipleFDs(
+    _PRUnixPollDesc *unixpds,
+    PRInt32 pdcnt,
+    PRIntervalTime timeout)
+{
+    PRPollQueue pq;
+    PRIntn is;
+    PRInt32 rv;
+    _PRCPU *io_cpu;
+    _PRUnixPollDesc *unixpd, *eunixpd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        return -1;
+    }
+
+    pq.pds = unixpds;
+    pq.npds = pdcnt;
+
+    _PR_INTSOFF(is);
+    _PR_MD_IOQ_LOCK();
+    _PR_THREAD_LOCK(me);
+
+    pq.thr = me;
+    io_cpu = me->cpu;
+    pq.on_ioq = PR_TRUE;
+    pq.timeout = timeout;
+    _PR_ADD_TO_IOQ(pq, me->cpu);
+
+#if !defined(_PR_USE_POLL)
+    eunixpd = unixpds + pdcnt;
+    for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
+        PRInt32 osfd = unixpd->osfd;
+        if (unixpd->in_flags & _PR_UNIX_POLL_READ) {
+            FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
+            _PR_FD_READ_CNT(me->cpu)[osfd]++;
+        }
+        if (unixpd->in_flags & _PR_UNIX_POLL_WRITE) {
+            FD_SET(osfd, &_PR_FD_WRITE_SET(me->cpu));
+            (_PR_FD_WRITE_CNT(me->cpu))[osfd]++;
+        }
+        if (unixpd->in_flags & _PR_UNIX_POLL_EXCEPT) {
+            FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+            (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
+        }
+        if (osfd > _PR_IOQ_MAX_OSFD(me->cpu)) {
+            _PR_IOQ_MAX_OSFD(me->cpu) = osfd;
+        }
+    }
+#endif  /* !defined(_PR_USE_POLL) */
+
+    if (_PR_IOQ_TIMEOUT(me->cpu) > timeout) {
+        _PR_IOQ_TIMEOUT(me->cpu) = timeout;
+    }
+
+    _PR_IOQ_OSFD_CNT(me->cpu) += pdcnt;
+        
+    _PR_SLEEPQ_LOCK(me->cpu);
+    _PR_ADD_SLEEPQ(me, timeout);
+    me->state = _PR_IO_WAIT;
+    me->io_pending = PR_TRUE;
+    me->io_suspended = PR_FALSE;
+    _PR_SLEEPQ_UNLOCK(me->cpu);
+    _PR_THREAD_UNLOCK(me);
+    _PR_MD_IOQ_UNLOCK();
+
+    _PR_MD_WAIT(me, timeout);
+
+    me->io_pending = PR_FALSE;
+    me->io_suspended = PR_FALSE;
+
+    /*
+     * This thread should run on the same cpu on which it was blocked; when 
+     * the IO request times out the fd sets and fd counts for the
+     * cpu are updated below.
+     */
+    PR_ASSERT(me->cpu == io_cpu);
+
+    /*
+    ** If we timed out the pollq might still be on the ioq. Remove it
+    ** before continuing.
+    */
+    if (pq.on_ioq) {
+        _PR_MD_IOQ_LOCK();
+        /*
+         * Need to check pq.on_ioq again
+         */
+        if (pq.on_ioq) {
+            PR_REMOVE_LINK(&pq.links);
+#ifndef _PR_USE_POLL
+            eunixpd = unixpds + pdcnt;
+            for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
+                PRInt32 osfd = unixpd->osfd;
+                PRInt16 in_flags = unixpd->in_flags;
+
+                if (in_flags & _PR_UNIX_POLL_READ) {
+                    if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                }
+                if (in_flags & _PR_UNIX_POLL_WRITE) {
+                    if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                }
+                if (in_flags & _PR_UNIX_POLL_EXCEPT) {
+                    if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                }
+            }
+#endif  /* _PR_USE_POLL */
+            PR_ASSERT(pq.npds == pdcnt);
+            _PR_IOQ_OSFD_CNT(me->cpu) -= pdcnt;
+            PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
+        }
+        _PR_MD_IOQ_UNLOCK();
+    }
+    /* XXX Should we use _PR_FAST_INTSON or _PR_INTSON? */
+    if (1 == pdcnt) {
+        _PR_FAST_INTSON(is);
+    } else {
+        _PR_INTSON(is);
+    }
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        return -1;
+    }
+
+    rv = 0;
+    if (pq.on_ioq == PR_FALSE) {
+        /* Count the number of ready descriptors */
+        while (--pdcnt >= 0) {
+            if (unixpds->out_flags != 0) {
+                rv++;
+            }
+            unixpds++;
+        }
+    }
+
+    return rv;
+}
+
+/*
+ * Unblock threads waiting for I/O
+ *    used when interrupting threads
+ *
+ * NOTE: The thread lock should held when this function is called.
+ * On return, the thread lock is released.
+ */
+void _PR_Unblock_IO_Wait(PRThread *thr)
+{
+    int pri = thr->priority;
+    _PRCPU *cpu = thr->cpu;
+ 
+    /*
+     * GLOBAL threads wakeup periodically to check for interrupt
+     */
+    if (_PR_IS_NATIVE_THREAD(thr)) {
+        _PR_THREAD_UNLOCK(thr); 
+        return;
+    }
+
+    PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ));
+    _PR_SLEEPQ_LOCK(cpu);
+    _PR_DEL_SLEEPQ(thr, PR_TRUE);
+    _PR_SLEEPQ_UNLOCK(cpu);
+
+    PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD));
+    thr->state = _PR_RUNNABLE;
+    _PR_RUNQ_LOCK(cpu);
+    _PR_ADD_RUNQ(thr, cpu, pri);
+    _PR_RUNQ_UNLOCK(cpu);
+    _PR_THREAD_UNLOCK(thr);
+    _PR_MD_WAKEUP_WAITER(thr);
+}
+#endif  /* !defined(_PR_PTHREADS) */
+
+/*
+ * When a nonblocking connect has completed, determine whether it
+ * succeeded or failed, and if it failed, what the error code is.
+ *
+ * The function returns the error code.  An error code of 0 means
+ * that the nonblocking connect succeeded.
+ */
+
+int _MD_unix_get_nonblocking_connect_error(int osfd)
+{
+#if defined(NTO)
+    /* Neutrino does not support the SO_ERROR socket option */
+    PRInt32      rv;
+    PRNetAddr    addr;
+    _PRSockLen_t addrlen = sizeof(addr);
+
+    /* Test to see if we are using the Tiny TCP/IP Stack or the Full one. */
+    struct statvfs superblock;
+    rv = fstatvfs(osfd, &superblock);
+    if (rv == 0) {
+        if (strcmp(superblock.f_basetype, "ttcpip") == 0) {
+            /* Using the Tiny Stack! */
+            rv = getpeername(osfd, (struct sockaddr *) &addr,
+                    (_PRSockLen_t *) &addrlen);
+            if (rv == -1) {
+                int errno_copy = errno;    /* make a copy so I don't
+                                            * accidentally reset */
+
+                if (errno_copy == ENOTCONN) {
+                    struct stat StatInfo;
+                    rv = fstat(osfd, &StatInfo);
+                    if (rv == 0) {
+                        time_t current_time = time(NULL);
+
+                        /*
+                         * this is a real hack, can't explain why it
+                         * works it just does
+                         */
+                        if (abs(current_time - StatInfo.st_atime) < 5) {
+                            return ECONNREFUSED;
+                        } else {
+                            return ETIMEDOUT;
+                        }
+                    } else {
+                        return ECONNREFUSED;
+                    }
+                } else {
+                    return errno_copy;
+                }
+            } else {
+                /* No Error */
+                return 0;
+            }
+        } else {
+            /* Have the FULL Stack which supports SO_ERROR */
+            /* Hasn't been written yet, never been tested! */
+            /* Jerry.Kirk@Nexwarecorp.com */
+
+            int err;
+            _PRSockLen_t optlen = sizeof(err);
+
+            if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
+                    (char *) &err, &optlen) == -1) {
+                return errno;
+            } else {
+                return err;
+            }		
+        }
+    } else {
+        return ECONNREFUSED;
+    }	
+#elif defined(NCR) || defined(UNIXWARE) || defined(SNI) || defined(NEC)
+    /*
+     * getsockopt() fails with EPIPE, so use getmsg() instead.
+     */
+
+    int rv;
+    int flags = 0;
+    rv = getmsg(osfd, NULL, NULL, &flags);
+    PR_ASSERT(-1 == rv || 0 == rv);
+    if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) {
+        return errno;
+    }
+    return 0;  /* no error */
+#else
+    int err;
+    _PRSockLen_t optlen = sizeof(err);
+    if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) {
+        return errno;
+    } else {
+        return err;
+    }
+#endif
+}
+
+/************************************************************************/
+
+/*
+** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread
+** safe.  Unfortunately, neither is mozilla. To make these programs work
+** in a pre-emptive threaded environment, we need to use a lock.
+*/
+
+void PR_XLock(void)
+{
+    PR_EnterMonitor(_pr_Xfe_mon);
+}
+
+void PR_XUnlock(void)
+{
+    PR_ExitMonitor(_pr_Xfe_mon);
+}
+
+PRBool PR_XIsLocked(void)
+{
+    return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE;
+}
+
+void PR_XWait(int ms)
+{
+    PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms));
+}
+
+void PR_XNotify(void)
+{
+    PR_Notify(_pr_Xfe_mon);
+}
+
+void PR_XNotifyAll(void)
+{
+    PR_NotifyAll(_pr_Xfe_mon);
+}
+
+#if defined(HAVE_FCNTL_FILE_LOCKING)
+
+PRStatus
+_MD_LockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_WRLCK;
+    arg.l_whence = SEEK_SET;
+    arg.l_start = 0;
+    arg.l_len = 0;  /* until EOF */
+    rv = fcntl(f, F_SETLKW, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_TLockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_WRLCK;
+    arg.l_whence = SEEK_SET;
+    arg.l_start = 0;
+    arg.l_len = 0;  /* until EOF */
+    rv = fcntl(f, F_SETLK, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_UnlockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_UNLCK;
+    arg.l_whence = SEEK_SET;
+    arg.l_start = 0;
+    arg.l_len = 0;  /* until EOF */
+    rv = fcntl(f, F_SETLK, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+#elif defined(HAVE_BSD_FLOCK)
+
+#include <sys/file.h>
+
+PRStatus
+_MD_LockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = flock(f, LOCK_EX);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_TLockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = flock(f, LOCK_EX|LOCK_NB);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_UnlockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = flock(f, LOCK_UN);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+#else
+
+PRStatus
+_MD_LockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = lockf(f, F_LOCK, 0);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_TLockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = lockf(f, F_TLOCK, 0);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_UnlockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = lockf(f, F_ULOCK, 0);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+#endif
+
+PRStatus _MD_gethostname(char *name, PRUint32 namelen)
+{
+    PRIntn rv;
+
+    rv = gethostname(name, namelen);
+    if (0 == rv) {
+        return PR_SUCCESS;
+    }
+    _PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen)
+{
+	struct utsname info;
+
+	PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE));
+
+	if (uname(&info) == -1) {
+		_PR_MD_MAP_DEFAULT_ERROR(errno);
+    	return PR_FAILURE;
+	}
+	if (PR_SI_SYSNAME == cmd)
+		(void)PR_snprintf(name, namelen, info.sysname);
+	else if (PR_SI_RELEASE == cmd)
+		(void)PR_snprintf(name, namelen, info.release);
+	else
+		return PR_FAILURE;
+    return PR_SUCCESS;
+}
+
+/*
+ *******************************************************************
+ *
+ * Memory-mapped files
+ *
+ *******************************************************************
+ */
+
+PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
+{
+    PRFileInfo info;
+    PRUint32 sz;
+
+    LL_L2UI(sz, size);
+    if (sz) {
+        if (PR_GetOpenFileInfo(fmap->fd, &info) == PR_FAILURE) {
+            return PR_FAILURE;
+        }
+        if (sz > info.size) {
+            /*
+             * Need to extend the file
+             */
+            if (fmap->prot != PR_PROT_READWRITE) {
+                PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
+                return PR_FAILURE;
+            }
+            if (PR_Seek(fmap->fd, sz - 1, PR_SEEK_SET) == -1) {
+                return PR_FAILURE;
+            }
+            if (PR_Write(fmap->fd, "", 1) != 1) {
+                return PR_FAILURE;
+            }
+        }
+    }
+    if (fmap->prot == PR_PROT_READONLY) {
+        fmap->md.prot = PROT_READ;
+#ifdef OSF1V4_MAP_PRIVATE_BUG
+        /*
+         * Use MAP_SHARED to work around a bug in OSF1 V4.0D
+         * (QAR 70220 in the OSF_QAR database) that results in
+         * corrupted data in the memory-mapped region.  This
+         * bug is fixed in V5.0.
+         */
+        fmap->md.flags = MAP_SHARED;
+#else
+        fmap->md.flags = MAP_PRIVATE;
+#endif
+    } else if (fmap->prot == PR_PROT_READWRITE) {
+        fmap->md.prot = PROT_READ | PROT_WRITE;
+        fmap->md.flags = MAP_SHARED;
+    } else {
+        PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY);
+        fmap->md.prot = PROT_READ | PROT_WRITE;
+        fmap->md.flags = MAP_PRIVATE;
+    }
+    return PR_SUCCESS;
+}
+
+void * _MD_MemMap(
+    PRFileMap *fmap,
+    PRInt64 offset,
+    PRUint32 len)
+{
+    PRInt32 off;
+    void *addr;
+
+    LL_L2I(off, offset);
+    if ((addr = mmap(0, len, fmap->md.prot, fmap->md.flags,
+        fmap->fd->secret->md.osfd, off)) == (void *) -1) {
+            _PR_MD_MAP_MMAP_ERROR(_MD_ERRNO());
+        addr = NULL;
+    }
+    return addr;
+}
+
+PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
+{
+    if (munmap(addr, len) == 0) {
+        return PR_SUCCESS;
+    } else {
+    if (errno == EINVAL) {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, errno);
+    } else {
+        PR_SetError(PR_UNKNOWN_ERROR, errno);
+    }
+        return PR_FAILURE;
+    }
+}
+
+PRStatus _MD_CloseFileMap(PRFileMap *fmap)
+{
+    if ( PR_TRUE == fmap->md.isAnonFM ) {
+        PRStatus rc = PR_Close( fmap->fd );
+        if ( PR_FAILURE == rc ) {
+            PR_LOG( _pr_io_lm, PR_LOG_DEBUG,
+                ("_MD_CloseFileMap(): error closing anonymnous file map osfd"));
+            return PR_FAILURE;
+        }
+    }
+    PR_DELETE(fmap);
+    return PR_SUCCESS;
+}
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+/*
+ * Some platforms don't have poll().  For easier porting of code
+ * that calls poll(), we emulate poll() using select().
+ */
+
+int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
+{
+    int i;
+    int rv;
+    int maxfd;
+    fd_set rd, wr, ex;
+    struct timeval tv, *tvp;
+
+    if (timeout < 0 && timeout != -1) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (timeout == -1) {
+        tvp = NULL;
+    } else {
+        tv.tv_sec = timeout / 1000;
+        tv.tv_usec = (timeout % 1000) * 1000;
+        tvp = &tv;
+    }
+
+    maxfd = -1;
+    FD_ZERO(&rd);
+    FD_ZERO(&wr);
+    FD_ZERO(&ex);
+
+    for (i = 0; i < nfds; i++) {
+        int osfd = filedes[i].fd;
+        int events = filedes[i].events;
+        PRBool fdHasEvent = PR_FALSE;
+
+        if (osfd < 0) {
+            continue;  /* Skip this osfd. */
+        }
+
+        /*
+         * Map the poll events to the select fd_sets.
+         *     POLLIN, POLLRDNORM  ===> readable
+         *     POLLOUT, POLLWRNORM ===> writable
+         *     POLLPRI, POLLRDBAND ===> exception
+         *     POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
+         *     are ignored.
+         *
+         * The output events POLLERR and POLLHUP are never turned on.
+         * POLLNVAL may be turned on.
+         */
+
+        if (events & (POLLIN | POLLRDNORM)) {
+            FD_SET(osfd, &rd);
+            fdHasEvent = PR_TRUE;
+        }
+        if (events & (POLLOUT | POLLWRNORM)) {
+            FD_SET(osfd, &wr);
+            fdHasEvent = PR_TRUE;
+        }
+        if (events & (POLLPRI | POLLRDBAND)) {
+            FD_SET(osfd, &ex);
+            fdHasEvent = PR_TRUE;
+        }
+        if (fdHasEvent && osfd > maxfd) {
+            maxfd = osfd;
+        }
+    }
+
+    rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
+
+    /* Compute poll results */
+    if (rv > 0) {
+        rv = 0;
+        for (i = 0; i < nfds; i++) {
+            PRBool fdHasEvent = PR_FALSE;
+
+            filedes[i].revents = 0;
+            if (filedes[i].fd < 0) {
+                continue;
+            }
+            if (FD_ISSET(filedes[i].fd, &rd)) {
+                if (filedes[i].events & POLLIN) {
+                    filedes[i].revents |= POLLIN;
+                }
+                if (filedes[i].events & POLLRDNORM) {
+                    filedes[i].revents |= POLLRDNORM;
+                }
+                fdHasEvent = PR_TRUE;
+            }
+            if (FD_ISSET(filedes[i].fd, &wr)) {
+                if (filedes[i].events & POLLOUT) {
+                    filedes[i].revents |= POLLOUT;
+                }
+                if (filedes[i].events & POLLWRNORM) {
+                    filedes[i].revents |= POLLWRNORM;
+                }
+                fdHasEvent = PR_TRUE;
+            }
+            if (FD_ISSET(filedes[i].fd, &ex)) {
+                if (filedes[i].events & POLLPRI) {
+                    filedes[i].revents |= POLLPRI;
+                }
+                if (filedes[i].events & POLLRDBAND) {
+                    filedes[i].revents |= POLLRDBAND;
+                }
+                fdHasEvent = PR_TRUE;
+            }
+            if (fdHasEvent) {
+                rv++;
+            }
+        }
+        PR_ASSERT(rv > 0);
+    } else if (rv == -1 && errno == EBADF) {
+        rv = 0;
+        for (i = 0; i < nfds; i++) {
+            filedes[i].revents = 0;
+            if (filedes[i].fd < 0) {
+                continue;
+            }
+            if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
+                filedes[i].revents = POLLNVAL;
+                rv++;
+            }
+        }
+        PR_ASSERT(rv > 0);
+    }
+    PR_ASSERT(-1 != timeout || rv != 0);
+
+    return rv;
+}
+#endif /* _PR_NEED_FAKE_POLL */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix_errors.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix_errors.c
new file mode 100644
index 0000000..a1b88dc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix_errors.c
@@ -0,0 +1,880 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#if defined(_PR_POLL_AVAILABLE)
+#include <poll.h>
+#endif
+#include <errno.h>
+
+void _MD_unix_map_default_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err ) {
+        case EACCES:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case EADDRINUSE:
+            prError = PR_ADDRESS_IN_USE_ERROR;
+            break;
+        case EADDRNOTAVAIL:
+            prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
+            break;
+        case EAFNOSUPPORT:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case EAGAIN:
+            prError = PR_WOULD_BLOCK_ERROR;
+            break;
+        /*
+         * On QNX and Neutrino, EALREADY is defined as EBUSY.
+         */
+#if EALREADY != EBUSY
+        case EALREADY:
+            prError = PR_ALREADY_INITIATED_ERROR;
+            break;
+#endif
+        case EBADF:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+#ifdef EBADMSG
+        case EBADMSG:
+            prError = PR_IO_ERROR;
+            break;
+#endif
+        case EBUSY:
+            prError = PR_FILESYSTEM_MOUNTED_ERROR;
+            break;
+        case ECONNABORTED:
+            prError = PR_CONNECT_ABORTED_ERROR;
+            break;
+        case ECONNREFUSED:
+            prError = PR_CONNECT_REFUSED_ERROR;
+            break;
+        case ECONNRESET:
+            prError = PR_CONNECT_RESET_ERROR;
+            break;
+        case EDEADLK:
+            prError = PR_DEADLOCK_ERROR;
+            break;
+#ifdef EDIRCORRUPTED
+        case EDIRCORRUPTED:
+            prError = PR_DIRECTORY_CORRUPTED_ERROR;
+            break;
+#endif
+#ifdef EDQUOT
+        case EDQUOT:
+            prError = PR_NO_DEVICE_SPACE_ERROR;
+            break;
+#endif
+        case EEXIST:
+            prError = PR_FILE_EXISTS_ERROR;
+            break;
+        case EFAULT:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case EFBIG:
+            prError = PR_FILE_TOO_BIG_ERROR;
+            break;
+        case EHOSTUNREACH:
+            prError = PR_HOST_UNREACHABLE_ERROR;
+            break;
+        case EINPROGRESS:
+            prError = PR_IN_PROGRESS_ERROR;
+            break;
+        case EINTR:
+            prError = PR_PENDING_INTERRUPT_ERROR;
+            break;
+        case EINVAL:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case EIO:
+            prError = PR_IO_ERROR;
+            break;
+        case EISCONN:
+            prError = PR_IS_CONNECTED_ERROR;
+            break;
+        case EISDIR:
+            prError = PR_IS_DIRECTORY_ERROR;
+            break;
+        case ELOOP:
+            prError = PR_LOOP_ERROR;
+            break;
+        case EMFILE:
+            prError = PR_PROC_DESC_TABLE_FULL_ERROR;
+            break;
+        case EMLINK:
+            prError = PR_MAX_DIRECTORY_ENTRIES_ERROR;
+            break;
+        case EMSGSIZE:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+#ifdef EMULTIHOP
+        case EMULTIHOP:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+#endif
+        case ENAMETOOLONG:
+            prError = PR_NAME_TOO_LONG_ERROR;
+            break;
+        case ENETUNREACH:
+            prError = PR_NETWORK_UNREACHABLE_ERROR;
+            break;
+        case ENFILE:
+            prError = PR_SYS_DESC_TABLE_FULL_ERROR;
+            break;
+        /*
+         * On SCO OpenServer 5, ENOBUFS is defined as ENOSR.
+         */
+#if defined(ENOBUFS) && (ENOBUFS != ENOSR)
+        case ENOBUFS:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+#endif
+        case ENODEV:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ENOENT:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ENOLCK:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+#ifdef ENOLINK 
+        case ENOLINK:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+#endif
+        case ENOMEM:
+            prError = PR_OUT_OF_MEMORY_ERROR;
+            break;
+        case ENOPROTOOPT:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case ENOSPC:
+            prError = PR_NO_DEVICE_SPACE_ERROR;
+            break;
+#ifdef ENOSR
+        case ENOSR:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+#endif
+        case ENOSYS:
+            prError = PR_NOT_IMPLEMENTED_ERROR;
+            break;
+        case ENOTCONN:
+            prError = PR_NOT_CONNECTED_ERROR;
+            break;
+        case ENOTDIR:
+            prError = PR_NOT_DIRECTORY_ERROR;
+            break;
+        case ENOTSOCK:
+            prError = PR_NOT_SOCKET_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case EOPNOTSUPP:
+            prError = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+#ifdef EOVERFLOW
+        case EOVERFLOW:
+            prError = PR_BUFFER_OVERFLOW_ERROR;
+            break;
+#endif
+        case EPERM:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case EPIPE:
+            prError = PR_CONNECT_RESET_ERROR;
+            break;
+#ifdef EPROTO
+        case EPROTO:
+            prError = PR_IO_ERROR;
+            break;
+#endif
+        case EPROTONOSUPPORT:
+            prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR;
+            break;
+        case EPROTOTYPE:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case ERANGE:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case EROFS:
+            prError = PR_READ_ONLY_FILESYSTEM_ERROR;
+            break;
+        case ESPIPE:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case ETIMEDOUT:
+            prError = PR_IO_TIMEOUT_ERROR;
+            break;
+#if EWOULDBLOCK != EAGAIN
+        case EWOULDBLOCK:
+            prError = PR_WOULD_BLOCK_ERROR;
+            break;
+#endif
+        case EXDEV:
+            prError = PR_NOT_SAME_DEVICE_ERROR;
+            break;
+        default:
+            prError = PR_UNKNOWN_ERROR;
+            break;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_opendir_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_closedir_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_readdir_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case 0:
+        case ENOENT:
+            prError = PR_NO_MORE_FILES_ERROR;
+            break;
+#ifdef EOVERFLOW
+        case EOVERFLOW:
+            prError = PR_IO_ERROR;
+            break;
+#endif
+        case EINVAL:
+            prError = PR_IO_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_IO_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_unlink_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EPERM:
+            prError = PR_IS_DIRECTORY_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_stat_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_fstat_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_rename_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EEXIST:
+            prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_access_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_mkdir_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_rmdir_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        /*
+         * On AIX 4.3, ENOTEMPTY is defined as EEXIST.
+         */
+#if ENOTEMPTY != EEXIST
+        case ENOTEMPTY:
+            prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
+            break;
+#endif
+        case EEXIST:
+            prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
+            break;
+        case EINVAL:
+            prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
+            break;
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_read_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_write_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_lseek_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_fsync_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        case EINVAL:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_close_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_socket_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_socketavailable_error(int err)
+{
+    PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+}
+
+void _MD_unix_map_recv_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_recvfrom_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_send_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_sendto_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_writev_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_accept_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENODEV:
+            prError = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_connect_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EACCES:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+#if defined(UNIXWARE) || defined(SNI) || defined(NEC)
+        /*
+         * On some platforms, if we connect to a port on the local host 
+         * (the loopback address) that no process is listening on, we get 
+         * EIO instead of ECONNREFUSED.
+         */
+        case EIO:
+            prError = PR_CONNECT_REFUSED_ERROR;
+            break;
+#endif
+        case ELOOP:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case ENOENT:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_IO_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_bind_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR;
+            break;
+        /*
+         * UNIX domain sockets are not supported in NSPR
+         */
+        case EIO:
+        case EISDIR:
+        case ELOOP:
+        case ENOENT:
+        case ENOTDIR:
+        case EROFS:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_listen_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_shutdown_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_socketpair_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_getsockname_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_getpeername_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_getsockopt_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_BUFFER_OVERFLOW_ERROR;
+            break;
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_setsockopt_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_BUFFER_OVERFLOW_ERROR;
+            break;
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_open_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EAGAIN:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case EBUSY:
+            prError = PR_IO_ERROR;
+            break;
+        case ENODEV:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+#ifdef EOVERFLOW
+        case EOVERFLOW:
+            prError = PR_FILE_TOO_BIG_ERROR;
+            break;
+#endif
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_mmap_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EAGAIN:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case EMFILE:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case ENODEV:
+            prError = PR_OPERATION_NOT_SUPPORTED_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_gethostname_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_select_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+#if defined(_PR_POLL_AVAILABLE) || defined(_PR_NEED_FAKE_POLL)
+void _MD_unix_map_poll_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EAGAIN:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_poll_revents_error(int err)
+{
+    if (err & POLLNVAL)
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
+    else if (err & POLLHUP)
+        PR_SetError(PR_CONNECT_RESET_ERROR, EPIPE);
+    else if (err & POLLERR)
+        PR_SetError(PR_IO_ERROR, EIO);
+    else
+        PR_SetError(PR_UNKNOWN_ERROR, err);
+}
+#endif /* _PR_POLL_AVAILABLE || _PR_NEED_FAKE_POLL */
+
+
+void _MD_unix_map_flock_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case EWOULDBLOCK:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_lockf_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EACCES:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+        case EDEADLK:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+#ifdef AIX
+void _MD_aix_map_sendfile_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+#endif /* AIX */
+
+#ifdef HPUX11
+void _MD_hpux_map_sendfile_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+#endif /* HPUX11 */
+
+#ifdef SOLARIS
+void _MD_solaris_map_sendfile_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        /*
+         * Solaris defines a 0 return value for sendfile to mean end-of-file.
+         */
+        case 0:
+            prError = PR_END_OF_FILE_ERROR;
+            break;
+
+        default:
+            _MD_unix_map_default_error(err) ;
+            return;
+    }
+    PR_SetError(prError, err);
+}
+#endif /* SOLARIS */
+
+#ifdef LINUX
+void _MD_linux_map_sendfile_error(int err)
+{
+    _MD_unix_map_default_error(err) ;
+}
+#endif /* LINUX */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unixware.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unixware.c
new file mode 100644
index 0000000..cbcbb3e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unixware.c
@@ -0,0 +1,583 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#if !defined (USE_SVR4_THREADS)
+
+/*
+         * using only NSPR threads here
+ */
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+#ifdef ALARMS_BREAK_TCP /* I don't think they do */
+
+PRInt32 _MD_connect(PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _connect(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+}
+
+PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _accept(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+    return(rv);
+}
+#endif
+
+/*
+ * These are also implemented in pratom.c using NSPR locks.  Any reason
+ * this might be better or worse?  If you like this better, define
+ * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h
+ */
+#ifdef _PR_HAVE_ATOMIC_OPS
+/* Atomic operations */
+#include  <stdio.h>
+static FILE *_uw_semf;
+
+void
+_MD_INIT_ATOMIC(void)
+{
+    /* Sigh.  Sure wish SYSV semaphores weren't such a pain to use */
+    if ((_uw_semf = tmpfile()) == NULL)
+        PR_ASSERT(0);
+
+    return;
+}
+
+void
+_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)++;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    flockfile(_uw_semf);
+    (*ptr) += val;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)--;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    flockfile(_uw_semf);
+    *val = newval;
+    unflockfile(_uw_semf);
+}
+#endif
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Unixware */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Unixware.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware.");
+}
+
+#else  /* USE_SVR4_THREADS */
+
+/* NOTE:
+ * SPARC v9 (Ultras) do have an atomic test-and-set operation.  But
+ * SPARC v8 doesn't.  We should detect in the init if we are running on
+ * v8 or v9, and then use assembly where we can.
+ */
+
+#include <thread.h>
+#include <synch.h>
+
+static mutex_t _unixware_atomic = DEFAULTMUTEX;
+
+#define TEST_THEN_ADD(where, inc) \
+    if (mutex_lock(&_unixware_atomic) != 0)\
+        PR_ASSERT(0);\
+    *where += inc;\
+    if (mutex_unlock(&_unixware_atomic) != 0)\
+        PR_ASSERT(0);
+
+#define TEST_THEN_SET(where, val) \
+    if (mutex_lock(&_unixware_atomic) != 0)\
+        PR_ASSERT(0);\
+    *where = val;\
+    if (mutex_unlock(&_unixware_atomic) != 0)\
+        PR_ASSERT(0);
+
+void
+_MD_INIT_ATOMIC(void)
+{
+}
+
+void
+_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    TEST_THEN_ADD(val, 1);
+}
+
+void
+_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    TEST_THEN_ADD(ptr, val);
+}
+
+void
+_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    TEST_THEN_ADD(val, 0xffffffff);
+}
+
+void
+_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    TEST_THEN_SET(val, newval);
+}
+
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/lwp.h>
+#include <sys/procfs.h>
+#include <sys/syscall.h>
+
+
+THREAD_KEY_T threadid_key;
+THREAD_KEY_T cpuid_key;
+THREAD_KEY_T last_thread_key;
+static sigset_t set, oldset;
+
+void _MD_EarlyInit(void)
+{
+    THR_KEYCREATE(&threadid_key, NULL);
+    THR_KEYCREATE(&cpuid_key, NULL);
+    THR_KEYCREATE(&last_thread_key, NULL);
+    sigemptyset(&set);
+    sigaddset(&set, SIGALRM);
+}
+
+PRStatus _MD_CREATE_THREAD(PRThread *thread, 
+					void (*start)(void *), 
+					PRThreadPriority priority,
+					PRThreadScope scope, 
+					PRThreadState state, 
+					PRUint32 stackSize) 
+{
+	long flags;
+	
+    /* mask out SIGALRM for native thread creation */
+    thr_sigsetmask(SIG_BLOCK, &set, &oldset); 
+
+    flags = (state == PR_JOINABLE_THREAD ? THR_SUSPENDED/*|THR_NEW_LWP*/ 
+			   : THR_SUSPENDED|THR_DETACHED/*|THR_NEW_LWP*/);
+	if (_PR_IS_GCABLE_THREAD(thread) ||
+							(scope == PR_GLOBAL_BOUND_THREAD))
+		flags |= THR_BOUND;
+
+    if (thr_create(NULL, thread->stack->stackSize,
+                  (void *(*)(void *)) start, (void *) thread, 
+				  flags,
+                  &thread->md.handle)) {
+        thr_sigsetmask(SIG_SETMASK, &oldset, NULL); 
+	return PR_FAILURE;
+    }
+
+
+    /* When the thread starts running, then the lwpid is set to the right
+     * value. Until then we want to mark this as 'uninit' so that
+     * its register state is initialized properly for GC */
+
+    thread->md.lwpid = -1;
+    thr_sigsetmask(SIG_SETMASK, &oldset, NULL); 
+    _MD_NEW_SEM(&thread->md.waiter_sem, 0);
+
+	if ((scope == PR_GLOBAL_THREAD) || (scope == PR_GLOBAL_BOUND_THREAD)) {
+		thread->flags |= _PR_GLOBAL_SCOPE;
+    }
+
+    /* 
+    ** Set the thread priority.  This will also place the thread on 
+    ** the runQ.
+    **
+    ** Force PR_SetThreadPriority to set the priority by
+    ** setting thread->priority to 100.
+    */
+    {
+    int pri;
+    pri = thread->priority;
+    thread->priority = 100;
+    PR_SetThreadPriority( thread, pri );
+
+    PR_LOG(_pr_thread_lm, PR_LOG_MIN, 
+            ("(0X%x)[Start]: on to runq at priority %d",
+            thread, thread->priority));
+    }
+
+    /* Activate the thread */
+    if (thr_continue( thread->md.handle ) ) {
+	return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+void _MD_cleanup_thread(PRThread *thread)
+{
+    thread_t hdl;
+    PRMonitor *mon;
+
+    hdl = thread->md.handle;
+
+    /* 
+    ** First, suspend the thread (unless it's the active one)
+    ** Because we suspend it first, we don't have to use LOCK_SCHEDULER to
+    ** prevent both of us modifying the thread structure at the same time.
+    */
+    if ( thread != _PR_MD_CURRENT_THREAD() ) {
+        thr_suspend(hdl);
+    }
+    PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+            ("(0X%x)[DestroyThread]\n", thread));
+
+    _MD_DESTROY_SEM(&thread->md.waiter_sem);
+}
+
+void _MD_SET_PRIORITY(_MDThread *md_thread, PRUintn newPri)
+{
+	if(thr_setprio((thread_t)md_thread->handle, newPri)) {
+		PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+		   ("_PR_SetThreadPriority: can't set thread priority\n"));
+	}
+}
+
+void _MD_WAIT_CV(
+    struct _MDCVar *md_cv, struct _MDLock *md_lock, PRIntervalTime timeout)
+{
+    struct timespec tt;
+    PRUint32 msec;
+    int rv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    msec = PR_IntervalToMilliseconds(timeout);
+
+    GETTIME (&tt);
+
+    tt.tv_sec += msec / PR_MSEC_PER_SEC;
+    tt.tv_nsec += (msec % PR_MSEC_PER_SEC) * PR_NSEC_PER_MSEC;
+    /* Check for nsec overflow - otherwise we'll get an EINVAL */
+    if (tt.tv_nsec >= PR_NSEC_PER_SEC) {
+        tt.tv_sec++;
+        tt.tv_nsec -= PR_NSEC_PER_SEC;
+    }
+    me->md.sp = unixware_getsp();
+
+
+    /* XXX Solaris 2.5.x gives back EINTR occasionally for no reason
+     * hence ignore EINTR for now */
+
+    COND_TIMEDWAIT(&md_cv->cv, &md_lock->lock, &tt);
+}
+
+void _MD_lock(struct _MDLock *md_lock)
+{
+    mutex_lock(&md_lock->lock);
+}
+
+void _MD_unlock(struct _MDLock *md_lock)
+{
+    mutex_unlock(&((md_lock)->lock));
+}
+
+
+PRThread *_pr_current_thread_tls()
+{
+    PRThread *ret;
+
+    thr_getspecific(threadid_key, (void **)&ret);
+    return ret;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+        _MD_WAIT_SEM(&thread->md.waiter_sem);
+        return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+	if (thread == NULL) {
+		return PR_SUCCESS;
+	}
+	_MD_POST_SEM(&thread->md.waiter_sem);
+	return PR_SUCCESS;
+}
+
+_PRCPU *_pr_current_cpu_tls()
+{
+    _PRCPU *ret;
+
+    thr_getspecific(cpuid_key, (void **)&ret);
+    return ret;
+}
+
+PRThread *_pr_last_thread_tls()
+{
+    PRThread *ret;
+
+    thr_getspecific(last_thread_key, (void **)&ret);
+    return ret;
+}
+
+_MDLock _pr_ioq_lock;
+
+void _MD_INIT_IO (void)
+{
+    _MD_NEW_LOCK(&_pr_ioq_lock);
+}
+
+PRStatus _MD_InitializeThread(PRThread *thread)
+{
+    if (!_PR_IS_NATIVE_THREAD(thread))
+        return;
+		/* prime the sp; substract 4 so we don't hit the assert that
+		 * curr sp > base_stack
+		 */
+    thread->md.sp = (uint_t) thread->stack->allocBase - sizeof(long);
+    thread->md.lwpid = _lwp_self();
+    thread->md.handle = THR_SELF();
+
+	/* all threads on Solaris are global threads from NSPR's perspective
+	 * since all of them are mapped to Solaris threads.
+	 */
+    thread->flags |= _PR_GLOBAL_SCOPE;
+
+ 	/* For primordial/attached thread, we don't create an underlying native thread.
+ 	 * So, _MD_CREATE_THREAD() does not get called.  We need to do initialization
+ 	 * like allocating thread's synchronization variables and set the underlying
+ 	 * native thread's priority.
+ 	 */
+	if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+	    _MD_NEW_SEM(&thread->md.waiter_sem, 0);
+	    _MD_SET_PRIORITY(&(thread->md), thread->priority);
+	}
+	return PR_SUCCESS;
+}
+
+static sigset_t old_mask;	/* store away original gc thread sigmask */
+static int gcprio;		/* store away original gc thread priority */
+static lwpid_t *all_lwps=NULL;	/* list of lwps that we suspended */
+static int num_lwps ;
+static int suspendAllOn = 0;
+
+#define VALID_SP(sp, bottom, top)	\
+       (((uint_t)(sp)) > ((uint_t)(bottom)) && ((uint_t)(sp)) < ((uint_t)(top)))
+
+void unixware_preempt_off()
+{
+    sigset_t set;
+    (void)sigfillset(&set);
+    sigprocmask (SIG_SETMASK, &set, &old_mask);
+}
+
+void unixware_preempt_on()
+{
+    sigprocmask (SIG_SETMASK, &old_mask, NULL);      
+}
+
+void _MD_Begin_SuspendAll()
+{
+    unixware_preempt_off();
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin_SuspendAll\n"));
+    /* run at highest prio so I cannot be preempted */
+    thr_getprio(thr_self(), &gcprio);
+    thr_setprio(thr_self(), 0x7fffffff); 
+    suspendAllOn = 1;
+}
+
+void _MD_End_SuspendAll()
+{
+}
+
+void _MD_End_ResumeAll()
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End_ResumeAll\n"));
+    thr_setprio(thr_self(), gcprio);
+    unixware_preempt_on();
+    suspendAllOn = 0;
+}
+
+void _MD_Suspend(PRThread *thr)
+{
+   int lwp_fd, result;
+   int lwp_main_proc_fd = 0;
+
+    thr_suspend(thr->md.handle);
+    if (!_PR_IS_GCABLE_THREAD(thr))
+      return;
+    /* XXX Primordial thread can't be bound to an lwp, hence there is no
+     * way we can assume that we can get the lwp status for primordial
+     * thread reliably. Hence we skip this for primordial thread, hoping
+     * that the SP is saved during lock and cond. wait. 
+     * XXX - Again this is concern only for java interpreter, not for the
+     * server, 'cause primordial thread in the server does not do java work
+     */
+    if (thr->flags & _PR_PRIMORDIAL)
+      return;
+
+    /* if the thread is not started yet then don't do anything */
+    if (!suspendAllOn || thr->md.lwpid == -1)
+      return;
+
+}
+void _MD_Resume(PRThread *thr)
+{
+   if (!_PR_IS_GCABLE_THREAD(thr) || !suspendAllOn){
+     /*XXX When the suspendAllOn is set, we will be trying to do lwp_suspend
+      * during that time we can't call any thread lib or libc calls. Hence
+      * make sure that no resume is requested for Non gcable thread
+      * during suspendAllOn */
+      PR_ASSERT(!suspendAllOn);
+      thr_continue(thr->md.handle);
+      return;
+   }
+   if (thr->md.lwpid == -1)
+     return;
+ 
+   if ( _lwp_continue(thr->md.lwpid) < 0) {
+      PR_ASSERT(0);  /* ARGH, we are hosed! */
+   }
+}
+
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) getcontext(CONTEXT(t));	/* XXX tune me: set md_IRIX.c */
+    }
+    *np = NGREG;
+    if (t->md.lwpid == -1)
+      memset(&t->md.context.uc_mcontext.gregs[0], 0, NGREG * sizeof(PRWord));
+    return (PRWord*) &t->md.context.uc_mcontext.gregs[0];
+}
+
+int
+_pr_unixware_clock_gettime (struct timespec *tp)
+{
+    struct timeval tv;
+ 
+    gettimeofday(&tv, NULL);
+    tp->tv_sec = tv.tv_sec;
+    tp->tv_nsec = tv.tv_usec * 1000;
+    return 0;
+}
+
+
+#endif /* USE_SVR4_THREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxpoll.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxpoll.c
new file mode 100644
index 0000000..aa02656
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxpoll.c
@@ -0,0 +1,708 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#if defined(_PR_PTHREADS)
+
+#error "This file should not be compiled"
+
+#else  /* defined(_PR_PTHREADS) */
+
+#include "primpl.h"
+
+#include <sys/time.h>
+
+#include <fcntl.h>
+#ifdef _PR_USE_POLL
+#include <poll.h>
+#endif
+
+#if defined(_PR_USE_POLL)
+static PRInt32 NativeThreadPoll(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    /*
+     * This function is mostly duplicated from ptio.s's PR_Poll().
+     */
+    PRInt32 ready = 0;
+    /*
+     * For restarting poll() if it is interrupted by a signal.
+     * We use these variables to figure out how much time has
+     * elapsed and how much of the timeout still remains.
+     */
+    PRIntn index, msecs;
+    struct pollfd *syspoll = NULL;
+    PRIntervalTime start, elapsed, remaining;
+
+    syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
+    if (NULL == syspoll)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+    for (index = 0; index < npds; ++index)
+    {
+        PRFileDesc *bottom;
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+        {
+            if (pds[index].in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pds[index].fd->methods->poll)(
+                    pds[index].fd,
+                    pds[index].in_flags & ~PR_POLL_WRITE,
+                    &out_flags_read);
+            }
+            if (pds[index].in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pds[index].fd->methods->poll)(
+                    pds[index].fd,
+                    pds[index].in_flags & ~PR_POLL_READ,
+                    &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read))
+            || (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one is ready right now */
+                if (0 == ready)
+                {
+                    /*
+                     * We will return without calling the system
+                     * poll function.  So zero the out_flags
+                     * fields of all the poll descriptors before
+                     * this one.
+                     */
+                    int i;
+                    for (i = 0; i < index; i++)
+                    {
+                        pds[i].out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pds[index].out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pds[index].out_flags = 0;  /* pre-condition */
+                /* now locate the NSPR layer at the bottom of the stack */
+                bottom = PR_GetIdentitiesLayer(pds[index].fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom)
+                && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        syspoll[index].fd = bottom->secret->md.osfd;
+                        syspoll[index].events = 0;  /* pre-condition */
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            pds[index].out_flags |=
+                                _PR_POLL_READ_SYS_READ;
+                            syspoll[index].events |= POLLIN;
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            pds[index].out_flags |=
+                                _PR_POLL_READ_SYS_WRITE;
+                            syspoll[index].events |= POLLOUT;
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            pds[index].out_flags |=
+                                _PR_POLL_WRITE_SYS_READ;
+                            syspoll[index].events |= POLLIN;
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            pds[index].out_flags |=
+                                _PR_POLL_WRITE_SYS_WRITE;
+                            syspoll[index].events |= POLLOUT;
+                        }
+                        if (pds[index].in_flags & PR_POLL_EXCEPT)
+                            syspoll[index].events |= POLLPRI;
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        int i;
+                        for (i = 0; i < index; i++)
+                        {
+                            pds[i].out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+        else
+        {
+            /* make poll() ignore this entry */
+            syspoll[index].fd = -1;
+            syspoll[index].events = 0;
+            pds[index].out_flags = 0;
+        }
+    }
+
+    if (0 == ready)
+    {
+        switch (timeout)
+        {
+            case PR_INTERVAL_NO_WAIT: msecs = 0; break;
+            case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break;
+            default:
+                msecs = PR_IntervalToMilliseconds(timeout);
+                start = PR_IntervalNow();
+        }
+
+retry:
+        ready = _MD_POLL(syspoll, npds, msecs);
+        if (-1 == ready)
+        {
+            PRIntn oserror = errno;
+
+            if (EINTR == oserror)
+            {
+                if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
+                else if (timeout == PR_INTERVAL_NO_WAIT) ready = 0;
+                else
+                {
+                    elapsed = (PRIntervalTime)(PR_IntervalNow() - start);
+                    if (elapsed > timeout) ready = 0;  /* timed out */
+                    else
+                    {
+                        remaining = timeout - elapsed;
+                        msecs = PR_IntervalToMilliseconds(remaining);
+                        goto retry;
+                    }
+                }
+            }
+            else _PR_MD_MAP_POLL_ERROR(oserror);
+        }
+        else if (ready > 0)
+        {
+            for (index = 0; index < npds; ++index)
+            {
+                PRInt16 out_flags = 0;
+                if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+                {
+                    if (0 != syspoll[index].revents)
+                    {
+                        /*
+                        ** Set up the out_flags so that it contains the
+                        ** bits that the highest layer thinks are nice
+                        ** to have. Then the client of that layer will
+                        ** call the appropriate I/O function and maybe
+                        ** the protocol will make progress.
+                        */
+                        if (syspoll[index].revents & POLLIN)
+                        {
+                            if (pds[index].out_flags
+                            & _PR_POLL_READ_SYS_READ)
+                            {
+                                out_flags |= PR_POLL_READ;
+                            }
+                            if (pds[index].out_flags
+                            & _PR_POLL_WRITE_SYS_READ)
+                            {
+                                out_flags |= PR_POLL_WRITE;
+                            }
+                        }
+                        if (syspoll[index].revents & POLLOUT)
+                        {
+                            if (pds[index].out_flags
+                            & _PR_POLL_READ_SYS_WRITE)
+                            {
+                                out_flags |= PR_POLL_READ;
+                            }
+                            if (pds[index].out_flags
+                            & _PR_POLL_WRITE_SYS_WRITE)
+                            {
+                                out_flags |= PR_POLL_WRITE;
+                            }
+                        }
+                        if (syspoll[index].revents & POLLPRI)
+                            out_flags |= PR_POLL_EXCEPT;
+                        if (syspoll[index].revents & POLLERR)
+                            out_flags |= PR_POLL_ERR;
+                        if (syspoll[index].revents & POLLNVAL)
+                            out_flags |= PR_POLL_NVAL;
+                        if (syspoll[index].revents & POLLHUP)
+                            out_flags |= PR_POLL_HUP;
+                    }
+                }
+                pds[index].out_flags = out_flags;
+            }
+        }
+    }
+
+    PR_DELETE(syspoll);
+    return ready;
+
+}  /* NativeThreadPoll */
+#endif  /* defined(_PR_USE_POLL) */
+
+#if !defined(_PR_USE_POLL)
+static PRInt32 NativeThreadSelect(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    /*
+     * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
+     */
+    fd_set rd, wt, ex;
+    PRFileDesc *bottom;
+    PRPollDesc *pd, *epd;
+    PRInt32 maxfd = -1, ready, err;
+    PRIntervalTime remaining, elapsed, start;
+
+    struct timeval tv, *tvp = NULL;
+
+    FD_ZERO(&rd);
+    FD_ZERO(&wt);
+    FD_ZERO(&ex);
+
+    ready = 0;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            if (pd->in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+            }
+            if (pd->in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read))
+            || (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one's ready right now */
+                if (0 == ready)
+                {
+                    /*
+                     * We will have to return without calling the
+                     * system poll/select function.  So zero the
+                     * out_flags fields of all the poll descriptors
+                     * before this one.
+                     */
+                    PRPollDesc *prev;
+                    for (prev = pds; prev < pd; prev++)
+                    {
+                        prev->out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pd->out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pd->out_flags = 0;  /* pre-condition */
+
+                /* make sure this is an NSPR supported stack */
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom)
+                && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        PRInt32 osfd = bottom->secret->md.osfd;
+                        if (osfd > maxfd) maxfd = osfd;
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
+                            FD_SET(osfd, &rd);
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+                            FD_SET(osfd, &wt);
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+                            FD_SET(osfd, &rd);
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+                            FD_SET(osfd, &wt);
+                        }
+                        if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        PRPollDesc *prev;
+                        for (prev = pds; prev < pd; prev++)
+                        {
+                            prev->out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+        else
+        {
+            pd->out_flags = 0;
+        }
+    }
+
+    if (0 != ready) return ready;  /* no need to block */
+
+    remaining = timeout;
+    start = PR_IntervalNow();
+
+retry:
+    if (timeout != PR_INTERVAL_NO_TIMEOUT)
+    {
+        PRInt32 ticksPerSecond = PR_TicksPerSecond();
+        tv.tv_sec = remaining / ticksPerSecond;
+        tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
+        tvp = &tv;
+    }
+
+    ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
+
+    if (ready == -1 && errno == EINTR)
+    {
+        if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
+        else
+        {
+            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+            if (elapsed > timeout) ready = 0;  /* timed out */
+            else
+            {
+                remaining = timeout - elapsed;
+                goto retry;
+            }
+        }
+    }
+
+    /*
+    ** Now to unravel the select sets back into the client's poll
+    ** descriptor list. Is this possibly an area for pissing away
+    ** a few cycles or what?
+    */
+    if (ready > 0)
+    {
+        ready = 0;
+        for (pd = pds, epd = pd + npds; pd < epd; pd++)
+        {
+            PRInt16 out_flags = 0;
+            if ((NULL != pd->fd) && (0 != pd->in_flags))
+            {
+                PRInt32 osfd;
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);
+
+                osfd = bottom->secret->md.osfd;
+
+                if (FD_ISSET(osfd, &rd))
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+                if (FD_ISSET(osfd, &wt))
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+                if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
+            }
+            pd->out_flags = out_flags;
+            if (out_flags) ready++;
+        }
+        PR_ASSERT(ready > 0);
+    }
+    else if (ready < 0)
+    {
+        err = _MD_ERRNO();
+        if (err == EBADF)
+        {
+            /* Find the bad fds */
+            ready = 0;
+            for (pd = pds, epd = pd + npds; pd < epd; pd++)
+            {
+                pd->out_flags = 0;
+                if ((NULL != pd->fd) && (0 != pd->in_flags))
+                {
+                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                    if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
+                    {
+                        pd->out_flags = PR_POLL_NVAL;
+                        ready++;
+                    }
+                }
+            }
+            PR_ASSERT(ready > 0);
+        }
+        else _PR_MD_MAP_SELECT_ERROR(err);
+    }
+
+    return ready;
+}  /* NativeThreadSelect */
+#endif  /* !defined(_PR_USE_POLL) */
+
+static PRInt32 LocalThreads(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRPollDesc *pd, *epd;
+    PRInt32 ready, pdcnt;
+    _PRUnixPollDesc *unixpds, *unixpd;
+
+    /*
+     * XXX
+     *        PRPollDesc has a PRFileDesc field, fd, while the IOQ
+     *        is a list of PRPollQueue structures, each of which contains
+     *        a _PRUnixPollDesc. A _PRUnixPollDesc struct contains
+     *        the OS file descriptor, osfd, and not a PRFileDesc.
+     *        So, we have allocate memory for _PRUnixPollDesc structures,
+     *        copy the flags information from the pds list and have pq
+     *        point to this list of _PRUnixPollDesc structures.
+     *
+     *        It would be better if the memory allocation can be avoided.
+     */
+
+    unixpd = unixpds = (_PRUnixPollDesc*)
+        PR_MALLOC(npds * sizeof(_PRUnixPollDesc));
+    if (NULL == unixpds)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+
+    ready = 0;
+    for (pdcnt = 0, pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        PRFileDesc *bottom;
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            if (pd->in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+            }
+            if (pd->in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read))
+            || (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one's ready right now */
+                if (0 == ready)
+                {
+                    /*
+                     * We will have to return without calling the
+                     * system poll/select function.  So zero the
+                     * out_flags fields of all the poll descriptors
+                     * before this one.
+                     */
+                    PRPollDesc *prev;
+                    for (prev = pds; prev < pd; prev++)
+                    {
+                        prev->out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pd->out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pd->out_flags = 0;  /* pre-condition */
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom)
+                && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        unixpd->osfd = bottom->secret->md.osfd;
+                        unixpd->in_flags = 0;
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_READ;
+                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
+                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_READ;
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+                        }
+                        if ((in_flags_read | in_flags_write) & PR_POLL_EXCEPT)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_EXCEPT;
+                        }
+                        unixpd++; pdcnt++;
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        PRPollDesc *prev;
+                        for (prev = pds; prev < pd; prev++)
+                        {
+                            prev->out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+    }
+
+    if (0 != ready)
+    {
+        /* no need to block */
+        PR_DELETE(unixpds);
+        return ready;
+    }
+
+    ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout);
+
+    /*
+     * Copy the out_flags from the _PRUnixPollDesc structures to the
+     * user's PRPollDesc structures and free the allocated memory
+     */
+    unixpd = unixpds;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        PRInt16 out_flags = 0;
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            /*
+             * take errors from the poll operation,
+             * the R/W bits from the request
+             */
+            if (0 != unixpd->out_flags)
+            {
+                if (unixpd->out_flags & _PR_UNIX_POLL_READ)
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+                        out_flags |= PR_POLL_WRITE;
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_WRITE)
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+                        out_flags |= PR_POLL_WRITE;
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT)
+                    out_flags |= PR_POLL_EXCEPT;
+                if (unixpd->out_flags & _PR_UNIX_POLL_ERR)
+                    out_flags |= PR_POLL_ERR;
+                if (unixpd->out_flags & _PR_UNIX_POLL_NVAL)
+                    out_flags |= PR_POLL_NVAL;
+                if (unixpd->out_flags & _PR_UNIX_POLL_HUP)
+                    out_flags |= PR_POLL_HUP;
+            }
+            unixpd++;
+        }
+        pd->out_flags = out_flags;
+    }
+
+    PR_DELETE(unixpds);
+
+    return ready;
+}  /* LocalThreads */
+
+#if defined(_PR_USE_POLL)
+#define NativeThreads NativeThreadPoll
+#else
+#define NativeThreads NativeThreadSelect
+#endif
+
+PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRInt32 rv = 0;
+    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 (0 == npds) PR_Sleep(timeout);
+    else if (_PR_IS_NATIVE_THREAD(me))
+        rv = NativeThreads(pds, npds, timeout);
+    else rv = LocalThreads(pds, npds, timeout);
+
+    return rv;
+}  /* _MD_pr_poll */
+
+#endif  /* defined(_PR_PTHREADS) */               
+
+/* uxpoll.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
new file mode 100644
index 0000000..364301c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
@@ -0,0 +1,912 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <string.h>
+#if defined(AIX)
+#include <dlfcn.h>  /* For dlopen, dlsym, dlclose */
+#endif
+
+#if defined(DARWIN)
+#include <crt_externs.h>
+#else
+PR_IMPORT_DATA(char **) environ;
+#endif
+
+/*
+ * HP-UX 9 doesn't have the SA_RESTART flag.
+ */
+#ifndef SA_RESTART
+#define SA_RESTART 0
+#endif
+
+/*
+ **********************************************************************
+ *
+ * The Unix process routines
+ *
+ **********************************************************************
+ */
+
+#define _PR_SIGNALED_EXITSTATUS 256
+
+typedef enum pr_PidState {
+    _PR_PID_DETACHED,
+    _PR_PID_REAPED,
+    _PR_PID_WAITING
+} pr_PidState;
+
+typedef struct pr_PidRecord {
+    pid_t pid;
+    int exitStatus;
+    pr_PidState state;
+    PRCondVar *reapedCV;
+    struct pr_PidRecord *next;
+} pr_PidRecord;
+
+/*
+ * Irix sprocs and LinuxThreads are actually a kind of processes
+ * that can share the virtual address space and file descriptors.
+ */
+#if (defined(IRIX) && !defined(_PR_PTHREADS)) \
+        || ((defined(LINUX) || defined(__GNU__) || defined(__GLIBC__)) \
+        && defined(_PR_PTHREADS))
+#define _PR_SHARE_CLONES
+#endif
+
+/*
+ * The macro _PR_NATIVE_THREADS indicates that we are
+ * using native threads only, so waitpid() blocks just the
+ * calling thread, not the process.  In this case, the waitpid
+ * daemon thread can safely block in waitpid().  So we don't
+ * need to catch SIGCHLD, and the pipe to unblock PR_Poll() is
+ * also not necessary.
+ */
+
+#if defined(_PR_GLOBAL_THREADS_ONLY) \
+	|| (defined(_PR_PTHREADS) \
+	&& !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__))
+#define _PR_NATIVE_THREADS
+#endif
+
+/*
+ * All the static variables used by the Unix process routines are
+ * collected in this structure.
+ */
+
+static struct {
+    PRCallOnceType once;
+    PRThread *thread;
+    PRLock *ml;
+#if defined(_PR_NATIVE_THREADS)
+    PRInt32 numProcs;
+    PRCondVar *cv;
+#else
+    int pipefd[2];
+#endif
+    pr_PidRecord **pidTable;
+
+#ifdef _PR_SHARE_CLONES
+    struct pr_CreateProcOp *opHead, *opTail;
+#endif
+
+#ifdef AIX
+    pid_t (*forkptr)(void);  /* Newer versions of AIX (starting in 4.3.2)
+                              * have f_fork, which is faster than the
+                              * regular fork in a multithreaded process
+                              * because it skips calling the fork handlers.
+                              * So we look up the f_fork symbol to see if
+                              * it's available and fall back on fork.
+                              */
+#endif /* AIX */
+} pr_wp;
+
+#ifdef _PR_SHARE_CLONES
+static int pr_waitpid_daemon_exit;
+
+void
+_MD_unix_terminate_waitpid_daemon(void)
+{
+    if (pr_wp.thread) {
+        pr_waitpid_daemon_exit = 1;
+        write(pr_wp.pipefd[1], "", 1);
+        PR_JoinThread(pr_wp.thread);
+    }
+}
+#endif
+
+static PRStatus _MD_InitProcesses(void);
+#if !defined(_PR_NATIVE_THREADS)
+static void pr_InstallSigchldHandler(void);
+#endif
+
+static PRProcess *
+ForkAndExec(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    PRProcess *process;
+    int nEnv, idx;
+    char *const *childEnvp;
+    char **newEnvp = NULL;
+    int flags;
+
+    process = PR_NEW(PRProcess);
+    if (!process) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    childEnvp = envp;
+    if (attr && attr->fdInheritBuffer) {
+        PRBool found = PR_FALSE;
+
+        if (NULL == childEnvp) {
+#ifdef DARWIN
+            childEnvp = *(_NSGetEnviron());
+#else
+            childEnvp = environ;
+#endif
+        }
+        for (nEnv = 0; childEnvp[nEnv]; nEnv++) {
+        }
+        newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *));
+        if (NULL == newEnvp) {
+            PR_DELETE(process);
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return NULL;
+        }
+        for (idx = 0; idx < nEnv; idx++) {
+            newEnvp[idx] = childEnvp[idx];
+            if (!found && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) {
+                newEnvp[idx] = attr->fdInheritBuffer;
+                found = PR_TRUE;
+            }
+        }
+        if (!found) {
+            newEnvp[idx++] = attr->fdInheritBuffer;
+        }
+        newEnvp[idx] = NULL;
+        childEnvp = newEnvp;
+    }
+
+#ifdef AIX
+    process->md.pid = (*pr_wp.forkptr)();
+#elif defined(NTO) || defined(SYMBIAN)
+    /*
+     * fork() & exec() does not work in a multithreaded process.
+     * Use spawn() instead.
+     */
+    {
+        int fd_map[3] = { 0, 1, 2 };
+
+        if (attr) {
+            if (attr->stdinFd && attr->stdinFd->secret->md.osfd != 0) {
+                fd_map[0] = dup(attr->stdinFd->secret->md.osfd);
+                flags = fcntl(fd_map[0], F_GETFL, 0);
+                if (flags & O_NONBLOCK)
+                    fcntl(fd_map[0], F_SETFL, flags & ~O_NONBLOCK);
+            }
+            if (attr->stdoutFd && attr->stdoutFd->secret->md.osfd != 1) {
+                fd_map[1] = dup(attr->stdoutFd->secret->md.osfd);
+                flags = fcntl(fd_map[1], F_GETFL, 0);
+                if (flags & O_NONBLOCK)
+                    fcntl(fd_map[1], F_SETFL, flags & ~O_NONBLOCK);
+            }
+            if (attr->stderrFd && attr->stderrFd->secret->md.osfd != 2) {
+                fd_map[2] = dup(attr->stderrFd->secret->md.osfd);
+                flags = fcntl(fd_map[2], F_GETFL, 0);
+                if (flags & O_NONBLOCK)
+                    fcntl(fd_map[2], F_SETFL, flags & ~O_NONBLOCK);
+            }
+
+            PR_ASSERT(attr->currentDirectory == NULL);  /* not implemented */
+        }
+
+#ifdef SYMBIAN
+        /* In Symbian OS, we use posix_spawn instead of fork() and exec() */
+        posix_spawn(&(process->md.pid), path, NULL, NULL, argv, childEnvp);
+#else
+        process->md.pid = spawn(path, 3, fd_map, NULL, argv, childEnvp);
+#endif
+
+        if (fd_map[0] != 0)
+            close(fd_map[0]);
+        if (fd_map[1] != 1)
+            close(fd_map[1]);
+        if (fd_map[2] != 2)
+            close(fd_map[2]);
+    }
+#else
+    process->md.pid = fork();
+#endif
+    if ((pid_t) -1 == process->md.pid) {
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno);
+        PR_DELETE(process);
+        if (newEnvp) {
+            PR_DELETE(newEnvp);
+        }
+        return NULL;
+    } else if (0 == process->md.pid) {  /* the child process */
+        /*
+         * If the child process needs to exit, it must call _exit().
+         * Do not call exit(), because exit() will flush and close
+         * the standard I/O file descriptors, and hence corrupt
+         * the parent process's standard I/O data structures.
+         */
+
+#if !defined(NTO) && !defined(SYMBIAN)
+        if (attr) {
+            /* the osfd's to redirect stdin, stdout, and stderr to */
+            int in_osfd = -1, out_osfd = -1, err_osfd = -1;
+
+            if (attr->stdinFd
+                    && attr->stdinFd->secret->md.osfd != 0) {
+                in_osfd = attr->stdinFd->secret->md.osfd;
+                if (dup2(in_osfd, 0) != 0) {
+                    _exit(1);  /* failed */
+                }
+                flags = fcntl(0, F_GETFL, 0);
+                if (flags & O_NONBLOCK) {
+                    fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
+                }
+            }
+            if (attr->stdoutFd
+                    && attr->stdoutFd->secret->md.osfd != 1) {
+                out_osfd = attr->stdoutFd->secret->md.osfd;
+                if (dup2(out_osfd, 1) != 1) {
+                    _exit(1);  /* failed */
+                }
+                flags = fcntl(1, F_GETFL, 0);
+                if (flags & O_NONBLOCK) {
+                    fcntl(1, F_SETFL, flags & ~O_NONBLOCK);
+                }
+            }
+            if (attr->stderrFd
+                    && attr->stderrFd->secret->md.osfd != 2) {
+                err_osfd = attr->stderrFd->secret->md.osfd;
+                if (dup2(err_osfd, 2) != 2) {
+                    _exit(1);  /* failed */
+                }
+                flags = fcntl(2, F_GETFL, 0);
+                if (flags & O_NONBLOCK) {
+                    fcntl(2, F_SETFL, flags & ~O_NONBLOCK);
+                }
+            }
+            if (in_osfd != -1) {
+                close(in_osfd);
+            }
+            if (out_osfd != -1 && out_osfd != in_osfd) {
+                close(out_osfd);
+            }
+            if (err_osfd != -1 && err_osfd != in_osfd
+                    && err_osfd != out_osfd) {
+                close(err_osfd);
+            }
+            if (attr->currentDirectory) {
+                if (chdir(attr->currentDirectory) < 0) {
+                    _exit(1);  /* failed */
+                }
+            }
+        }
+
+        if (childEnvp) {
+            (void)execve(path, argv, childEnvp);
+        } else {
+            /* Inherit the environment of the parent. */
+            (void)execv(path, argv);
+        }
+        /* Whoops! It returned. That's a bad sign. */
+        _exit(1);
+#endif /* !NTO */
+    }
+
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+
+#if defined(_PR_NATIVE_THREADS)
+    PR_Lock(pr_wp.ml);
+    if (0 == pr_wp.numProcs++) {
+        PR_NotifyCondVar(pr_wp.cv);
+    }
+    PR_Unlock(pr_wp.ml);
+#endif
+    return process;
+}
+
+#ifdef _PR_SHARE_CLONES
+
+struct pr_CreateProcOp {
+    const char *path;
+    char *const *argv;
+    char *const *envp;
+    const PRProcessAttr *attr;
+    PRProcess *process;
+    PRErrorCode prerror;
+    PRInt32 oserror;
+    PRBool done;
+    PRCondVar *doneCV;
+    struct pr_CreateProcOp *next;
+};
+
+PRProcess *
+_MD_CreateUnixProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    struct pr_CreateProcOp *op;
+    PRProcess *proc;
+    int rv;
+
+    if (PR_CallOnce(&pr_wp.once, _MD_InitProcesses) == PR_FAILURE) {
+	return NULL;
+    }
+
+    op = PR_NEW(struct pr_CreateProcOp);
+    if (NULL == op) {
+	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	return NULL;
+    }
+    op->path = path;
+    op->argv = argv;
+    op->envp = envp;
+    op->attr = attr;
+    op->done = PR_FALSE;
+    op->doneCV = PR_NewCondVar(pr_wp.ml);
+    if (NULL == op->doneCV) {
+	PR_DELETE(op);
+	return NULL;
+    }
+    PR_Lock(pr_wp.ml);
+
+    /* add to the tail of op queue */
+    op->next = NULL;
+    if (pr_wp.opTail) {
+	pr_wp.opTail->next = op;
+	pr_wp.opTail = op;
+    } else {
+	PR_ASSERT(NULL == pr_wp.opHead);
+	pr_wp.opHead = pr_wp.opTail = op;
+    }
+
+    /* wake up the daemon thread */
+    do {
+        rv = write(pr_wp.pipefd[1], "", 1);
+    } while (-1 == rv && EINTR == errno);
+
+    while (op->done == PR_FALSE) {
+	PR_WaitCondVar(op->doneCV, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(pr_wp.ml);
+    PR_DestroyCondVar(op->doneCV);
+    proc = op->process;
+    if (!proc) {
+	PR_SetError(op->prerror, op->oserror);
+    }
+    PR_DELETE(op);
+    return proc;
+}
+
+#else  /* ! _PR_SHARE_CLONES */
+
+PRProcess *
+_MD_CreateUnixProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    if (PR_CallOnce(&pr_wp.once, _MD_InitProcesses) == PR_FAILURE) {
+	return NULL;
+    }
+    return ForkAndExec(path, argv, envp, attr);
+}  /* _MD_CreateUnixProcess */
+
+#endif  /* _PR_SHARE_CLONES */
+
+/*
+ * The pid table is a hashtable.
+ *
+ * The number of buckets in the hashtable (NBUCKETS) must be a power of 2.
+ */
+#define NBUCKETS_LOG2 6
+#define NBUCKETS (1 << NBUCKETS_LOG2)
+#define PID_HASH_MASK ((pid_t) (NBUCKETS - 1))
+
+static pr_PidRecord *
+FindPidTable(pid_t pid)
+{
+    pr_PidRecord *pRec;
+    int keyHash = (int) (pid & PID_HASH_MASK);
+
+    pRec =  pr_wp.pidTable[keyHash];
+    while (pRec) {
+	if (pRec->pid == pid) {
+	    break;
+	}
+	pRec = pRec->next;
+    }
+    return pRec;
+}
+
+static void
+InsertPidTable(pr_PidRecord *pRec)
+{
+    int keyHash = (int) (pRec->pid & PID_HASH_MASK);
+
+    pRec->next = pr_wp.pidTable[keyHash];
+    pr_wp.pidTable[keyHash] = pRec;
+}
+
+static void
+DeletePidTable(pr_PidRecord *pRec)
+{
+    int keyHash = (int) (pRec->pid & PID_HASH_MASK);
+
+    if (pr_wp.pidTable[keyHash] == pRec) {
+	pr_wp.pidTable[keyHash] = pRec->next;
+    } else {
+	pr_PidRecord *pred, *cur;  /* predecessor and current */
+
+	pred = pr_wp.pidTable[keyHash];
+	cur = pred->next;
+	while (cur) {
+	    if (cur == pRec) {
+		pred->next = cur->next;
+		break;
+            }
+	    pred = cur;
+	    cur = cur->next;
+        }
+	PR_ASSERT(cur != NULL);
+    }
+}
+
+static int
+ExtractExitStatus(int rawExitStatus)
+{
+    /*
+     * We did not specify the WCONTINUED and WUNTRACED options
+     * for waitpid, so these two events should not be reported.
+     */
+    PR_ASSERT(!WIFSTOPPED(rawExitStatus));
+#ifdef WIFCONTINUED
+    PR_ASSERT(!WIFCONTINUED(rawExitStatus));
+#endif
+    if (WIFEXITED(rawExitStatus)) {
+	return WEXITSTATUS(rawExitStatus);
+    } else {
+	PR_ASSERT(WIFSIGNALED(rawExitStatus));
+	return _PR_SIGNALED_EXITSTATUS;
+    }
+}
+
+static void
+ProcessReapedChildInternal(pid_t pid, int status)
+{
+    pr_PidRecord *pRec;
+
+    pRec = FindPidTable(pid);
+    if (NULL == pRec) {
+        pRec = PR_NEW(pr_PidRecord);
+        pRec->pid = pid;
+        pRec->state = _PR_PID_REAPED;
+        pRec->exitStatus = ExtractExitStatus(status);
+        pRec->reapedCV = NULL;
+        InsertPidTable(pRec);
+    } else {
+        PR_ASSERT(pRec->state != _PR_PID_REAPED);
+        if (_PR_PID_DETACHED == pRec->state) {
+            PR_ASSERT(NULL == pRec->reapedCV);
+            DeletePidTable(pRec);
+            PR_DELETE(pRec);
+        } else {
+            PR_ASSERT(_PR_PID_WAITING == pRec->state);
+            PR_ASSERT(NULL != pRec->reapedCV);
+            pRec->exitStatus = ExtractExitStatus(status);
+            pRec->state = _PR_PID_REAPED;
+            PR_NotifyCondVar(pRec->reapedCV);
+        }
+    }
+}
+
+#if defined(_PR_NATIVE_THREADS)
+
+/*
+ * If all the threads are native threads, the daemon thread is
+ * simpler.  We don't need to catch the SIGCHLD signal.  We can
+ * just have the daemon thread block in waitpid().
+ */
+
+static void WaitPidDaemonThread(void *unused)
+{
+    pid_t pid;
+    int status;
+
+    while (1) {
+        PR_Lock(pr_wp.ml);
+        while (0 == pr_wp.numProcs) {
+            PR_WaitCondVar(pr_wp.cv, PR_INTERVAL_NO_TIMEOUT);
+        }
+        PR_Unlock(pr_wp.ml);
+
+	while (1) {
+	    do {
+	        pid = waitpid((pid_t) -1, &status, 0);
+	    } while ((pid_t) -1 == pid && EINTR == errno);
+
+            /*
+             * waitpid() cannot return 0 because we did not invoke it
+             * with the WNOHANG option.
+             */ 
+	    PR_ASSERT(0 != pid);
+
+            /*
+             * The only possible error code is ECHILD.  But if we do
+             * our accounting correctly, we should only call waitpid()
+             * when there is a child process to wait for.
+             */
+            PR_ASSERT((pid_t) -1 != pid);
+	    if ((pid_t) -1 == pid) {
+                break;
+            }
+
+	    PR_Lock(pr_wp.ml);
+            ProcessReapedChildInternal(pid, status);
+            pr_wp.numProcs--;
+            while (0 == pr_wp.numProcs) {
+                PR_WaitCondVar(pr_wp.cv, PR_INTERVAL_NO_TIMEOUT);
+            }
+	    PR_Unlock(pr_wp.ml);
+	}
+    }
+}
+
+#else /* _PR_NATIVE_THREADS */
+
+static void WaitPidDaemonThread(void *unused)
+{
+    PRPollDesc pd;
+    PRFileDesc *fd;
+    int rv;
+    char buf[128];
+    pid_t pid;
+    int status;
+#ifdef _PR_SHARE_CLONES
+    struct pr_CreateProcOp *op;
+#endif
+
+#ifdef _PR_SHARE_CLONES
+    pr_InstallSigchldHandler();
+#endif
+
+    fd = PR_ImportFile(pr_wp.pipefd[0]);
+    PR_ASSERT(NULL != fd);
+    pd.fd = fd;
+    pd.in_flags = PR_POLL_READ;
+
+    while (1) {
+        rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+        PR_ASSERT(1 == rv);
+
+#ifdef _PR_SHARE_CLONES
+        if (pr_waitpid_daemon_exit) {
+            return;
+        }
+	PR_Lock(pr_wp.ml);
+#endif
+	    
+        do {
+            rv = read(pr_wp.pipefd[0], buf, sizeof(buf));
+        } while (sizeof(buf) == rv || (-1 == rv && EINTR == errno));
+
+#ifdef _PR_SHARE_CLONES
+	PR_Unlock(pr_wp.ml);
+	while ((op = pr_wp.opHead) != NULL) {
+	    op->process = ForkAndExec(op->path, op->argv,
+		    op->envp, op->attr);
+	    if (NULL == op->process) {
+		op->prerror = PR_GetError();
+		op->oserror = PR_GetOSError();
+	    }
+	    PR_Lock(pr_wp.ml);
+	    pr_wp.opHead = op->next;
+	    if (NULL == pr_wp.opHead) {
+		pr_wp.opTail = NULL;
+	    }
+	    op->done = PR_TRUE;
+	    PR_NotifyCondVar(op->doneCV);
+	    PR_Unlock(pr_wp.ml);
+	}
+#endif
+
+	while (1) {
+	    do {
+	        pid = waitpid((pid_t) -1, &status, WNOHANG);
+	    } while ((pid_t) -1 == pid && EINTR == errno);
+	    if (0 == pid) break;
+	    if ((pid_t) -1 == pid) {
+		/* must be because we have no child processes */
+		PR_ASSERT(ECHILD == errno);
+		break;
+            }
+
+	    PR_Lock(pr_wp.ml);
+            ProcessReapedChildInternal(pid, status);
+	    PR_Unlock(pr_wp.ml);
+	}
+    }
+}
+
+static void pr_SigchldHandler(int sig)
+{
+    int errnoCopy;
+    int rv;
+
+    errnoCopy = errno;
+
+    do {
+        rv = write(pr_wp.pipefd[1], "", 1);
+    } while (-1 == rv && EINTR == errno);
+
+#ifdef DEBUG
+    if (-1 == rv && EAGAIN != errno && EWOULDBLOCK != errno) {
+        char *msg = "cannot write to pipe\n";
+        write(2, msg, strlen(msg) + 1);
+        _exit(1);
+    }
+#endif
+
+    errno = errnoCopy;
+}
+
+static void pr_InstallSigchldHandler()
+{
+#if defined(HPUX) && defined(_PR_DCETHREADS)
+#error "HP-UX DCE threads have their own SIGCHLD handler"
+#endif
+
+    struct sigaction act, oact;
+    int rv;
+
+    act.sa_handler = pr_SigchldHandler;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_NOCLDSTOP | SA_RESTART;
+    rv = sigaction(SIGCHLD, &act, &oact);
+    PR_ASSERT(0 == rv);
+    /* Make sure we are not overriding someone else's SIGCHLD handler */
+#ifndef _PR_SHARE_CLONES
+    PR_ASSERT(oact.sa_handler == SIG_DFL);
+#endif
+}
+
+#endif  /* !defined(_PR_NATIVE_THREADS) */
+
+static PRStatus _MD_InitProcesses(void)
+{
+#if !defined(_PR_NATIVE_THREADS)
+    int rv;
+    int flags;
+#endif
+#ifdef SUNOS4
+#define _PR_NBIO_FLAG FNDELAY
+#else
+#define _PR_NBIO_FLAG O_NONBLOCK
+#endif
+
+#ifdef AIX
+    {
+        void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
+        pr_wp.forkptr = (pid_t (*)(void)) dlsym(handle, "f_fork");
+        if (!pr_wp.forkptr) {
+            pr_wp.forkptr = fork;
+        }
+        dlclose(handle);
+    }
+#endif /* AIX */
+
+    pr_wp.ml = PR_NewLock();
+    PR_ASSERT(NULL != pr_wp.ml);
+
+#if defined(_PR_NATIVE_THREADS)
+    pr_wp.numProcs = 0;
+    pr_wp.cv = PR_NewCondVar(pr_wp.ml);
+    PR_ASSERT(NULL != pr_wp.cv);
+#else
+    rv = pipe(pr_wp.pipefd);
+    PR_ASSERT(0 == rv);
+    flags = fcntl(pr_wp.pipefd[0], F_GETFL, 0);
+    fcntl(pr_wp.pipefd[0], F_SETFL, flags | _PR_NBIO_FLAG);
+    flags = fcntl(pr_wp.pipefd[1], F_GETFL, 0);
+    fcntl(pr_wp.pipefd[1], F_SETFL, flags | _PR_NBIO_FLAG);
+
+#ifndef _PR_SHARE_CLONES
+    pr_InstallSigchldHandler();
+#endif
+#endif  /* !_PR_NATIVE_THREADS */
+
+    pr_wp.thread = PR_CreateThread(PR_SYSTEM_THREAD,
+	    WaitPidDaemonThread, NULL, PR_PRIORITY_NORMAL,
+#ifdef _PR_SHARE_CLONES
+            PR_GLOBAL_THREAD,
+#else
+	    PR_LOCAL_THREAD,
+#endif
+	    PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(NULL != pr_wp.thread);
+
+    pr_wp.pidTable = (pr_PidRecord**)PR_CALLOC(NBUCKETS * sizeof(pr_PidRecord *));
+    PR_ASSERT(NULL != pr_wp.pidTable);
+    return PR_SUCCESS;
+}
+
+PRStatus _MD_DetachUnixProcess(PRProcess *process)
+{
+    PRStatus retVal = PR_SUCCESS;
+    pr_PidRecord *pRec;
+
+    PR_Lock(pr_wp.ml);
+    pRec = FindPidTable(process->md.pid);
+    if (NULL == pRec) {
+	pRec = PR_NEW(pr_PidRecord);
+	if (NULL == pRec) {
+	    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	    retVal = PR_FAILURE;
+	    goto done;
+	}
+	pRec->pid = process->md.pid;
+	pRec->state = _PR_PID_DETACHED;
+	pRec->reapedCV = NULL;
+	InsertPidTable(pRec);
+    } else {
+	PR_ASSERT(_PR_PID_REAPED == pRec->state);
+	if (_PR_PID_REAPED != pRec->state) {
+	    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+	    retVal = PR_FAILURE;
+	} else {
+	    DeletePidTable(pRec);
+	    PR_ASSERT(NULL == pRec->reapedCV);
+	    PR_DELETE(pRec);
+	}
+    }
+    PR_DELETE(process);
+
+done:
+    PR_Unlock(pr_wp.ml);
+    return retVal;
+}
+
+PRStatus _MD_WaitUnixProcess(
+    PRProcess *process,
+    PRInt32 *exitCode)
+{
+    pr_PidRecord *pRec;
+    PRStatus retVal = PR_SUCCESS;
+    PRBool interrupted = PR_FALSE;
+
+    PR_Lock(pr_wp.ml);
+    pRec = FindPidTable(process->md.pid);
+    if (NULL == pRec) {
+	pRec = PR_NEW(pr_PidRecord);
+	if (NULL == pRec) {
+	    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	    retVal = PR_FAILURE;
+	    goto done;
+	}
+	pRec->pid = process->md.pid;
+	pRec->state = _PR_PID_WAITING;
+	pRec->reapedCV = PR_NewCondVar(pr_wp.ml);
+	if (NULL == pRec->reapedCV) {
+	    PR_DELETE(pRec);
+	    retVal = PR_FAILURE;
+	    goto done;
+	}
+	InsertPidTable(pRec);
+	while (!interrupted && _PR_PID_REAPED != pRec->state) {
+	    if (PR_WaitCondVar(pRec->reapedCV,
+		    PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE
+		    && PR_GetError() == PR_PENDING_INTERRUPT_ERROR) {
+		interrupted = PR_TRUE;
+            }
+	}
+	if (_PR_PID_REAPED == pRec->state) {
+            if (exitCode) {
+                *exitCode = pRec->exitStatus;
+            }
+	} else {
+	    PR_ASSERT(interrupted);
+	    retVal = PR_FAILURE;
+	}
+	DeletePidTable(pRec);
+	PR_DestroyCondVar(pRec->reapedCV);
+	PR_DELETE(pRec);
+    } else {
+	PR_ASSERT(_PR_PID_REAPED == pRec->state);
+	PR_ASSERT(NULL == pRec->reapedCV);
+	DeletePidTable(pRec);
+        if (exitCode) {
+            *exitCode = pRec->exitStatus;
+        }
+	PR_DELETE(pRec);
+    }
+    PR_DELETE(process);
+
+done:
+    PR_Unlock(pr_wp.ml);
+    return retVal;
+}  /* _MD_WaitUnixProcess */
+
+PRStatus _MD_KillUnixProcess(PRProcess *process)
+{
+    PRErrorCode prerror;
+    PRInt32 oserror;
+
+#ifdef SYMBIAN
+    /* In Symbian OS, we can not kill other process with Open C */
+    PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, oserror);
+    return PR_FAILURE;
+#else
+    if (kill(process->md.pid, SIGKILL) == 0) {
+	return PR_SUCCESS;
+    }
+    oserror = errno;
+    switch (oserror) {
+        case EPERM:
+	    prerror = PR_NO_ACCESS_RIGHTS_ERROR;
+	    break;
+        case ESRCH:
+	    prerror = PR_INVALID_ARGUMENT_ERROR;
+	    break;
+        default:
+	    prerror = PR_UNKNOWN_ERROR;
+	    break;
+    }
+    PR_SetError(prerror, oserror);
+    return PR_FAILURE;
+#endif
+}  /* _MD_KillUnixProcess */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxrng.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxrng.c
new file mode 100644
index 0000000..d46f447
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxrng.c
@@ -0,0 +1,328 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "primpl.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+
+
+#if defined(SOLARIS)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    hrtime_t t;
+    t = gethrtime();
+    if (t) {
+	    return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
+    }
+    return 0;
+}
+
+#elif defined(SUNOS4)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+
+#elif defined(HPUX)
+
+#ifdef __ia64
+#include <ia64/sys/inline.h>
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    PRUint64 t;
+
+#ifdef __GNUC__
+    __asm__ __volatile__("mov %0 = ar.itc" : "=r" (t));
+#else
+    t = _Asm_mov_from_ar(_AREG44);
+#endif
+    return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
+}
+#else
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    extern int ret_cr16();
+    int cr16val;
+
+    cr16val = ret_cr16();
+    return(_pr_CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val)));
+}
+#endif
+
+#elif defined(OSF1)
+
+#include <c_asm.h>
+
+/*
+ * Use the "get the cycle counter" instruction on the alpha.
+ * The low 32 bits completely turn over in less than a minute.
+ * The high 32 bits are some non-counter gunk that changes sometimes.
+ */
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    unsigned long t;
+
+#ifdef __GNUC__
+    __asm__("rpcc %0" : "=r" (t));
+#else
+    t = asm("rpcc %v0");
+#endif
+    return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
+}
+
+#elif defined(AIX)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+
+#elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) \
+    || defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD) \
+    || defined(SYMBIAN))
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static int      fdDevURandom;
+static PRCallOnceType coOpenDevURandom;
+
+static PRStatus OpenDevURandom( void )
+{
+    fdDevURandom = open( "/dev/urandom", O_RDONLY );
+    return((-1 == fdDevURandom)? PR_FAILURE : PR_SUCCESS );
+} /* end OpenDevURandom() */
+
+static size_t GetDevURandom( void *buf, size_t size )
+{
+    int bytesIn;
+    int rc;
+
+    rc = PR_CallOnce( &coOpenDevURandom, OpenDevURandom );
+    if ( PR_FAILURE == rc ) {
+        _PR_MD_MAP_OPEN_ERROR( errno );
+        return(0);
+    }
+
+    bytesIn = read( fdDevURandom, buf, size );
+    if ( -1 == bytesIn ) {
+        _PR_MD_MAP_READ_ERROR( errno );
+        return(0);
+    }
+
+    return( bytesIn );
+} /* end GetDevURandom() */
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{             
+    return(GetDevURandom( buf, maxbytes ));
+}
+
+#elif defined(NCR)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+
+#elif defined(IRIX)
+#include <fcntl.h>
+#undef PRIVATE
+#include <sys/mman.h>
+#include <sys/syssgi.h>
+#include <sys/immu.h>
+#include <sys/systeminfo.h>
+#include <sys/utsname.h>
+
+static size_t GetHighResClock(void *buf, size_t maxbuf)
+{
+    unsigned phys_addr, raddr, cycleval;
+    static volatile unsigned *iotimer_addr = NULL;
+    static int tries = 0;
+    static int cntr_size;
+    int mfd;
+    unsigned s0[2];
+
+#ifndef SGI_CYCLECNTR_SIZE
+#define SGI_CYCLECNTR_SIZE      165     /* Size user needs to use to read CC */
+#endif
+
+    if (iotimer_addr == NULL) {
+	    if (tries++ > 1) {
+	        /* Don't keep trying if it didn't work */
+	        return 0;
+	    }
+
+	    /*
+	    ** For SGI machines we can use the cycle counter, if it has one,
+	    ** to generate some truly random numbers
+	    */
+	    phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
+	    if (phys_addr) {
+	        int pgsz = getpagesize();
+	        int pgoffmask = pgsz - 1;
+
+	        raddr = phys_addr & ~pgoffmask;
+	        mfd = open("/dev/mmem", O_RDONLY);
+	        if (mfd < 0) {
+    		    return 0;
+	        }
+	        iotimer_addr = (unsigned *)
+		    mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr);
+	        if (iotimer_addr == (unsigned*)-1) {
+	    	    close(mfd);
+		        iotimer_addr = NULL;
+		        return 0;
+	        }
+	        iotimer_addr = (unsigned*)
+		    ((__psint_t)iotimer_addr | (phys_addr & pgoffmask));
+	        /*
+	         * The file 'mfd' is purposefully not closed.
+	         */
+	        cntr_size = syssgi(SGI_CYCLECNTR_SIZE);
+	        if (cntr_size < 0) {
+    		    struct utsname utsinfo;
+
+		        /* 
+		         * We must be executing on a 6.0 or earlier system, since the
+		         * SGI_CYCLECNTR_SIZE call is not supported.
+		         * 
+		         * The only pre-6.1 platforms with 64-bit counters are
+		         * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
+		         */
+		        uname(&utsinfo);
+		        if (!strncmp(utsinfo.machine, "IP19", 4) ||
+		            !strncmp(utsinfo.machine, "IP21", 4))
+			        cntr_size = 64;
+		        else
+			        cntr_size = 32;
+	        }
+	        cntr_size /= 8;	/* Convert from bits to bytes */
+	    }
+    }
+
+    s0[0] = *iotimer_addr;
+    if (cntr_size > 4)
+	s0[1] = *(iotimer_addr + 1);
+    memcpy(buf, (char *)&s0[0], cntr_size);
+    return _pr_CopyLowBits(buf, maxbuf, &s0, cntr_size);
+}
+
+#elif defined(SONY)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+
+#elif defined(SNI)
+#include <sys/times.h>
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    int ticks;
+    struct tms buffer;
+
+    ticks=times(&buffer);
+    return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
+}
+
+#elif defined(NEC)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+#elif defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \
+    || defined(QNX) || defined(DARWIN) || defined(RISCOS)
+#include <sys/times.h>
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    int ticks;
+    struct tms buffer;
+
+    ticks=times(&buffer);
+    return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
+}
+#else
+#error! Platform undefined
+#endif /* defined(SOLARIS) */
+
+extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
+{
+    struct timeval tv;
+    int n = 0;
+    int s;
+
+    n += GetHighResClock(buf, size);
+    size -= n;
+
+    GETTIMEOFDAY(&tv);
+
+    if ( size > 0 ) {
+        s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec));
+        size -= s;
+        n += s;
+    }
+    if ( size > 0 ) {
+        s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec));
+        size -= s;
+        n += s;
+    }
+
+    return n;
+} /* end _PR_MD_GetRandomNoise() */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxshm.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxshm.c
new file mode 100644
index 0000000..4eef672
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxshm.c
@@ -0,0 +1,675 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** uxshm.c -- Unix Implementations NSPR Named Shared Memory
+**
+**
+** lth. Jul-1999.
+**
+*/
+#include <string.h>
+#include <prshm.h>
+#include <prerr.h>
+#include <prmem.h>
+#include "primpl.h"       
+#include <fcntl.h>
+
+extern PRLogModuleInfo *_pr_shm_lm;
+
+
+#define NSPR_IPC_SHM_KEY 'b'
+/*
+** Implementation for System V
+*/
+#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
+#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
+#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
+#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
+#define _MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
+
+extern PRSharedMemory * _MD_OpenSharedMemory( 
+    const char *name,
+    PRSize      size,
+    PRIntn      flags,
+    PRIntn      mode
+)
+{
+    PRStatus rc = PR_SUCCESS;
+    key_t   key;
+    PRSharedMemory *shm;
+    char        ipcname[PR_IPC_NAME_SIZE];
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
+        return( NULL );
+    }
+
+    shm = PR_NEWZAP( PRSharedMemory );
+    if ( NULL == shm ) 
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 
+        return( NULL );
+    }
+
+    shm->ipcname = (char*)PR_MALLOC( strlen( ipcname ) + 1 );
+    if ( NULL == shm->ipcname )
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 
+        PR_DELETE( shm );
+        return( NULL );
+    }
+
+    /* copy args to struct */
+    strcpy( shm->ipcname, ipcname );
+    shm->size = size; 
+    shm->mode = mode; 
+    shm->flags = flags;
+    shm->ident = _PR_SHM_IDENT;
+
+    /* create the file first */
+    if ( flags & PR_SHM_CREATE )  {
+        int osfd = open( shm->ipcname, (O_RDWR | O_CREAT), shm->mode );
+        if ( -1 == osfd ) {
+            _PR_MD_MAP_OPEN_ERROR( errno );
+            PR_FREEIF( shm->ipcname );
+            PR_DELETE( shm );
+            return( NULL );
+        } 
+        if ( close(osfd) == -1 ) {
+            _PR_MD_MAP_CLOSE_ERROR( errno );
+            PR_FREEIF( shm->ipcname );
+            PR_DELETE( shm );
+            return( NULL );
+        }
+    }
+
+    /* hash the shm.name to an ID */
+    key = ftok( shm->ipcname, NSPR_IPC_SHM_KEY );
+    if ( -1 == key )
+    {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): ftok() failed on name: %s", shm->ipcname));
+        PR_FREEIF( shm->ipcname );
+        PR_DELETE( shm );
+        return( NULL );
+    }
+
+    /* get the shared memory */
+    if ( flags & PR_SHM_CREATE )  {
+        shm->id = shmget( key, shm->size, ( shm->mode | IPC_CREAT|IPC_EXCL));
+        if ( shm->id >= 0 ) {
+            return( shm );
+        }
+        if ((errno == EEXIST) && (flags & PR_SHM_EXCL)) {
+            PR_SetError( PR_FILE_EXISTS_ERROR, errno );
+            PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+                ("_MD_OpenSharedMemory(): shmget() exclusive failed, errno: %d", errno));
+            PR_FREEIF(shm->ipcname);
+            PR_DELETE(shm);
+            return(NULL);
+        }
+    } 
+
+    shm->id = shmget( key, shm->size, shm->mode );
+    if ( -1 == shm->id ) {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): shmget() failed, errno: %d", errno));
+        PR_FREEIF(shm->ipcname);
+        PR_DELETE(shm);
+        return(NULL);
+    }
+
+    return( shm );
+} /* end _MD_OpenSharedMemory() */
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
+{
+    void        *addr;
+    PRUint32    aFlags = shm->mode;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    aFlags |= (flags & PR_SHM_READONLY )? SHM_RDONLY : 0;
+
+    addr = shmat( shm->id, NULL, aFlags );
+    if ( (void*)-1 == addr )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_AttachSharedMemory(): shmat() failed on name: %s, OsError: %d", 
+                shm->ipcname, PR_GetOSError() ));
+        addr = NULL;
+    }
+
+    return addr;
+}    
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
+{
+    PRStatus rc = PR_SUCCESS;
+    PRIntn   urc;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    urc = shmdt( addr );
+    if ( -1 == urc )
+    {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DetachSharedMemory(): shmdt() failed on name: %s", shm->ipcname ));
+    }
+
+    return rc;
+}    
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
+{
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    PR_FREEIF(shm->ipcname);
+    PR_DELETE(shm);
+
+    return PR_SUCCESS;
+}    
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name )
+{
+    PRStatus rc = PR_SUCCESS;
+    key_t   key;
+    int     id;
+    PRIntn  urc;
+    char        ipcname[PR_IPC_NAME_SIZE];
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_SetError( PR_UNKNOWN_ERROR , errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
+        return(PR_FAILURE);
+    }
+
+    /* create the file first */ 
+    {
+        int osfd = open( ipcname, (O_RDWR | O_CREAT), 0666 );
+        if ( -1 == osfd ) {
+            _PR_MD_MAP_OPEN_ERROR( errno );
+            return( PR_FAILURE );
+        } 
+        if ( close(osfd) == -1 ) {
+            _PR_MD_MAP_CLOSE_ERROR( errno );
+            return( PR_FAILURE );
+        }
+    }
+
+    /* hash the shm.name to an ID */
+    key = ftok( ipcname, NSPR_IPC_SHM_KEY );
+    if ( -1 == key )
+    {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): ftok() failed on name: %s", ipcname));
+    }
+
+#ifdef SYMBIAN
+    /* In Symbian OS the system imposed minimum is 1 byte, instead of ZERO */
+    id = shmget( key, 1, 0 );
+#else
+    id = shmget( key, 0, 0 );
+#endif
+    if ( -1 == id ) {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): shmget() failed, errno: %d", errno));
+        return(PR_FAILURE);
+    }
+
+    urc = shmctl( id, IPC_RMID, NULL );
+    if ( -1 == urc )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): shmctl() failed on name: %s", ipcname ));
+        return(PR_FAILURE);
+    }
+
+    urc = unlink( ipcname );
+    if ( -1 == urc ) {
+        _PR_MD_MAP_UNLINK_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): unlink() failed: %s", ipcname ));
+        return(PR_FAILURE);
+    }
+
+    return rc;
+}  /* end _MD_DeleteSharedMemory() */
+
+/*
+** Implementation for Posix
+*/
+#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#include <sys/mman.h>
+
+#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
+#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
+#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
+#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
+#define _MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
+
+struct _MDSharedMemory {
+    int     handle;
+};
+
+extern PRSharedMemory * _MD_OpenSharedMemory( 
+    const char *name,
+    PRSize      size,
+    PRIntn      flags,
+    PRIntn      mode
+)
+{
+    PRStatus    rc = PR_SUCCESS;
+    PRInt32     end;
+    PRSharedMemory *shm;
+    char        ipcname[PR_IPC_NAME_SIZE];
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_SetError( PR_UNKNOWN_ERROR , errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
+        return( NULL );
+    }
+
+    shm = PR_NEWZAP( PRSharedMemory );
+    if ( NULL == shm ) 
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 
+        return( NULL );
+    }
+
+    shm->ipcname = PR_MALLOC( strlen( ipcname ) + 1 );
+    if ( NULL == shm->ipcname )
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 
+        return( NULL );
+    }
+
+    /* copy args to struct */
+    strcpy( shm->ipcname, ipcname );
+    shm->size = size; 
+    shm->mode = mode;
+    shm->flags = flags;
+    shm->ident = _PR_SHM_IDENT;
+
+    /*
+    ** Create the shared memory
+    */
+    if ( flags & PR_SHM_CREATE )  {
+        int oflag = (O_CREAT | O_RDWR);
+        
+        if ( flags & PR_SHM_EXCL )
+            oflag |= O_EXCL;
+        shm->id = shm_open( shm->ipcname, oflag, shm->mode );
+    } else {
+        shm->id = shm_open( shm->ipcname, O_RDWR, shm->mode );
+    }
+
+    if ( -1 == shm->id )  {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): shm_open failed: %s, OSError: %d",
+                shm->ipcname, PR_GetOSError())); 
+        PR_DELETE( shm->ipcname );
+        PR_DELETE( shm );
+        return(NULL);
+    }
+
+    end = ftruncate( shm->id, shm->size );
+    if ( -1 == end ) {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): ftruncate failed, OSError: %d",
+                PR_GetOSError()));
+        PR_DELETE( shm->ipcname );
+        PR_DELETE( shm );
+        return(NULL);
+    }
+
+    return(shm);
+} /* end _MD_OpenSharedMemory() */
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
+{
+    void        *addr;
+    PRIntn      prot = (PROT_READ | PROT_WRITE);
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    if ( PR_SHM_READONLY == flags)
+        prot ^= PROT_WRITE;
+
+    addr = mmap( (void*)0, shm->size, prot, MAP_SHARED, shm->id, 0 );
+    if ((void*)-1 == addr )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_AttachSharedMemory(): mmap failed: %s, errno: %d",
+                shm->ipcname, PR_GetOSError()));
+        addr = NULL;
+    } else {
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_AttachSharedMemory(): name: %s, attached at: %p", shm->ipcname, addr));
+    }
+    
+    return addr;
+}    
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
+{
+    PRStatus    rc = PR_SUCCESS;
+    PRIntn      urc;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    urc = munmap( addr, shm->size );
+    if ( -1 == urc )
+    {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DetachSharedMemory(): munmap failed: %s, errno: %d", 
+                shm->ipcname, PR_GetOSError()));
+    }
+    return rc;
+}    
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
+{
+    int urc;
+    
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    urc = close( shm->id );
+    if ( -1 == urc ) {
+        _PR_MD_MAP_CLOSE_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_CloseSharedMemory(): close() failed, error: %d", PR_GetOSError()));
+        return(PR_FAILURE);
+    }
+    PR_DELETE( shm->ipcname );
+    PR_DELETE( shm );
+    return PR_SUCCESS;
+}    
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name )
+{
+    PRStatus    rc = PR_SUCCESS;
+    PRUintn     urc;
+    char        ipcname[PR_IPC_NAME_SIZE];
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_SetError( PR_UNKNOWN_ERROR , errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
+        return rc;
+    }
+
+    urc = shm_unlink( ipcname );
+    if ( -1 == urc ) {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): shm_unlink failed: %s, errno: %d", 
+                ipcname, PR_GetOSError()));
+    } else {
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): %s, success", ipcname));
+    }
+
+    return rc;
+} /* end _MD_DeleteSharedMemory() */
+#endif
+
+
+
+/*
+** Unix implementation for anonymous memory (file) mapping
+*/
+extern PRLogModuleInfo *_pr_shma_lm;
+
+#include <unistd.h>
+
+extern PRFileMap* _md_OpenAnonFileMap( 
+    const char *dirName,
+    PRSize      size,
+    PRFileMapProtect prot
+)
+{
+    PRFileMap   *fm = NULL;
+    PRFileDesc  *fd;
+    int         osfd;
+    PRIntn      urc;
+    PRIntn      mode = 0600;
+    char        *genName;
+    pid_t       pid = getpid(); /* for generating filename */
+    PRThread    *tid = PR_GetCurrentThread(); /* for generating filename */
+    int         incr; /* for generating filename */
+    const int   maxTries = 20; /* maximum # attempts at a unique filename */
+    PRInt64     size64; /* 64-bit version of 'size' */
+
+    /*
+    ** generate a filename from input and runtime environment
+    ** open the file, unlink the file.
+    ** make maxTries number of attempts at uniqueness in the filename
+    */
+    for ( incr = 0; incr < maxTries ; incr++ ) {
+#if defined(SYMBIAN)
+#define NSPR_AFM_FILENAME "%s\\NSPR-AFM-%d-%p.%d"
+#else
+#define NSPR_AFM_FILENAME "%s/.NSPR-AFM-%d-%p.%d"
+#endif
+        genName = PR_smprintf( NSPR_AFM_FILENAME,
+            dirName, (int) pid, tid, incr );
+        if ( NULL == genName ) {
+            PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+                ("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename"));
+            goto Finished;
+        }
+        
+        /* create the file */
+        osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode );
+        if ( -1 == osfd ) {
+            if ( EEXIST == errno )  {
+                PR_smprintf_free( genName );
+                continue; /* name exists, try again */
+            } else {
+                _PR_MD_MAP_OPEN_ERROR( errno );
+                PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+                    ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d", 
+                        genName, PR_GetOSError()));
+                PR_smprintf_free( genName );
+                goto Finished;
+            }
+        }
+        break; /* name generation and open successful, break; */
+    } /* end for() */
+
+    if ( incr == maxTries ) {
+        PR_ASSERT( -1 == osfd );
+        PR_ASSERT( EEXIST == errno );
+        _PR_MD_MAP_OPEN_ERROR( errno );
+        goto Finished;
+    }
+
+    urc = unlink( genName );
+#if defined(SYMBIAN) && defined(__WINS__)
+    /* If it is being used by the system or another process, Symbian OS 
+     * Emulator(WINS) considers this an error. */
+    if ( -1 == urc && EACCES != errno ) {
+#else
+    if ( -1 == urc ) {
+#endif
+        _PR_MD_MAP_UNLINK_ERROR( errno );
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): failed on unlink(), errno: %d", errno));
+        PR_smprintf_free( genName );
+        close( osfd );
+        goto Finished;        
+    }
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_OpenAnonFileMap(): unlink(): %s", genName ));
+
+    PR_smprintf_free( genName );
+
+    fd = PR_ImportFile( osfd );
+    if ( NULL == fd ) {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): PR_ImportFile(): failed"));
+        goto Finished;        
+    }
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_OpenAnonFileMap(): fd: %p", fd ));
+
+    urc = ftruncate( fd->secret->md.osfd, size );
+    if ( -1 == urc ) {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): failed on ftruncate(), errno: %d", errno));
+        PR_Close( fd );
+        goto Finished;        
+    }
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_OpenAnonFileMap(): ftruncate(): size: %d", size ));
+
+    LL_UI2L(size64, size);  /* PRSize (size_t) is unsigned */
+    fm = PR_CreateFileMap( fd, size64, prot );
+    if ( NULL == fm )  {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("PR_OpenAnonFileMap(): failed"));
+        PR_Close( fd );
+        goto Finished;        
+    }
+    fm->md.isAnonFM = PR_TRUE; /* set fd close */
+
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_OpenAnonFileMap(): PR_CreateFileMap(): fm: %p", fm ));
+
+Finished:    
+    return(fm);
+} /* end md_OpenAnonFileMap() */
+
+/*
+** _md_ExportFileMapAsString()
+**
+**
+*/
+extern PRStatus _md_ExportFileMapAsString(
+    PRFileMap *fm,
+    PRSize    bufSize,
+    char      *buf
+)
+{
+    PRIntn  written;
+    PRIntn  prot = (PRIntn)fm->prot;
+    
+    written = PR_snprintf( buf, bufSize, "%ld:%d",
+        fm->fd->secret->md.osfd, prot );
+        
+    return((written == -1)? PR_FAILURE : PR_SUCCESS);
+} /* end _md_ExportFileMapAsString() */
+
+
+extern PRFileMap * _md_ImportFileMapFromString(
+    const char *fmstring
+)
+{
+    PRStatus    rc;
+    PRInt32     osfd;
+    PRIntn      prot; /* really: a PRFileMapProtect */
+    PRFileDesc  *fd;
+    PRFileMap   *fm = NULL; /* default return value */
+    PRFileInfo64 info;
+
+    PR_sscanf( fmstring, "%ld:%d", &osfd, &prot );
+
+    /* import the os file descriptor */
+    fd = PR_ImportFile( osfd );
+    if ( NULL == fd ) {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_ImportFileMapFromString(): PR_ImportFile() failed"));
+        goto Finished;
+    }
+
+    rc = PR_GetOpenFileInfo64( fd, &info );
+    if ( PR_FAILURE == rc )  {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_ImportFileMapFromString(): PR_GetOpenFileInfo64() failed"));    
+        goto Finished;
+    }
+
+    fm = PR_CreateFileMap( fd, info.size, (PRFileMapProtect)prot );
+    if ( NULL == fm ) {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_ImportFileMapFromString(): PR_CreateFileMap() failed"));    
+    }
+
+Finished:
+    return(fm);
+} /* end _md_ImportFileMapFromString() */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxwrap.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxwrap.c
new file mode 100644
index 0000000..ef226a6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxwrap.c
@@ -0,0 +1,548 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *------------------------------------------------------------------------
+ * File: uxwrap.c
+ *
+ *     Our wrapped versions of the Unix select() and poll() system calls.
+ *
+ *------------------------------------------------------------------------
+ */
+
+#include "primpl.h"
+
+#if defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) || defined(QNX)
+/* Do not wrap select() and poll(). */
+#else  /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */
+/* The include files for select() */
+#ifdef IRIX
+#include <unistd.h>
+#include <bstring.h>
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#define ZAP_SET(_to, _width)				      \
+    PR_BEGIN_MACRO					      \
+	memset(_to, 0,					      \
+	       ((_width + 8*sizeof(int)-1) / (8*sizeof(int))) \
+		* sizeof(int)				      \
+	       );					      \
+    PR_END_MACRO
+
+/* see comments in ns/cmd/xfe/mozilla.c (look for "PR_XGetXtHackFD") */
+static int _pr_xt_hack_fd = -1;
+ 
+int PR_XGetXtHackFD(void)
+{
+    int fds[2];
+ 
+    if (_pr_xt_hack_fd == -1) {
+        if (!pipe(fds)) {
+            _pr_xt_hack_fd = fds[0];
+        }
+    }
+    return _pr_xt_hack_fd;
+}
+
+static int (*_pr_xt_hack_okayToReleaseXLock)(void) = 0;
+
+void PR_SetXtHackOkayToReleaseXLockFn(int (*fn)(void))
+{
+    _pr_xt_hack_okayToReleaseXLock = fn; 
+}
+
+
+/*
+ *-----------------------------------------------------------------------
+ *  select() --
+ *
+ *    Wrap up the select system call so that we can deschedule
+ *    a thread that tries to wait for i/o.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+#if defined(HPUX9)
+int select(size_t width, int *rl, int *wl, int *el, const struct timeval *tv)
+#elif defined(NEXTSTEP)
+int wrap_select(int width, fd_set *rd, fd_set *wr, fd_set *ex,
+        const struct timeval *tv)
+#elif defined(AIX_RENAME_SELECT)
+int wrap_select(unsigned long width, void *rl, void *wl, void *el,
+        struct timeval *tv)
+#elif defined(_PR_SELECT_CONST_TIMEVAL)
+int select(int width, fd_set *rd, fd_set *wr, fd_set *ex,
+        const struct timeval *tv)
+#else
+int select(int width, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *tv)
+#endif
+{
+    int osfd;
+    _PRUnixPollDesc *unixpds, *unixpd, *eunixpd;
+    PRInt32 pdcnt;
+    PRIntervalTime timeout;
+    int retVal;
+#if defined(HPUX9) || defined(AIX_RENAME_SELECT)
+    fd_set *rd = (fd_set*) rl;
+    fd_set *wr = (fd_set*) wl;
+    fd_set *ex = (fd_set*) el;
+#endif
+
+#if 0
+    /*
+     * Easy special case: zero timeout.  Simply call the native
+     * select() with no fear of blocking.
+     */
+    if (tv != NULL && tv->tv_sec == 0 && tv->tv_usec == 0) {
+#if defined(HPUX9) || defined(AIX_RENAME_SELECT)
+        return _MD_SELECT(width, rl, wl, el, tv);
+#else
+        return _MD_SELECT(width, rd, wr, ex, tv);
+#endif
+    }
+#endif
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+		
+#ifndef _PR_LOCAL_THREADS_ONLY
+    if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) {
+        return _MD_SELECT(width, rd, wr, ex, tv);	
+    }
+#endif
+
+    if (width < 0 || width > FD_SETSIZE) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    /* Compute timeout */
+    if (tv) {
+        /*
+         * These acceptable ranges for t_sec and t_usec are taken
+         * from the select() man pages.
+         */
+        if (tv->tv_sec < 0 || tv->tv_sec > 100000000
+                || tv->tv_usec < 0 || tv->tv_usec >= 1000000) {
+            errno = EINVAL;
+            return -1;
+        }
+
+        /* Convert microseconds to ticks */
+        timeout = PR_MicrosecondsToInterval(1000000*tv->tv_sec + tv->tv_usec);
+    } else {
+        /* tv being a NULL pointer means blocking indefinitely */
+        timeout = PR_INTERVAL_NO_TIMEOUT;
+    }
+
+    /* Check for no descriptors case (just doing a timeout) */
+    if ((!rd && !wr && !ex) || !width) {
+        PR_Sleep(timeout);
+        return 0;
+    }
+
+    /*
+     * Set up for PR_Poll().  The PRPollDesc array is allocated
+     * dynamically.  If this turns out to have high performance
+     * penalty, one can change to use a large PRPollDesc array
+     * on the stack, and allocate dynamically only when it turns
+     * out to be not large enough.
+     *
+     * I allocate an array of size 'width', which is the maximum
+     * number of fds we may need to poll.
+     */
+    unixpds = (_PRUnixPollDesc *) PR_CALLOC(width * sizeof(_PRUnixPollDesc));
+    if (!unixpds) {
+        errno = ENOMEM;
+        return -1;
+    }
+
+    pdcnt = 0;
+    unixpd = unixpds;
+    for (osfd = 0; osfd < width; osfd++) {
+        int in_flags = 0;
+        if (rd && FD_ISSET(osfd, rd)) {
+            in_flags |= _PR_UNIX_POLL_READ;
+        }
+        if (wr && FD_ISSET(osfd, wr)) {
+            in_flags |= _PR_UNIX_POLL_WRITE;
+        }
+        if (ex && FD_ISSET(osfd, ex)) {
+            in_flags |= _PR_UNIX_POLL_EXCEPT;
+        }
+        if (in_flags) {
+            unixpd->osfd = osfd;
+            unixpd->in_flags = in_flags;
+            unixpd->out_flags = 0;
+            unixpd++;
+            pdcnt++;
+        }
+    }
+
+    /*
+     * see comments in mozilla/cmd/xfe/mozilla.c (look for
+     * "PR_XGetXtHackFD")
+     */
+   {
+     int needToLockXAgain;
+ 
+     needToLockXAgain = 0;
+     if (rd && (_pr_xt_hack_fd != -1)
+             && FD_ISSET(_pr_xt_hack_fd, rd) && PR_XIsLocked()
+             && (!_pr_xt_hack_okayToReleaseXLock
+             || _pr_xt_hack_okayToReleaseXLock())) {
+         PR_XUnlock();
+         needToLockXAgain = 1;
+     }
+
+    /* This is the potentially blocking step */
+    retVal = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout);
+
+     if (needToLockXAgain) {
+         PR_XLock();
+     }
+   }
+
+    if (retVal > 0) {
+        /* Compute select results */
+        if (rd) ZAP_SET(rd, width);
+        if (wr) ZAP_SET(wr, width);
+        if (ex) ZAP_SET(ex, width);
+
+        /*
+         * The return value can be either the number of ready file
+         * descriptors or the number of set bits in the three fd_set's.
+         */
+        retVal = 0;  /* we're going to recompute */
+        eunixpd = unixpds + pdcnt;
+        for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
+            if (unixpd->out_flags) {
+                int nbits = 0;  /* The number of set bits on for this fd */
+
+                if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) {
+                    errno = EBADF;
+                    PR_LOG(_pr_io_lm, PR_LOG_ERROR,
+                            ("select returns EBADF for %d", unixpd->osfd));
+                    retVal = -1;
+                    break;
+                }
+                /*
+                 * If a socket has a pending error, it is considered
+                 * both readable and writable.  (See W. Richard Stevens,
+                 * Unix Network Programming, Vol. 1, 2nd Ed., Section 6.3,
+                 * pp. 153-154.)  We also consider a socket readable if
+                 * it has a hangup condition.
+                 */
+                if (rd && (unixpd->in_flags & _PR_UNIX_POLL_READ)
+                        && (unixpd->out_flags & (_PR_UNIX_POLL_READ
+                        | _PR_UNIX_POLL_ERR | _PR_UNIX_POLL_HUP))) {
+                    FD_SET(unixpd->osfd, rd);
+                    nbits++;
+                }
+                if (wr && (unixpd->in_flags & _PR_UNIX_POLL_WRITE)
+                        && (unixpd->out_flags & (_PR_UNIX_POLL_WRITE
+                        | _PR_UNIX_POLL_ERR))) {
+                    FD_SET(unixpd->osfd, wr);
+                    nbits++;
+                }
+                if (ex && (unixpd->in_flags & _PR_UNIX_POLL_WRITE)
+                        && (unixpd->out_flags & PR_POLL_EXCEPT)) {
+                    FD_SET(unixpd->osfd, ex);
+                    nbits++;
+                }
+                PR_ASSERT(nbits > 0);
+#if defined(HPUX) || defined(SOLARIS) || defined(SUNOS4) || defined(OSF1) || defined(AIX)
+                retVal += nbits;
+#else /* IRIX */
+                retVal += 1;
+#endif
+            }
+        }
+    }
+
+    PR_ASSERT(tv || retVal != 0);
+    PR_LOG(_pr_io_lm, PR_LOG_MIN, ("select returns %d", retVal));
+    PR_DELETE(unixpds);
+
+    return retVal;
+}
+
+/*
+ * Redefine poll, when supported on platforms, for local threads
+ */
+
+/*
+ * I am commenting out the poll() wrapper for Linux for now
+ * because it is difficult to define _MD_POLL that works on all
+ * Linux varieties.  People reported that glibc 2.0.7 on Debian
+ * 2.0 Linux machines doesn't have the __syscall_poll symbol
+ * defined.  (WTC 30 Nov. 1998)
+ */
+#if defined(_PR_POLL_AVAILABLE) && !defined(LINUX)
+
+/*
+ *-----------------------------------------------------------------------
+ * poll() --
+ *
+ * RETURN VALUES: 
+ *     -1:  fails, errno indicates the error.
+ *      0:  timed out, the revents bitmasks are not set.
+ *      positive value: the number of file descriptors for which poll()
+ *          has set the revents bitmask.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+#include <poll.h>
+
+#if defined(AIX_RENAME_SELECT)
+int wrap_poll(void *listptr, unsigned long nfds, long timeout)
+#elif (defined(AIX) && !defined(AIX_RENAME_SELECT))
+int poll(void *listptr, unsigned long nfds, long timeout)
+#elif defined(OSF1) || (defined(HPUX) && !defined(HPUX9))
+int poll(struct pollfd filedes[], unsigned int nfds, int timeout)
+#elif defined(HPUX9)
+int poll(struct pollfd filedes[], int nfds, int timeout)
+#elif defined(NETBSD)
+int poll(struct pollfd *filedes, nfds_t nfds, int timeout)
+#elif defined(OPENBSD)
+int poll(struct pollfd filedes[], nfds_t nfds, int timeout)
+#elif defined(FREEBSD)
+int poll(struct pollfd *filedes, unsigned nfds, int timeout)
+#else
+int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
+#endif
+{
+#ifdef AIX
+    struct pollfd *filedes = (struct pollfd *) listptr;
+#endif
+    struct pollfd *pfd, *epfd;
+    _PRUnixPollDesc *unixpds, *unixpd, *eunixpd;
+    PRIntervalTime ticks;
+    PRInt32 pdcnt;
+    int ready;
+
+    /*
+     * Easy special case: zero timeout.  Simply call the native
+     * poll() with no fear of blocking.
+     */
+    if (timeout == 0) {
+#if defined(AIX)
+        return _MD_POLL(listptr, nfds, timeout);
+#else
+        return _MD_POLL(filedes, nfds, timeout);
+#endif
+    }
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+
+#ifndef _PR_LOCAL_THREADS_ONLY
+    if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) {
+    	return _MD_POLL(filedes, nfds, timeout);
+    }
+#endif
+
+    /* We do not support the pollmsg structures on AIX */
+#ifdef AIX
+    PR_ASSERT((nfds & 0xff00) == 0);
+#endif
+
+    if (timeout < 0 && timeout != -1) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    /* Convert timeout from miliseconds to ticks */
+    if (timeout == -1) {
+        ticks = PR_INTERVAL_NO_TIMEOUT;
+    } else {
+        ticks = PR_MillisecondsToInterval(timeout);
+    }
+
+    /* Check for no descriptor case (just do a timeout) */
+    if (nfds == 0) {
+        PR_Sleep(ticks);
+        return 0;
+    }
+
+    unixpds = (_PRUnixPollDesc *)
+            PR_MALLOC(nfds * sizeof(_PRUnixPollDesc));
+    if (NULL == unixpds) {
+        errno = EAGAIN;
+        return -1;
+    }
+
+    pdcnt = 0;
+    epfd = filedes + nfds;
+    unixpd = unixpds;
+    for (pfd = filedes; pfd < epfd; pfd++) {
+        /*
+         * poll() ignores negative fd's.
+         */
+        if (pfd->fd >= 0) {
+            unixpd->osfd = pfd->fd;
+#ifdef _PR_USE_POLL
+            unixpd->in_flags = pfd->events;
+#else
+            /*
+             * Map the poll events to one of the three that can be
+             * represented by the select fd_sets:
+             *     POLLIN, POLLRDNORM  ===> readable
+             *     POLLOUT, POLLWRNORM ===> writable
+             *     POLLPRI, POLLRDBAND ===> exception
+             *     POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
+             *     are ignored.
+             *
+             * The output events POLLERR and POLLHUP are never turned on.
+             * POLLNVAL may be turned on.
+             */
+            unixpd->in_flags = 0;
+            if (pfd->events & (POLLIN
+#ifdef POLLRDNORM
+                    | POLLRDNORM
+#endif
+                    )) {
+                unixpd->in_flags |= _PR_UNIX_POLL_READ;
+            }
+            if (pfd->events & (POLLOUT
+#ifdef POLLWRNORM
+                    | POLLWRNORM
+#endif
+                    )) {
+                unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
+            }
+            if (pfd->events & (POLLPRI
+#ifdef POLLRDBAND
+                    | POLLRDBAND
+#endif
+                    )) {
+                unixpd->in_flags |= PR_POLL_EXCEPT;
+            }
+#endif  /* _PR_USE_POLL */
+            unixpd->out_flags = 0;
+            unixpd++;
+            pdcnt++;
+        }
+    }
+
+    ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, ticks);
+    if (-1 == ready) {
+        if (PR_GetError() == PR_PENDING_INTERRUPT_ERROR) {
+            errno = EINTR;  /* XXX we aren't interrupted by a signal, but... */
+        } else {
+            errno = PR_GetOSError();
+        }
+    }
+    if (ready <= 0) {
+        goto done;
+    }
+
+    /*
+     * Copy the out_flags from the _PRUnixPollDesc structures to the
+     * user's pollfd structures and free the allocated memory
+     */
+    unixpd = unixpds;
+    for (pfd = filedes; pfd < epfd; pfd++) {
+        pfd->revents = 0;
+        if (pfd->fd >= 0) {
+#ifdef _PR_USE_POLL
+            pfd->revents = unixpd->out_flags;
+#else
+            if (0 != unixpd->out_flags) {
+                if (unixpd->out_flags & _PR_UNIX_POLL_READ) {
+                    if (pfd->events & POLLIN) {
+                        pfd->revents |= POLLIN;
+                    }
+#ifdef POLLRDNORM
+                    if (pfd->events & POLLRDNORM) {
+                        pfd->revents |= POLLRDNORM;
+                    }
+#endif
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) {
+                    if (pfd->events & POLLOUT) {
+                        pfd->revents |= POLLOUT;
+                    }
+#ifdef POLLWRNORM
+                    if (pfd->events & POLLWRNORM) {
+                        pfd->revents |= POLLWRNORM;
+                    }
+#endif
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) {
+                    if (pfd->events & POLLPRI) {
+                        pfd->revents |= POLLPRI;
+                    }
+#ifdef POLLRDBAND
+                    if (pfd->events & POLLRDBAND) {
+                        pfd->revents |= POLLRDBAND;
+                    }
+#endif
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_ERR) {
+                    pfd->revents |= POLLERR;
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) {
+                    pfd->revents |= POLLNVAL;
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_HUP) {
+                    pfd->revents |= POLLHUP;
+                }
+            }
+#endif  /* _PR_USE_POLL */
+            unixpd++;
+        }
+    }
+
+done:
+    PR_DELETE(unixpds);
+    return ready;
+}
+
+#endif  /* !defined(LINUX) */
+
+#endif  /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */
+
+/* uxwrap.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/Makefile.in
new file mode 100644
index 0000000..fbf2987
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/Makefile.in
@@ -0,0 +1,104 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET)))
+CSRCS =          \
+    ntmisc.c \
+    ntsec.c   \
+    ntsem.c   \
+    ntinrval.c \
+    ntgc.c \
+	w95thred.c \
+	w95io.c \
+	w95cv.c \
+	w32rng.c \
+	w95sock.c \
+	win32_errors.c \
+    w32ipcsem.c \
+    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 \
+    w32rng.c \
+    w32shm.c \
+    $(NULL)
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES += -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+# Bug 122433 workaround: disable global optimization (-Og-) on ntio.c.
+ifdef MOZ_OPTIMIZE
+ifeq ($(OS_TARGET), WINNT)
+ifndef NS_USE_GCC
+$(OBJDIR)/ntio.$(OBJ_SUFFIX): ntio.c
+	@$(MAKE_OBJDIR)
+	$(CC) -Fo$@ -c $(CFLAGS) -Og- $<
+endif
+endif
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntdllmn.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntdllmn.c
new file mode 100644
index 0000000..fa8d25f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntdllmn.c
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * The DLL entry point (DllMain) for NSPR.
+ *
+ * The only reason we use DLLMain() now is to find out whether
+ * the NSPR DLL is statically or dynamically loaded.  When
+ * dynamically loaded, we cannot use static thread-local storage.
+ * However, static TLS is faster than the TlsXXX() functions.
+ * So we want to use static TLS whenever we can.  A global
+ * variable _pr_use_static_tls is set in DllMain() during process
+ * attachment to indicate whether it is safe to use static TLS
+ * or not.
+ */
+
+#include <windows.h>
+#include <primpl.h>
+
+extern BOOL _pr_use_static_tls;  /* defined in ntthread.c */
+
+BOOL WINAPI DllMain(
+    HINSTANCE hinstDLL,
+    DWORD fdwReason,
+    LPVOID lpvReserved)
+{
+PRThread *me;
+
+    switch (fdwReason) {
+        case DLL_PROCESS_ATTACH:
+            /*
+             * If lpvReserved is NULL, we are dynamically loaded
+             * and therefore can't use static thread-local storage.
+             */
+            if (lpvReserved == NULL) {
+                _pr_use_static_tls = FALSE;
+            } else {
+                _pr_use_static_tls = TRUE;
+            }
+            break;
+        case DLL_THREAD_ATTACH:
+            break;
+        case DLL_THREAD_DETACH:
+            if (_pr_initialized) {
+                me = _MD_GET_ATTACHED_THREAD();
+                if ((me != NULL) && (me->flags & _PR_ATTACHED))
+                    _PRI_DetachThread();
+            }
+            break;
+        case DLL_PROCESS_DETACH:
+            break;
+    }
+    return TRUE;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntgc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntgc.c
new file mode 100644
index 0000000..e12b30d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntgc.c
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * GC related routines
+ *
+ */
+#include <windows.h>
+#include "primpl.h"
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) 
+{
+#if defined(_X86_)
+    CONTEXT context;
+    context.ContextFlags = CONTEXT_INTEGER;
+
+    if (_PR_IS_NATIVE_THREAD(t)) {
+        context.ContextFlags |= CONTEXT_CONTROL;
+        if (GetThreadContext(t->md.handle, &context)) {
+            t->md.gcContext[0] = context.Eax;
+            t->md.gcContext[1] = context.Ebx;
+            t->md.gcContext[2] = context.Ecx;
+            t->md.gcContext[3] = context.Edx;
+            t->md.gcContext[4] = context.Esi;
+            t->md.gcContext[5] = context.Edi;
+            t->md.gcContext[6] = context.Esp;
+            t->md.gcContext[7] = context.Ebp;
+            *np = PR_NUM_GCREGS;
+        } else {
+            PR_ASSERT(0);/* XXX */
+        }
+    } else {
+        /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+         *
+         * This code is extremely machine dependant and completely 
+         * undocumented by MS.  Its only known to work experimentally.  
+         * Ready for a walk on the wild * side?
+         *
+         * WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
+
+#if !defined WIN95 // Win95 does not have fibers
+        int *fiberData = t->md.fiber_id;
+
+        /* I found these offsets by disassembling SwitchToFiber().
+         * Are your palms sweating yet?
+         */
+
+        /* 
+        ** EAX is on the stack (ESP+0)
+        ** EDX is on the stack (ESP+4)
+        ** ECX is on the stack (ESP+8)
+        */
+        t->md.gcContext[0] = 0;                /* context.Eax */
+        t->md.gcContext[1] = fiberData[0x2e];  /* context.Ebx */
+        t->md.gcContext[2] = 0;                /* context.Ecx */
+        t->md.gcContext[2] = 0;                /* context.Edx */
+        t->md.gcContext[4] = fiberData[0x2d];  /* context.Esi */
+        t->md.gcContext[5] = fiberData[0x2c];  /* context.Edi */
+        t->md.gcContext[6] = fiberData[0x36];  /* context.Esp */
+        t->md.gcContext[7] = fiberData[0x32];  /* context.Ebp */
+        *np = PR_NUM_GCREGS;
+#endif
+    }
+    return (PRWord *)&t->md.gcContext;
+#else
+    PR_NOT_REACHED("not implemented");
+    return NULL;
+#endif /* defined(_X86_) */
+}
+
+/* This function is not used right now, but is left as a reference.
+ * If you ever need to get the fiberID from the currently running fiber, 
+ * this is it.
+ */
+void *
+GetMyFiberID()
+{
+#if defined(_X86_) && !defined(__MINGW32__)
+    void *fiberData;
+
+    /* A pointer to our tib entry is found at FS:[18]
+     * At offset 10h is the fiberData pointer.  The context of the 
+     * fiber is stored in there.  
+     */
+    __asm {
+        mov    EDX, FS:[18h]
+        mov    EAX, DWORD PTR [EDX+10h]
+        mov    [fiberData], EAX
+    }
+  
+    return fiberData;
+#else
+    PR_NOT_REACHED("not implemented");
+    return NULL;
+#endif /* defined(_X86_) */
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntinrval.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntinrval.c
new file mode 100644
index 0000000..f96c27b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntinrval.c
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * NT interval timers
+ *
+ */
+
+#include "primpl.h"
+
+#ifdef WINCE
+typedef DWORD (*IntervalFuncType)(void);
+static IntervalFuncType intervalFunc;
+#endif
+
+void
+_PR_MD_INTERVAL_INIT()
+{
+#ifdef WINCE
+    HMODULE mmtimerlib = LoadLibraryW(L"mmtimer.dll");  /* XXX leaked! */
+    if (mmtimerlib) {
+        intervalFunc = (IntervalFuncType)GetProcAddress(mmtimerlib,
+                                                        "timeGetTime");
+    } else {
+        intervalFunc = &GetTickCount;
+    }
+#endif
+}
+
+PRIntervalTime 
+_PR_MD_GET_INTERVAL()
+{
+    /* milliseconds since system start */
+#ifdef WINCE
+    return (*intervalFunc)();
+#else
+    return timeGetTime();
+#endif
+}
+
+PRIntervalTime 
+_PR_MD_INTERVAL_PER_SEC()
+{
+    return 1000;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntio.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntio.c
new file mode 100644
index 0000000..4653503
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntio.c
@@ -0,0 +1,4642 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Masayuki Nakano <masayuki@d-toybox.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Windows NT IO module
+ *
+ * This module handles IO for LOCAL_SCOPE and GLOBAL_SCOPE threads.
+ * For LOCAL_SCOPE threads, we're using NT fibers.  For GLOBAL_SCOPE threads
+ * we're using NT-native threads.
+ *
+ * When doing IO, we want to use completion ports for optimal performance 
+ * with fibers.  But if we use completion ports for all IO, it is difficult
+ * to project a blocking model with GLOBAL_SCOPE threads.  To handle this
+ * we create an extra thread for completing IO for GLOBAL_SCOPE threads.
+ * We don't really want to complete IO on a separate thread for LOCAL_SCOPE
+ * threads because it means extra context switches, which are really slow
+ * on NT...  Since we're using a single completion port, some IO will
+ * 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_INET_array[RECYCLE_SIZE];
+static PRInt32               _pr_recycle_INET_tail = 0; 
+static PRInt32               _pr_recycle_INET6_array[RECYCLE_SIZE];
+static PRInt32               _pr_recycle_INET6_tail = 0; 
+
+__declspec(thread) PRThread *_pr_io_restarted_io = NULL;
+DWORD _pr_io_restartedIOIndex;  /* The thread local storage slot for each
+                                 * thread is initialized to NULL. */
+
+PRBool                       _nt_version_gets_lockfile_completion;
+
+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
+};
+
+static PRBool IsPrevCharSlash(const char *str, const char *current);
+
+#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);
+
+static PROsfd _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr *addr, int *addrlen, PRIntervalTime);
+static PRInt32 _nt_nonblock_connect(PRFileDesc *fd, struct sockaddr *addr, int addrlen, PRIntervalTime);
+static PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime);
+static PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
+static PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime);
+static PRInt32 _nt_nonblock_sendto(PRFileDesc *, const char *, int, const struct sockaddr *, int, PRIntervalTime);
+static PRInt32 _nt_nonblock_recvfrom(PRFileDesc *, char *, int, struct sockaddr *, int *, PRIntervalTime);
+
+/*
+ * We cannot associate a fd (a socket) with an I/O completion port
+ * if the fd is nonblocking or inheritable.
+ *
+ * Nonblocking socket I/O won't work if the socket is associated with
+ * an I/O completion port.
+ *
+ * An inheritable fd cannot be associated with an I/O completion port
+ * because the completion notification of async I/O initiated by the
+ * child process is still posted to the I/O completion port in the
+ * parent process. 
+ */
+#define _NT_USE_NB_IO(fd) \
+    ((fd)->secret->nonblocking || (fd)->secret->inheritable == _PR_TRI_TRUE)
+
+/*
+ * UDP support
+ * 
+ * UDP is supported on NT by the continuation thread mechanism.
+ * The code is borrowed from ptio.c in pthreads nspr, hence the
+ * PT and pt prefixes.  This mechanism is in fact general and
+ * not limited to UDP.  For now, only UDP's recvfrom and sendto
+ * go through the continuation thread if they get WSAEWOULDBLOCK
+ * on first try.  Recv and send on a connected UDP socket still
+ * goes through asychronous io.
+ */
+
+#define PT_DEFAULT_SELECT_MSEC 100
+
+typedef struct pt_Continuation pt_Continuation;
+typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revent);
+
+typedef enum pr_ContuationStatus
+{
+    pt_continuation_sumbitted,
+    pt_continuation_inprogress,
+    pt_continuation_abort,
+    pt_continuation_done
+} pr_ContuationStatus;
+
+struct pt_Continuation
+{
+    /* These objects are linked in ascending timeout order */
+    pt_Continuation *next, *prev;           /* self linked list of these things */
+
+    /* The building of the continuation operation */
+    ContinuationFn function;                /* what function to continue */
+    union { SOCKET osfd; } arg1;            /* #1 - the op's fd */
+    union { void* buffer; } arg2;           /* #2 - primary transfer buffer */
+    union { PRIntn amount; } arg3;          /* #3 - size of 'buffer' */
+    union { PRIntn flags; } arg4;           /* #4 - read/write flags */
+    union { PRNetAddr *addr; } arg5;        /* #5 - send/recv address */
+    
+    PRIntervalTime timeout;                 /* representation of the timeout */
+
+    PRIntn event;                           /* flags for select()'s events */
+
+    /*
+    ** The representation and notification of the results of the operation.
+    ** These function can either return an int return code or a pointer to
+    ** some object.
+    */
+    union { PRIntn code; void *object; } result;
+
+    PRIntn syserrno;                        /* in case it failed, why (errno) */
+    pr_ContuationStatus status;             /* the status of the operation */
+    PRCondVar *complete;                    /* to notify the initiating thread */
+};
+
+static struct pt_TimedQueue
+{
+    PRLock *ml;                             /* a little protection */
+    PRThread *thread;                       /* internal thread's identification */
+    PRCondVar *new_op;                      /* new operation supplied */
+    PRCondVar *finish_op;                   /* an existing operation finished */
+    PRUintn op_count;                       /* number of operations in the list */
+    pt_Continuation *head, *tail;           /* head/tail of list of operations */
+
+    pt_Continuation *op;                    /* timed operation furthest in future */
+    PRIntervalTime epoch;                   /* the epoch of 'timed' */
+} pt_tq;
+
+#if defined(DEBUG)
+static struct pt_debug_s
+{
+    PRIntn predictionsFoiled;
+    PRIntn pollingListMax;
+    PRIntn continuationsServed;
+} pt_debug;
+#endif  /* DEBUG */
+
+static void ContinuationThread(void *arg);
+static PRInt32 pt_SendTo(
+    SOCKET osfd, const void *buf,
+    PRInt32 amount, PRInt32 flags, const PRNetAddr *addr,
+    PRIntn addrlen, PRIntervalTime timeout);
+static PRInt32 pt_RecvFrom(SOCKET osfd, void *buf, PRInt32 amount,
+    PRInt32 flags, PRNetAddr *addr, PRIntn *addr_len, PRIntervalTime timeout);
+
+
+/* The key returned from GetQueuedCompletionStatus() is used to determine what
+ * type of completion we have.  We differentiate between IO completions and
+ * CVAR completions.
+ */
+#define KEY_IO              0xaaaaaaaa
+#define KEY_CVAR            0xbbbbbbbb
+
+PRInt32
+_PR_MD_PAUSE_CPU(PRIntervalTime ticks)
+{
+    int awoken = 0;
+    unsigned long bytes, key;
+    int rv;
+    LPOVERLAPPED olp;
+    _MDOverlapped *mdOlp;
+    PRUint32 timeout;
+
+    if (_nt_idleCount > 0) {
+        PRThread *deadThread;
+
+        _MD_LOCK(&_nt_idleLock);
+        while( !PR_CLIST_IS_EMPTY(&_nt_idleList) ) {
+            deadThread = _PR_THREAD_PTR(PR_LIST_HEAD(&_nt_idleList));
+            PR_REMOVE_LINK(&deadThread->links);
+
+            PR_ASSERT(deadThread->state == _PR_DEAD_STATE);
+
+            /* XXXMB - cleanup to do here? */
+            if ( !_PR_IS_NATIVE_THREAD(deadThread) ){
+                /* Spinlock while user thread is still running.
+                 * There is no way to use a condition variable here. The thread
+                 * is dead, and we have to wait until we switch off the dead 
+                 * thread before we can kill the fiber completely.
+                 */
+                while ( deadThread->no_sched)
+                    ;
+
+                DeleteFiber(deadThread->md.fiber_id);
+            }
+            memset(deadThread, 0xa, sizeof(PRThread)); /* debugging */
+            if (!deadThread->threadAllocatedOnStack)
+                PR_DELETE(deadThread);
+            _nt_idleCount--;
+        }
+        _MD_UNLOCK(&_nt_idleLock);
+    }
+
+    if (ticks == PR_INTERVAL_NO_TIMEOUT)
+#if 0
+        timeout = INFINITE;
+#else
+    /*
+     * temporary hack to poll the runq every 5 seconds because of bug in
+     * native threads creating user threads and not poking the right cpu.
+     *
+     * A local thread that was interrupted is bound to its current
+     * cpu but there is no easy way for the interrupter to poke the
+     * right cpu.  This is a hack to poll the runq every 5 seconds.
+     */
+        timeout = 5000;
+#endif
+    else 
+        timeout = PR_IntervalToMilliseconds(ticks);
+
+    /*
+     * The idea of looping here is to complete as many IOs as possible before
+     * returning.  This should minimize trips to the idle thread.
+     */
+    while(1) {
+        rv = GetQueuedCompletionStatus(
+                _pr_completion_port,
+                &bytes,
+                &key,
+                &olp,
+                timeout); 
+        if (rv == 0 && olp == NULL) {
+            /* Error in GetQueuedCompetionStatus */
+            if (GetLastError() != WAIT_TIMEOUT) {
+                /* ARGH - what can we do here? Log an error? XXXMB */
+                return -1;
+            } else {
+                /* If awoken == 0, then we just had a timeout */
+                return awoken;
+            }
+        }
+
+        if (olp == NULL) 
+            return 0;
+
+        mdOlp = (_MDOverlapped *)olp;
+
+        if (mdOlp->ioModel == _MD_MultiWaitIO) {
+            PRRecvWait *desc;
+            PRWaitGroup *group;
+            PRThread *thred = NULL;
+            PRMWStatus mwstatus;
+
+            desc = mdOlp->data.mw.desc;
+            PR_ASSERT(desc != NULL);
+            mwstatus = rv ? PR_MW_SUCCESS : PR_MW_FAILURE;
+            if (InterlockedCompareExchange((PVOID *)&desc->outcome,
+                    (PVOID)mwstatus, (PVOID)PR_MW_PENDING)
+                    == (PVOID)PR_MW_PENDING) {
+                if (mwstatus == PR_MW_SUCCESS) {
+                    desc->bytesRecv = bytes;
+                } else {
+                    mdOlp->data.mw.error = GetLastError();
+                }
+            }
+            group = mdOlp->data.mw.group;
+            PR_ASSERT(group != NULL);
+
+            _PR_MD_LOCK(&group->mdlock);
+            PR_APPEND_LINK(&mdOlp->data.mw.links, &group->io_ready);
+            PR_ASSERT(desc->fd != NULL);
+            NT_HashRemoveInternal(group, desc->fd);
+            if (!PR_CLIST_IS_EMPTY(&group->wait_list)) {
+                thred = _PR_THREAD_CONDQ_PTR(PR_LIST_HEAD(&group->wait_list));
+                PR_REMOVE_LINK(&thred->waitQLinks);
+            }
+            _PR_MD_UNLOCK(&group->mdlock);
+
+            if (thred) {
+                if (!_PR_IS_NATIVE_THREAD(thred)) {
+                    int pri = thred->priority;
+                    _PRCPU *lockedCPU = _PR_MD_CURRENT_CPU();
+                    _PR_THREAD_LOCK(thred);
+                    if (thred->flags & _PR_ON_PAUSEQ) {
+                        _PR_SLEEPQ_LOCK(thred->cpu);
+                        _PR_DEL_SLEEPQ(thred, PR_TRUE);
+                        _PR_SLEEPQ_UNLOCK(thred->cpu);
+                        _PR_THREAD_UNLOCK(thred);
+                        thred->cpu = lockedCPU;
+                        thred->state = _PR_RUNNABLE;
+                        _PR_RUNQ_LOCK(lockedCPU);
+                        _PR_ADD_RUNQ(thred, lockedCPU, pri);
+                        _PR_RUNQ_UNLOCK(lockedCPU);
+                    } else {
+                        /*
+                         * The thread was just interrupted and moved
+                         * from the pause queue to the run queue.
+                         */
+                        _PR_THREAD_UNLOCK(thred);
+                    }
+                } else {
+                    _PR_THREAD_LOCK(thred);
+                    thred->state = _PR_RUNNABLE;
+                    _PR_THREAD_UNLOCK(thred);
+                    ReleaseSemaphore(thred->md.blocked_sema, 1, NULL);
+                }
+            }
+        } else {
+            PRThread *completed_io;
+
+            PR_ASSERT(mdOlp->ioModel == _MD_BlockingIO);
+            completed_io = _PR_THREAD_MD_TO_PTR(mdOlp->data.mdThread);
+            completed_io->md.blocked_io_status = rv;
+            if (rv == 0)
+                completed_io->md.blocked_io_error = GetLastError();
+            completed_io->md.blocked_io_bytes = bytes;
+
+            if ( !_PR_IS_NATIVE_THREAD(completed_io) ) {
+                int pri = completed_io->priority;
+                _PRCPU *lockedCPU = _PR_MD_CURRENT_CPU();
+
+                /* The KEY_CVAR notification only occurs when a native thread
+                 * is notifying a user thread.  For user-user notifications
+                 * the wakeup occurs by having the notifier place the thread 
+                 * on the runq directly; for native-native notifications the
+                 * wakeup occurs by calling ReleaseSemaphore.
+                 */
+                if ( key == KEY_CVAR ) {
+                    PR_ASSERT(completed_io->io_pending == PR_FALSE);
+                    PR_ASSERT(completed_io->io_suspended == PR_FALSE);
+                    PR_ASSERT(completed_io->md.thr_bound_cpu == NULL);
+
+                    /* Thread has already been deleted from sleepQ */
+
+                    /* Switch CPU and add to runQ */
+                    completed_io->cpu = lockedCPU;
+                    completed_io->state = _PR_RUNNABLE;
+                    _PR_RUNQ_LOCK(lockedCPU);
+                    _PR_ADD_RUNQ(completed_io, lockedCPU, pri);
+                    _PR_RUNQ_UNLOCK(lockedCPU);
+                } else {
+                    PR_ASSERT(key == KEY_IO);
+                    PR_ASSERT(completed_io->io_pending == PR_TRUE);
+
+                    _PR_THREAD_LOCK(completed_io);
+
+                    completed_io->io_pending = PR_FALSE;
+
+                    /* If io_suspended is true, then this IO has already resumed.
+                     * We don't need to do anything; because the thread is
+                     * already running.
+                     */
+                    if (completed_io->io_suspended == PR_FALSE) {
+                        if (completed_io->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) {
+                            _PR_SLEEPQ_LOCK(completed_io->cpu);
+                            _PR_DEL_SLEEPQ(completed_io, PR_TRUE);
+                            _PR_SLEEPQ_UNLOCK(completed_io->cpu);
+
+                            _PR_THREAD_UNLOCK(completed_io);
+
+						/*
+						 * If an I/O operation is suspended, the thread
+						 * must be running on the same cpu on which the
+						 * I/O operation was issued.
+						 */
+						PR_ASSERT(!completed_io->md.thr_bound_cpu ||
+					(completed_io->cpu == completed_io->md.thr_bound_cpu));
+
+							if (!completed_io->md.thr_bound_cpu)
+                            	completed_io->cpu = lockedCPU;
+                            completed_io->state = _PR_RUNNABLE;
+                            _PR_RUNQ_LOCK(completed_io->cpu);
+                            _PR_ADD_RUNQ(completed_io, completed_io->cpu, pri);
+                            _PR_RUNQ_UNLOCK(completed_io->cpu);
+                        } else {
+                            _PR_THREAD_UNLOCK(completed_io);
+                        }
+                    } else {
+                        _PR_THREAD_UNLOCK(completed_io);
+                    }
+                }
+            } else {
+                /* For native threads, they are only notified through this loop
+                 * when completing IO.  So, don't worry about this being a CVAR
+                 * notification, because that is not possible.
+                 */
+                _PR_THREAD_LOCK(completed_io);
+                completed_io->io_pending = PR_FALSE;
+                if (completed_io->io_suspended == PR_FALSE) {
+                    completed_io->state = _PR_RUNNABLE;
+                    _PR_THREAD_UNLOCK(completed_io);
+                    rv = ReleaseSemaphore(completed_io->md.blocked_sema,
+                            1, NULL);
+                    PR_ASSERT(0 != rv);
+                } else {
+                    _PR_THREAD_UNLOCK(completed_io);
+                }
+            }
+        }
+
+        awoken++;
+        timeout = 0;   /* Don't block on subsequent trips through the loop */
+    }
+
+    /* never reached */
+    return 0;
+}
+
+static PRStatus
+_native_thread_md_wait(PRThread *thread, PRIntervalTime ticks)
+{
+    DWORD rv;
+	PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+		INFINITE : PR_IntervalToMilliseconds(ticks);
+
+	/*
+	 * thread waiting for a cvar or a joining thread
+	 */
+	rv = WaitForSingleObject(thread->md.blocked_sema, msecs);
+	switch(rv) {
+		case WAIT_OBJECT_0:
+			return PR_SUCCESS;
+			break;
+		case WAIT_TIMEOUT:
+			_PR_THREAD_LOCK(thread);
+			PR_ASSERT (thread->state != _PR_IO_WAIT);
+			if (thread->wait.cvar != NULL) {
+				PR_ASSERT(thread->state == _PR_COND_WAIT);
+				thread->wait.cvar = NULL;
+				thread->state = _PR_RUNNING;
+				_PR_THREAD_UNLOCK(thread);
+			} else {
+				/* The CVAR was notified just as the timeout
+				 * occurred.  This left the semaphore in the
+				 * signaled state.  Call WaitForSingleObject()
+				 * to clear the semaphore.
+				 */
+				_PR_THREAD_UNLOCK(thread);
+				rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+				PR_ASSERT(rv == WAIT_OBJECT_0);
+			}
+			return PR_SUCCESS;
+			break;
+		default:
+			return PR_FAILURE;
+			break;
+	}
+
+    return PR_SUCCESS;
+}
+
+PRStatus
+_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    DWORD rv;
+
+	if (_native_threads_only) {
+		return(_native_thread_md_wait(thread, ticks));
+	}
+    if ( thread->flags & _PR_GLOBAL_SCOPE ) {
+        PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+            INFINITE : PR_IntervalToMilliseconds(ticks);
+        rv = WaitForSingleObject(thread->md.blocked_sema, msecs);
+        switch(rv) {
+            case WAIT_OBJECT_0:
+                return PR_SUCCESS;
+                break;
+            case WAIT_TIMEOUT:
+                _PR_THREAD_LOCK(thread);
+                if (thread->state == _PR_IO_WAIT) {
+                    if (thread->io_pending == PR_TRUE) {
+                        thread->state = _PR_RUNNING;
+                        thread->io_suspended = PR_TRUE;
+                        _PR_THREAD_UNLOCK(thread);
+                    } else {
+                        /* The IO completed just at the same time the timeout
+                         * occurred.  This left the semaphore in the signaled
+                         * state.  Call WaitForSingleObject() to clear the
+                         * semaphore.
+                         */
+                        _PR_THREAD_UNLOCK(thread);
+                        rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+                        PR_ASSERT(rv == WAIT_OBJECT_0);
+                    }
+                } else {
+                    if (thread->wait.cvar != NULL) {
+                        PR_ASSERT(thread->state == _PR_COND_WAIT);
+                        thread->wait.cvar = NULL;
+                        thread->state = _PR_RUNNING;
+                        _PR_THREAD_UNLOCK(thread);
+                    } else {
+                        /* The CVAR was notified just as the timeout
+                         * occurred.  This left the semaphore in the
+                         * signaled state.  Call WaitForSingleObject()
+                         * to clear the semaphore.
+                         */
+                        _PR_THREAD_UNLOCK(thread);
+                        rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+                        PR_ASSERT(rv == WAIT_OBJECT_0);
+                    }
+                }
+                return PR_SUCCESS;
+                break;
+            default:
+                return PR_FAILURE;
+                break;
+        }
+    } else {
+        PRInt32 is;
+
+        _PR_INTSOFF(is);
+        _PR_MD_SWITCH_CONTEXT(thread);
+    }
+
+    return PR_SUCCESS;
+}
+
+static void
+_native_thread_io_nowait(
+    PRThread *thread,
+    int rv,
+    int bytes)
+{
+    int rc;
+
+    PR_ASSERT(rv != 0);
+    _PR_THREAD_LOCK(thread);
+    if (thread->state == _PR_IO_WAIT) {
+        PR_ASSERT(thread->io_suspended == PR_FALSE);
+        PR_ASSERT(thread->io_pending == PR_TRUE);
+        thread->state = _PR_RUNNING;
+        thread->io_pending = PR_FALSE;
+        _PR_THREAD_UNLOCK(thread);
+    } else {
+        /* The IO completed just at the same time the
+         * thread was interrupted. This left the semaphore
+         * in the signaled state. Call WaitForSingleObject()
+         * to clear the semaphore.
+         */
+        PR_ASSERT(thread->io_suspended == PR_TRUE);
+        PR_ASSERT(thread->io_pending == PR_TRUE);
+        thread->io_pending = PR_FALSE;
+        _PR_THREAD_UNLOCK(thread);
+        rc = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+        PR_ASSERT(rc == WAIT_OBJECT_0);
+    }
+
+    thread->md.blocked_io_status = rv;
+    thread->md.blocked_io_bytes = bytes;
+    rc = ResetEvent(thread->md.thr_event);
+    PR_ASSERT(rc != 0);
+    return;
+}
+
+static PRStatus
+_native_thread_io_wait(PRThread *thread, PRIntervalTime ticks)
+{
+    DWORD rv, bytes;
+#define _NATIVE_IO_WAIT_HANDLES		2
+#define _NATIVE_WAKEUP_EVENT_INDEX	0
+#define _NATIVE_IO_EVENT_INDEX		1
+
+	HANDLE wait_handles[_NATIVE_IO_WAIT_HANDLES];
+
+	PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+		INFINITE : PR_IntervalToMilliseconds(ticks);
+
+    PR_ASSERT(thread->flags & _PR_GLOBAL_SCOPE);
+
+	wait_handles[0] = thread->md.blocked_sema;
+	wait_handles[1] = thread->md.thr_event;
+	rv = WaitForMultipleObjects(_NATIVE_IO_WAIT_HANDLES, wait_handles,
+										FALSE, msecs);
+
+	switch(rv) {
+		case WAIT_OBJECT_0 + _NATIVE_IO_EVENT_INDEX:
+			/*
+			 * I/O op completed
+			 */
+			_PR_THREAD_LOCK(thread);
+			if (thread->state == _PR_IO_WAIT) {
+
+				PR_ASSERT(thread->io_suspended == PR_FALSE);
+				PR_ASSERT(thread->io_pending == PR_TRUE);
+				thread->state = _PR_RUNNING;
+				thread->io_pending = PR_FALSE;
+				_PR_THREAD_UNLOCK(thread);
+			} else {
+				/* The IO completed just at the same time the
+				 * thread was interrupted. This led to us being
+				 * notified twice. Call WaitForSingleObject()
+				 * to clear the semaphore.
+				 */
+				PR_ASSERT(thread->io_suspended == PR_TRUE);
+				PR_ASSERT(thread->io_pending == PR_TRUE);
+				thread->io_pending = PR_FALSE;
+				_PR_THREAD_UNLOCK(thread);
+				rv = WaitForSingleObject(thread->md.blocked_sema,
+							INFINITE);
+				PR_ASSERT(rv == WAIT_OBJECT_0);
+			}
+
+			rv = GetOverlappedResult((HANDLE) thread->io_fd,
+				&thread->md.overlapped.overlapped, &bytes, FALSE);
+
+			thread->md.blocked_io_status = rv;
+			if (rv != 0) {
+				thread->md.blocked_io_bytes = bytes;
+			} else {
+				thread->md.blocked_io_error = GetLastError();
+				PR_ASSERT(ERROR_IO_PENDING != thread->md.blocked_io_error);
+			}
+			rv = ResetEvent(thread->md.thr_event);
+			PR_ASSERT(rv != 0);
+			break;
+		case WAIT_OBJECT_0 + _NATIVE_WAKEUP_EVENT_INDEX:
+			/*
+			 * I/O interrupted; 
+			 */
+#ifdef DEBUG
+			_PR_THREAD_LOCK(thread);
+			PR_ASSERT(thread->io_suspended == PR_TRUE);
+			_PR_THREAD_UNLOCK(thread);
+#endif
+			break;
+		case WAIT_TIMEOUT:
+			_PR_THREAD_LOCK(thread);
+			if (thread->state == _PR_IO_WAIT) {
+				thread->state = _PR_RUNNING;
+				thread->io_suspended = PR_TRUE;
+				_PR_THREAD_UNLOCK(thread);
+			} else {
+				/*
+				 * The thread was interrupted just as the timeout
+				 * occurred. This left the semaphore in the signaled
+				 * state. Call WaitForSingleObject() to clear the
+				 * semaphore.
+				 */
+				PR_ASSERT(thread->io_suspended == PR_TRUE);
+				_PR_THREAD_UNLOCK(thread);
+				rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+				PR_ASSERT(rv == WAIT_OBJECT_0);
+			}
+			break;
+		default:
+			return PR_FAILURE;
+			break;
+	}
+
+    return PR_SUCCESS;
+}
+
+
+static PRStatus
+_NT_IO_WAIT(PRThread *thread, PRIntervalTime timeout)
+{
+    PRBool fWait = PR_TRUE;
+
+	if (_native_threads_only) {
+		return(_native_thread_io_wait(thread, timeout));
+	}
+    if (!_PR_IS_NATIVE_THREAD(thread))  {
+
+        _PR_THREAD_LOCK(thread);
+
+        /* The IO may have already completed; if so, don't add to sleepQ, 
+         * since we are already on the runQ!
+         */
+        if (thread->io_pending == PR_TRUE) {
+            _PR_SLEEPQ_LOCK(thread->cpu);
+            _PR_ADD_SLEEPQ(thread, timeout);
+            _PR_SLEEPQ_UNLOCK(thread->cpu);
+        } else
+            fWait = PR_FALSE;
+        _PR_THREAD_UNLOCK(thread);
+    }
+    if (fWait)
+        return _PR_MD_WAIT(thread, timeout);
+    else
+        return PR_SUCCESS;
+}
+
+/*
+ * Unblock threads waiting for I/O
+ * used when interrupting threads
+ *
+ * NOTE: The thread lock should held when this function is called.
+ * On return, the thread lock is released.
+ */
+void _PR_Unblock_IO_Wait(PRThread *thr)
+{
+    PRStatus rv;
+    _PRCPU *cpu = thr->cpu;
+ 
+    PR_ASSERT(thr->state == _PR_IO_WAIT);
+	/*
+	 * A thread for which an I/O timed out or was interrupted cannot be
+	 * in an IO_WAIT state except as a result of calling PR_Close or
+	 * PR_NT_CancelIo for the FD. For these two cases, _PR_IO_WAIT state
+	 * is not interruptible
+	 */
+	if (thr->md.interrupt_disabled == PR_TRUE) {
+    	_PR_THREAD_UNLOCK(thr);
+		return;
+	}
+    thr->io_suspended = PR_TRUE;
+    thr->state = _PR_RUNNABLE;
+
+    if (!_PR_IS_NATIVE_THREAD(thr)) {
+        PRThread *me = _PR_MD_CURRENT_THREAD();
+        PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ));
+        _PR_SLEEPQ_LOCK(cpu);
+        _PR_DEL_SLEEPQ(thr, PR_TRUE);
+        _PR_SLEEPQ_UNLOCK(cpu);
+		/*
+		 * this thread will continue to run on the same cpu until the
+		 * I/O is aborted by closing the FD or calling CancelIO
+		 */
+		thr->md.thr_bound_cpu = cpu;
+
+        PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD));
+        _PR_AddThreadToRunQ(me, thr);
+    }
+    _PR_THREAD_UNLOCK(thr);
+    rv = _PR_MD_WAKEUP_WAITER(thr);
+    PR_ASSERT(PR_SUCCESS == rv);
+}
+
+/* Resume an outstanding IO; requires that after the switch, we disable */
+static PRStatus
+_NT_ResumeIO(PRThread *thread, PRIntervalTime ticks)
+{
+    PRBool fWait = PR_TRUE;
+
+    if (!_PR_IS_NATIVE_THREAD(thread)) {
+        if (_pr_use_static_tls) {
+            _pr_io_restarted_io = thread;
+        } else {
+            TlsSetValue(_pr_io_restartedIOIndex, thread);
+        }
+    } else {
+        _PR_THREAD_LOCK(thread);
+        if (!thread->io_pending)
+            fWait = PR_FALSE;
+        thread->io_suspended = PR_FALSE;
+            
+        _PR_THREAD_UNLOCK(thread);
+    }
+    /* We don't put ourselves back on the sleepQ yet; until we 
+     * set the suspended bit to false, we can't do that.  Just save
+     * the sleep time here, and then continue.  The restarted_io handler
+     * will add us to the sleepQ if needed.
+     */
+    thread->sleep = ticks;
+
+    if (fWait) {
+        if (!_PR_IS_NATIVE_THREAD(thread))
+            return _PR_MD_WAIT(thread, ticks);
+        else
+            return _NT_IO_WAIT(thread, ticks);
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus
+_PR_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread == NULL) {
+        /* If thread is NULL, we aren't waking a thread, we're just poking
+         * idle thread 
+         */
+        if ( PostQueuedCompletionStatus(_pr_completion_port, 0, 
+            KEY_CVAR, NULL) == FALSE) 
+            return PR_FAILURE;
+        return PR_SUCCESS;
+    }
+
+    if ( _PR_IS_NATIVE_THREAD(thread) ) {
+        if (ReleaseSemaphore(thread->md.blocked_sema, 1, NULL) == FALSE)
+            return PR_FAILURE;
+        else
+            return PR_SUCCESS;
+    } else {
+        PRThread *me = _PR_MD_CURRENT_THREAD();
+
+        /* When a Native thread has to awaken a user thread, it has to poke
+         * the completion port because all user threads might be idle, and
+         * thus the CPUs are just waiting for a completion.  
+         *
+         * XXXMB - can we know when we are truely idle (and not checking 
+         *         the runq)?
+         */
+        if ((_PR_IS_NATIVE_THREAD(me) || (thread->cpu != me->cpu)) &&
+                (!thread->md.thr_bound_cpu)) {
+            /* The thread should not be in any queue */
+            PR_ASSERT(thread->queueCount == 0);
+            if ( PostQueuedCompletionStatus(_pr_completion_port, 0, 
+                KEY_CVAR, &(thread->md.overlapped.overlapped)) == FALSE) 
+                return PR_FAILURE;
+        }
+        return PR_SUCCESS;
+    }
+}
+
+void
+_PR_MD_INIT_IO()
+{
+    WORD WSAVersion = 0x0101;
+    WSADATA WSAData;
+    int err;
+    OSVERSIONINFO OSversion;
+
+    err = WSAStartup( WSAVersion, &WSAData );
+    PR_ASSERT(0 == err);
+                                                      
+    _pr_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 
+                                                 NULL, 
+                                                 0, 
+                                                 0);
+ 
+    _MD_NEW_LOCK(&_pr_recycle_lock);
+    _MD_NEW_LOCK(&_pr_ioq_lock);
+
+    OSversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    if (GetVersionEx(&OSversion)) {
+        _nt_version_gets_lockfile_completion = PR_FALSE;
+        if (OSversion.dwMajorVersion >= 4) {
+            _nt_version_gets_lockfile_completion = PR_TRUE;
+        }
+    } else 
+        PR_ASSERT(0);
+
+#ifdef _NEED_351_FILE_LOCKING_HACK
+    IsFileLocalInit();
+#endif /* _NEED_351_FILE_LOCKING_HACK */
+
+    /*
+     * UDP support: start up the continuation thread
+     */
+
+    pt_tq.op_count = 0;
+    pt_tq.head = pt_tq.tail = NULL;
+    pt_tq.ml = PR_NewLock();
+    PR_ASSERT(NULL != pt_tq.ml);
+    pt_tq.new_op = PR_NewCondVar(pt_tq.ml);
+    PR_ASSERT(NULL != pt_tq.new_op);
+#if defined(DEBUG)
+    memset(&pt_debug, 0, sizeof(struct pt_debug_s));
+#endif
+
+    pt_tq.thread = PR_CreateThread(
+        PR_SYSTEM_THREAD, ContinuationThread, NULL,
+        PR_PRIORITY_URGENT, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    PR_ASSERT(NULL != pt_tq.thread);
+
+#ifdef DEBUG
+    /* Doublecheck _pr_filetime_offset's hard-coded value is correct. */
+    {
+        SYSTEMTIME systime;
+        union {
+           PRTime prt;
+           FILETIME ft;
+        } filetime;
+        BOOL rv;
+
+        systime.wYear = 1970;
+        systime.wMonth = 1;
+        /* wDayOfWeek is ignored */
+        systime.wDay = 1;
+        systime.wHour = 0;
+        systime.wMinute = 0;
+        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.
+ */
+static SOCKET
+_md_get_recycled_socket(int af)
+{
+    SOCKET rv;
+
+    _MD_LOCK(&_pr_recycle_lock);
+    if (af == AF_INET && _pr_recycle_INET_tail) {
+        _pr_recycle_INET_tail--;
+        rv = _pr_recycle_INET_array[_pr_recycle_INET_tail];
+        _MD_UNLOCK(&_pr_recycle_lock);
+        return rv;
+    }
+    if (af == AF_INET6 && _pr_recycle_INET6_tail) {
+        _pr_recycle_INET6_tail--;
+        rv = _pr_recycle_INET6_array[_pr_recycle_INET6_tail];
+        _MD_UNLOCK(&_pr_recycle_lock);
+        return rv;
+    }
+    _MD_UNLOCK(&_pr_recycle_lock);
+
+    rv = _PR_MD_SOCKET(af, SOCK_STREAM, 0);
+    if (rv != INVALID_SOCKET && _md_Associate((HANDLE)rv) == 0) {
+        closesocket(rv);
+        return INVALID_SOCKET;
+    }
+    return rv;
+}
+
+/* _md_put_recycled_socket()
+ * Add a socket to the recycle bin.
+ */
+static void
+_md_put_recycled_socket(SOCKET newsock, int af)
+{
+    PR_ASSERT(_pr_recycle_INET_tail >= 0);
+    PR_ASSERT(_pr_recycle_INET6_tail >= 0);
+
+    _MD_LOCK(&_pr_recycle_lock);
+    if (af == AF_INET && _pr_recycle_INET_tail < RECYCLE_SIZE) {
+        _pr_recycle_INET_array[_pr_recycle_INET_tail] = newsock;
+        _pr_recycle_INET_tail++;
+        _MD_UNLOCK(&_pr_recycle_lock);
+    } else if (af == AF_INET6 && _pr_recycle_INET6_tail < RECYCLE_SIZE) {
+        _pr_recycle_INET6_array[_pr_recycle_INET6_tail] = newsock;
+        _pr_recycle_INET6_tail++;
+        _MD_UNLOCK(&_pr_recycle_lock);
+    } else {
+        _MD_UNLOCK(&_pr_recycle_lock);
+        closesocket(newsock);
+    }
+ 
+    return;
+}
+
+/* _md_Associate()
+ * Associates a file with the completion port.
+ * Returns 0 on failure, 1 on success.
+ */
+PRInt32
+_md_Associate(HANDLE file)
+{
+    HANDLE port;
+
+	if (!_native_threads_only) {
+		port = CreateIoCompletionPort((HANDLE)file, 
+										_pr_completion_port, 
+										KEY_IO,
+										0);
+
+		/* XXX should map error codes on failures */
+		return (port == _pr_completion_port);
+	} else {
+		return 1;
+	}
+}
+
+/*
+ * _md_MakeNonblock()
+ * Make a socket nonblocking.
+ * Returns 0 on failure, 1 on success.
+ */
+static PRInt32
+_md_MakeNonblock(HANDLE file)
+{
+    int rv;
+    u_long one = 1;
+
+    rv = ioctlsocket((SOCKET)file, FIONBIO, &one);
+    /* XXX should map error codes on failures */
+    return (rv == 0);
+}
+
+static int missing_completions = 0;
+static int max_wait_loops = 0;
+
+static PRInt32
+_NT_IO_ABORT(PROsfd sock)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRBool fWait;
+    PRInt32 rv;
+    int loop_count;
+
+    /* This is a clumsy way to abort the IO, but it is all we can do.
+     * It looks a bit racy, but we handle all the cases. 
+     * case 1:  IO completes before calling closesocket
+     *     case 1a:  fWait is set to PR_FALSE
+     *           This should e the most likely case.  We'll properly
+     *           not wait call _NT_IO_WAIT, since the closesocket()
+     *           won't be forcing a completion.
+     *     case 1b: fWait is set to PR_TRUE
+     *           This hopefully won't happen much.  When it does, this
+     *           thread will timeout in _NT_IO_WAIT for CLOSE_INTERVAL
+     *           before cleaning up.
+     * case 2:  IO does not complete before calling closesocket
+     *     case 2a: IO never completes
+     *           This is the likely case.  We'll close it and wait
+     *           for the completion forced by the close.  Return should
+     *           be immediate.
+     *     case 2b: IO completes just after calling closesocket
+     *           Since the closesocket is issued, we'll either get a
+     *           completion back for the real IO or for the close.  We
+     *           don't really care.  It may not even be possible to get
+     *           a real completion here.  In any event, we'll awaken
+     *           from NT_IO_WAIT immediately.
+     */
+
+    _PR_THREAD_LOCK(me);
+    fWait = me->io_pending;
+    if (fWait) {
+        /*
+         * If there's still I/O pending, it should have already timed
+         * out once before this function is called.
+         */
+        PR_ASSERT(me->io_suspended == PR_TRUE);
+
+        /* Set up to wait for I/O completion again */
+        me->state = _PR_IO_WAIT;
+        me->io_suspended = PR_FALSE;
+        me->md.interrupt_disabled = PR_TRUE;
+    }
+    _PR_THREAD_UNLOCK(me);
+
+    /* Close the socket if there is one */
+    if (sock != INVALID_SOCKET) {
+        rv = closesocket((SOCKET)sock);
+    }
+
+    /* If there was I/O pending before the close, wait for it to complete */
+    if (fWait) {
+
+        /* Wait and wait for the I/O to complete */
+        for (loop_count = 0; fWait; ++loop_count) {
+
+            _NT_IO_WAIT(me, CLOSE_TIMEOUT);
+
+            _PR_THREAD_LOCK(me);
+            fWait = me->io_pending;
+            if (fWait) {
+                PR_ASSERT(me->io_suspended == PR_TRUE);
+                me->state = _PR_IO_WAIT;
+                me->io_suspended = PR_FALSE;
+            }
+            _PR_THREAD_UNLOCK(me);
+
+            if (loop_count > max_wait_loops) {
+                max_wait_loops = loop_count;
+            }
+        }
+
+        if (loop_count > 1) {
+            ++missing_completions;
+        }
+
+        me->md.interrupt_disabled = PR_FALSE;
+        me->io_pending = PR_FALSE;
+        me->state = _PR_RUNNING;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+    me->md.thr_bound_cpu = NULL;
+    me->io_suspended = PR_FALSE;
+
+    return rv;
+}
+
+
+PROsfd
+_PR_MD_SOCKET(int af, int type, int flags)
+{
+    SOCKET sock;
+
+    sock = socket(af, type, flags);
+
+    if (sock == INVALID_SOCKET) {
+        _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError());
+    }
+
+    return (PROsfd)sock;
+}
+
+struct connect_data_s {
+    PRInt32 status;
+    PRInt32 error;
+    PROsfd  osfd;
+    struct sockaddr *addr;
+    PRUint32 addrlen;
+    PRIntervalTime timeout;
+};
+
+void
+_PR_MD_connect_thread(void *cdata)
+{
+    struct connect_data_s *cd = (struct connect_data_s *)cdata;
+
+    cd->status = connect(cd->osfd, cd->addr, cd->addrlen);
+
+    if (cd->status == SOCKET_ERROR)
+        cd->error = WSAGetLastError();
+
+    return;
+}
+
+
+PRInt32
+_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, 
+               PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    u_long nbio;
+    PRInt32 rc;
+
+    if (fd->secret->nonblocking) {
+        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 ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) {
+            err = WSAGetLastError();
+            _PR_MD_MAP_CONNECT_ERROR(err);
+        }
+        return rv;
+    }
+
+    /*
+     * Temporarily make the socket non-blocking so that we can
+     * initiate a non-blocking connect and wait for its completion
+     * (with a timeout) in select.
+     */
+    PR_ASSERT(!fd->secret->md.io_model_committed);
+    nbio = 1;
+    rv = ioctlsocket((SOCKET)osfd, FIONBIO, &nbio);
+    PR_ASSERT(0 == rv);
+
+    rc = _nt_nonblock_connect(fd, (struct sockaddr *) addr, addrlen, timeout);
+
+    /* Set the socket back to blocking. */
+    nbio = 0;
+    rv = ioctlsocket((SOCKET)osfd, FIONBIO, &nbio);
+    PR_ASSERT(0 == rv);
+
+    return rc;
+}
+
+PRInt32
+_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv;
+#if 0
+    int one = 1;
+#endif
+
+    rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen);
+
+    if (rv == SOCKET_ERROR) {
+        _PR_MD_MAP_BIND_ERROR(WSAGetLastError());
+        return -1;
+    }
+
+#if 0
+    /* Disable nagle- so far unknown if this is good or not...
+     */
+    rv = setsockopt(fd->secret->md.osfd, 
+                    SOL_SOCKET,
+                    TCP_NODELAY,
+                    (const char *)&one,
+                    sizeof(one));
+    PR_ASSERT(rv == 0);
+#endif
+
+    return 0;
+}
+
+void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd accept_sock, PROsfd listen_sock)
+{
+    /* Sockets accept()'d with AcceptEx need to call this setsockopt before
+     * calling anything other than ReadFile(), WriteFile(), send(), recv(), 
+     * Transmitfile(), and closesocket().  In order to call any other 
+     * winsock functions, we have to make this setsockopt call.
+     *
+     * XXXMB - For the server, we *NEVER* need this in
+     * the "normal" code path.  But now we have to call it.  This is a waste
+     * of a system call.  We'd like to only call it before calling the 
+     * obscure socket calls, but since we don't know at that point what the
+     * original socket was (or even if it is still alive) we can't do it
+     * at that point... 
+     */
+    setsockopt((SOCKET)accept_sock, 
+               SOL_SOCKET, 
+               SO_UPDATE_ACCEPT_CONTEXT,
+               (char *)&listen_sock,
+               sizeof(listen_sock));
+
+}
+
+#define INET_ADDR_PADDED (sizeof(PRNetAddr) + 16)
+PROsfd
+_PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
+              PRIntervalTime timeout, PRBool fast, 
+              _PR_AcceptTimeoutCallback callback, void *callbackArg)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    SOCKET accept_sock;
+    int bytes;
+    PRNetAddr *Laddr;
+    PRNetAddr *Raddr;
+    PRUint32 llen, err;
+    int rv;
+
+    if (_NT_USE_NB_IO(fd)) {
+        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 *)raddr, rlen, timeout);
+        if (!fd->secret->nonblocking) {
+            u_long zero = 0;
+
+            rv = ioctlsocket(accept_sock, FIONBIO, &zero);
+            PR_ASSERT(0 == rv);
+        }
+        return accept_sock;
+    }
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return -1;
+    }
+
+    if (!fd->secret->md.io_model_committed) {
+        rv = _md_Associate((HANDLE)osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+
+    if (!me->md.acceptex_buf) {
+        me->md.acceptex_buf = PR_MALLOC(2*INET_ADDR_PADDED);
+        if (!me->md.acceptex_buf) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return -1;
+        }
+    }
+
+    accept_sock = _md_get_recycled_socket(fd->secret->af);
+    if (accept_sock == INVALID_SOCKET)
+        return -1;
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		closesocket(accept_sock);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = osfd;
+
+    rv = AcceptEx((SOCKET)osfd,
+                  accept_sock,
+                  me->md.acceptex_buf,
+                  0,
+                  INET_ADDR_PADDED,
+                  INET_ADDR_PADDED,
+                  &bytes,
+                  &(me->md.overlapped.overlapped));
+
+    if ( (rv == 0) && ((err = WSAGetLastError()) != ERROR_IO_PENDING))  {
+        /* Argh! The IO failed */
+		closesocket(accept_sock);
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_ACCEPTEX_ERROR(err);
+        return -1;
+    }
+
+    if (_native_threads_only && rv) {
+        _native_thread_io_nowait(me, rv, bytes);
+    } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        closesocket(accept_sock);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+    if (me->io_suspended) {
+        closesocket(accept_sock);
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        return -1;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		closesocket(accept_sock);
+		_PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error);
+        return -1;
+    }
+
+    if (!fast)
+        _PR_MD_UPDATE_ACCEPT_CONTEXT((SOCKET)accept_sock, (SOCKET)osfd);
+
+    /* IO is done */
+    GetAcceptExSockaddrs(
+            me->md.acceptex_buf,
+            0,
+            INET_ADDR_PADDED,
+            INET_ADDR_PADDED,
+            (LPSOCKADDR *)&(Laddr),
+            &llen,
+            (LPSOCKADDR *)&(Raddr),
+            (unsigned int *)rlen);
+
+    if (raddr != NULL)
+        memcpy((char *)raddr, (char *)&Raddr->inet, *rlen);
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+
+    return accept_sock;
+}
+
+PRInt32
+_PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, PRNetAddr **raddr, 
+                   void *buf, PRInt32 amount, PRIntervalTime timeout, 
+                   PRBool fast, _PR_AcceptTimeoutCallback callback, 
+                   void *callbackArg)
+{
+    PROsfd sock = sd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    int bytes;
+    PRNetAddr *Laddr;
+    PRUint32 llen, rlen, err;
+    int rv;
+    PRBool isConnected;
+    PRBool madeCallback = PR_FALSE;
+
+    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);
+        sd->secret->md.io_model_committed = PR_TRUE;
+    }
+
+    *newSock = _md_get_recycled_socket(sd->secret->af);
+    if (*newSock == INVALID_SOCKET)
+        return -1;
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		closesocket(*newSock);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = sock;
+
+    rv = AcceptEx((SOCKET)sock,
+                  *newSock,
+                  buf,
+                  amount,
+                  INET_ADDR_PADDED,
+                  INET_ADDR_PADDED,
+                  &bytes,
+                  &(me->md.overlapped.overlapped));
+
+    if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING)) {
+		closesocket(*newSock);
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_ACCEPTEX_ERROR(err);
+        return -1;
+    }
+
+    if (_native_threads_only && rv) {
+        _native_thread_io_nowait(me, rv, bytes);
+    } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        closesocket(*newSock);
+        return -1;
+    }
+
+retry:
+    if (me->io_suspended) {
+        PRInt32 err;
+        INT seconds;
+        INT bytes = sizeof(seconds);
+
+        PR_ASSERT(timeout != PR_INTERVAL_NO_TIMEOUT);
+
+        err = getsockopt(*newSock, 
+                         SOL_SOCKET,
+                         SO_CONNECT_TIME,
+                         (char *)&seconds,
+                         (PINT)&bytes);
+        if ( err == NO_ERROR ) {
+            PRIntervalTime elapsed = PR_SecondsToInterval(seconds);
+
+            if (seconds == 0xffffffff) 
+                isConnected = PR_FALSE;
+            else 
+                isConnected = PR_TRUE;
+
+            if (!isConnected) {
+                if (madeCallback == PR_FALSE && callback)
+                    callback(callbackArg);
+                madeCallback = PR_TRUE;
+                me->state = _PR_IO_WAIT;
+                if (_NT_ResumeIO(me, timeout) == PR_FAILURE) {
+                    closesocket(*newSock);
+                    return -1;
+                }
+                goto retry;
+            }
+
+            if (elapsed < timeout) {
+                /* Socket is connected but time not elapsed, RESUME IO */
+                timeout -= elapsed;
+                me->state = _PR_IO_WAIT;
+                if (_NT_ResumeIO(me, timeout) == PR_FAILURE) {
+                    closesocket(*newSock);
+                    return -1;
+                }
+                goto retry;
+            }
+        } else {
+            /*  What to do here? Assume socket not open?*/
+            PR_ASSERT(0);
+            isConnected = PR_FALSE;
+        }
+
+        rv = _NT_IO_ABORT(*newSock);
+
+        PR_ASSERT(me->io_pending ==  PR_FALSE);
+        PR_ASSERT(me->io_suspended ==  PR_FALSE);
+        PR_ASSERT(me->md.thr_bound_cpu ==  NULL);
+        /* If the IO is still suspended, it means we didn't get any 
+         * completion from NT_IO_WAIT.  This is not disasterous, I hope,
+         * but it may mean we still have an IO outstanding...  Try to 
+         * recover by just allowing ourselves to continue.
+         */
+        me->io_suspended = PR_FALSE;
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        me->state = _PR_RUNNING;
+        closesocket(*newSock);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+    PR_ASSERT(me->io_suspended == PR_FALSE);
+    PR_ASSERT(me->md.thr_bound_cpu == NULL);
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error);
+        closesocket(*newSock);
+        return -1;
+    }
+
+    if (!fast) 
+        _PR_MD_UPDATE_ACCEPT_CONTEXT((SOCKET)*newSock, (SOCKET)sock);
+
+    /* IO is done */
+    GetAcceptExSockaddrs(
+            buf,
+            amount,
+            INET_ADDR_PADDED,
+            INET_ADDR_PADDED,
+            (LPSOCKADDR *)&(Laddr),
+            &llen,
+            (LPSOCKADDR *)(raddr),
+            (unsigned int *)&rlen);
+
+    return me->md.blocked_io_bytes;
+}
+
+PRInt32
+_PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd,
+					PRInt32 flags, PRIntervalTime timeout)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 tflags;
+    int rv, err;
+
+    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);
+        sock->secret->md.io_model_committed = PR_TRUE;
+    }
+    if (!me->md.xmit_bufs) {
+        me->md.xmit_bufs = PR_NEW(TRANSMIT_FILE_BUFFERS);
+        if (!me->md.xmit_bufs) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return -1;
+        }
+    }
+    me->md.xmit_bufs->Head       = (void *)sfd->header;
+    me->md.xmit_bufs->HeadLength = sfd->hlen;
+    me->md.xmit_bufs->Tail       = (void *)sfd->trailer;
+    me->md.xmit_bufs->TailLength = sfd->tlen;
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+    me->md.overlapped.overlapped.Offset = sfd->file_offset;
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    tflags = 0;
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET)
+        tflags = TF_DISCONNECT | TF_REUSE_SOCKET;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = sock->secret->md.osfd;
+
+    rv = TransmitFile((SOCKET)sock->secret->md.osfd,
+                      (HANDLE)sfd->fd->secret->md.osfd,
+                      (DWORD)sfd->file_nbytes,
+                      (DWORD)0,
+                      (LPOVERLAPPED)&(me->md.overlapped.overlapped),
+                      (TRANSMIT_FILE_BUFFERS *)me->md.xmit_bufs,
+                      (DWORD)tflags);
+    if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_TRANSMITFILE_ERROR(err);
+        return -1;
+    }
+
+    if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+    if (me->io_suspended) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        return -1;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_TRANSMITFILE_ERROR(me->md.blocked_io_error);
+        return -1;
+    }
+
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+        _md_put_recycled_socket(sock->secret->md.osfd, sock->secret->af);
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+
+    return me->md.blocked_io_bytes;
+}
+
+PRInt32
+_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
+            PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    int bytes;
+    int rv, err;
+
+    if (_NT_USE_NB_IO(fd)) {
+        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, flags, timeout);
+    }
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return -1;
+    }
+
+    if (!fd->secret->md.io_model_committed) {
+        rv = _md_Associate((HANDLE)osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = osfd;
+
+    rv = ReadFile((HANDLE)osfd,
+                  buf, 
+                  amount,
+                  &bytes,
+                  &(me->md.overlapped.overlapped));
+    if ( (rv == 0) && (GetLastError() != ERROR_IO_PENDING) ) {
+    	_PR_THREAD_LOCK(me);
+        me->io_pending = PR_FALSE;
+        me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        if ((err = GetLastError()) == ERROR_HANDLE_EOF)
+            return 0;
+		_PR_MD_MAP_READ_ERROR(err);
+        return -1;
+    }
+
+    if (_native_threads_only && rv) {
+        _native_thread_io_nowait(me, rv, bytes);
+    } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+    if (me->io_suspended) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        return -1;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+        if (me->md.blocked_io_error == ERROR_HANDLE_EOF)
+            return 0;
+		_PR_MD_MAP_READ_ERROR(me->md.blocked_io_error);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+
+    return me->md.blocked_io_bytes;
+}
+
+PRInt32
+_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    int bytes;
+    int rv, err;
+
+    if (_NT_USE_NB_IO(fd)) {
+        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);
+    }
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return -1;
+    }
+
+    if (!fd->secret->md.io_model_committed) {
+        rv = _md_Associate((HANDLE)osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = osfd;
+
+    rv = WriteFile((HANDLE)osfd,
+                   buf, 
+                   amount,
+                   &bytes,
+                   &(me->md.overlapped.overlapped));
+    if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) {
+    	_PR_THREAD_LOCK(me);
+        me->io_pending = PR_FALSE;
+        me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_WRITE_ERROR(err);
+        return -1;
+    }
+
+    if (_native_threads_only && rv) {
+        _native_thread_io_nowait(me, rv, bytes);
+    } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+    if (me->io_suspended) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        return -1;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_WRITE_ERROR(me->md.blocked_io_error);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+
+    return me->md.blocked_io_bytes;
+}
+
+PRInt32
+_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+              const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PROsfd 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_NB_IO(fd))
+        return _nt_nonblock_sendto(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
+    else
+        return pt_SendTo(osfd, buf, amount, flags, addr, addrlen, timeout);
+}
+
+PRInt32
+_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+                PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PROsfd 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_NB_IO(fd))
+        return _nt_nonblock_recvfrom(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
+    else
+        return pt_RecvFrom(osfd, buf, amount, flags, 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)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    int index;
+    int sent = 0;
+    int rv;
+
+    if (_NT_USE_NB_IO(fd)) {
+        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);
+    }
+
+    for (index=0; index<iov_size; index++) {
+        rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0,
+						timeout);
+        if (rv > 0) 
+            sent += rv;
+        if ( rv != iov[index].iov_len ) {
+            if (sent <= 0)
+                return -1;
+            return -1;
+        }
+    }
+
+    return sent;
+}
+
+PRInt32
+_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv;
+
+    rv = listen(fd->secret->md.osfd, backlog);
+	if (rv < 0)
+		_PR_MD_MAP_LISTEN_ERROR(WSAGetLastError());
+	return(rv);
+}
+
+PRInt32
+_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how)
+{
+    PRInt32 rv;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+	if (rv < 0)
+		_PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError());
+	return(rv);
+}
+
+PRStatus
+_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len);
+    if (rv==0)
+		return PR_SUCCESS;
+	else {
+		_PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError());
+		return PR_FAILURE;
+	}
+}
+
+PRStatus
+_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    /*
+     * NT has a bug that, when invoked on a socket accepted by
+     * AcceptEx(), getpeername() returns an all-zero peer address.
+     * To work around this bug, we store the peer's address (returned
+     * by AcceptEx()) with the socket fd and use the cached peer
+     * address if the socket is an accepted socket.
+     */
+
+    if (fd->secret->md.accepted_socket) {
+        INT seconds;
+        INT bytes = sizeof(seconds);
+
+        /*
+         * Determine if the socket is connected.
+         */
+
+        rv = getsockopt(fd->secret->md.osfd, 
+                        SOL_SOCKET,
+                        SO_CONNECT_TIME,
+                        (char *) &seconds,
+                        (PINT) &bytes);
+        if (rv == NO_ERROR) {
+            if (seconds == 0xffffffff) {
+                PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
+                return PR_FAILURE;
+            }
+            *len = PR_NETADDR_SIZE(&fd->secret->md.peer_addr);
+            memcpy(addr, &fd->secret->md.peer_addr, *len);
+            return PR_SUCCESS;
+        } else {
+            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+            return PR_FAILURE;
+        }
+    } else { 
+        rv = getpeername((SOCKET)fd->secret->md.osfd,
+                         (struct sockaddr *) addr, len);
+        if (rv == 0) {
+            return PR_SUCCESS;
+        } else {
+            _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError());
+            return PR_FAILURE;
+        }
+    }
+}
+
+PRStatus
+_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv;
+
+    rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0)
+		return PR_SUCCESS;
+	else {
+		_PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+		return PR_FAILURE;
+	}
+}
+
+PRStatus
+_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv;
+
+    rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0)
+		return PR_SUCCESS;
+	else {
+		_PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError());
+		return PR_FAILURE;
+	}
+}
+
+/* --- FILE IO ----------------------------------------------------------- */
+
+PROsfd
+_PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    
+    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;
+
+    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;
+        }
+    }
+
+    return (PROsfd)file;
+}
+
+PROsfd
+_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,
+                      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 (PROsfd)file;
+}
+
+PRInt32 
+_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
+{
+    PROsfd f = fd->secret->md.osfd;
+    PRUint32 bytes;
+    int rv, err;
+    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, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+        PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
+
+        if (fd->secret->inheritable == _PR_TRI_TRUE) {
+            rv = ReadFile((HANDLE)f, 
+                          (LPVOID)buf, 
+                          len, 
+                          &bytes, 
+                          &me->md.overlapped.overlapped);
+            if (rv != 0) {
+                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) {
+                    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);
+                return -1;
+            }
+        } else {
+            if (!fd->secret->md.io_model_committed) {
+                rv = _md_Associate((HANDLE)f);
+                PR_ASSERT(rv != 0);
+                fd->secret->md.io_model_committed = PR_TRUE;
+            }
+
+			if (_native_threads_only)
+        		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+			_PR_THREAD_LOCK(me);
+			if (_PR_PENDING_INTERRUPT(me)) {
+				me->flags &= ~_PR_INTERRUPT;
+				PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+				_PR_THREAD_UNLOCK(me);
+				return -1;
+			}
+			me->io_pending = PR_TRUE;
+			me->state = _PR_IO_WAIT;
+			_PR_THREAD_UNLOCK(me);
+			me->io_fd = f;
+
+            rv = ReadFile((HANDLE)f, 
+                          (LPVOID)buf, 
+                          len, 
+                          &bytes, 
+                          &me->md.overlapped.overlapped);
+            if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) {
+				_PR_THREAD_LOCK(me);
+				me->io_pending = PR_FALSE;
+				me->state = _PR_RUNNING;
+				if (_PR_PENDING_INTERRUPT(me)) {
+					me->flags &= ~_PR_INTERRUPT;
+					PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+					_PR_THREAD_UNLOCK(me);
+					return -1;
+				}
+				_PR_THREAD_UNLOCK(me);
+
+                if (err == ERROR_HANDLE_EOF) {
+                    return 0;
+                }
+                _PR_MD_MAP_READ_ERROR(err);
+                return -1;
+            }
+
+            if (_native_threads_only && rv) {
+                _native_thread_io_nowait(me, rv, bytes);
+            } else if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+                PR_ASSERT(0);
+                return -1;
+            }
+
+            PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+            if (me->io_suspended) {
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                } else {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                return -1;
+            }
+
+            if (me->md.blocked_io_status == 0) {
+                if (me->md.blocked_io_error == ERROR_HANDLE_EOF) {
+                    return 0;
+                }
+                _PR_MD_MAP_READ_ERROR(me->md.blocked_io_error);
+                return -1;
+            }
+
+            SetFilePointer((HANDLE)f, me->md.blocked_io_bytes, 0, FILE_CURRENT);
+    
+            PR_ASSERT(me->io_pending == PR_FALSE);
+
+            return me->md.blocked_io_bytes;
+        }
+    } else {
+
+        rv = ReadFile((HANDLE)f,
+                      (LPVOID)buf,
+                      len,
+                      &bytes,
+                      NULL);
+        if (rv == 0) {
+            err = GetLastError();
+            /* ERROR_HANDLE_EOF can only be returned by async io */
+            PR_ASSERT(err != ERROR_HANDLE_EOF);
+            if (err == ERROR_BROKEN_PIPE) {
+                /* The write end of the pipe has been closed. */ 
+                return 0;
+            }
+            _PR_MD_MAP_READ_ERROR(err);
+            return -1;
+        }
+        return bytes;
+    }
+}
+
+PRInt32
+_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
+{
+    PROsfd f = fd->secret->md.osfd;
+    PRInt32 bytes;
+    int rv, err;
+    LONG hiOffset = 0;
+    LONG loOffset;
+    LARGE_INTEGER offset; /* use for the calculation of the new offset */
+
+    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, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+        PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
+
+        if (fd->secret->inheritable == _PR_TRI_TRUE) {
+            rv = WriteFile((HANDLE)f, 
+                          (LPVOID)buf, 
+                          len, 
+                          &bytes, 
+                          &me->md.overlapped.overlapped);
+            if (rv != 0) {
+                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) {
+                    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) {
+                rv = _md_Associate((HANDLE)f);
+                PR_ASSERT(rv != 0);
+                fd->secret->md.io_model_committed = PR_TRUE;
+            }
+			if (_native_threads_only)
+        		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+			_PR_THREAD_LOCK(me);
+			if (_PR_PENDING_INTERRUPT(me)) {
+				me->flags &= ~_PR_INTERRUPT;
+				PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+				_PR_THREAD_UNLOCK(me);
+				return -1;
+			}
+			me->io_pending = PR_TRUE;
+			me->state = _PR_IO_WAIT;
+			_PR_THREAD_UNLOCK(me);
+			me->io_fd = f;
+
+            rv = WriteFile((HANDLE)f, 
+                           buf, 
+                           len, 
+                           &bytes, 
+                           &(me->md.overlapped.overlapped));
+            if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) {
+				_PR_THREAD_LOCK(me);
+				me->io_pending = PR_FALSE;
+				me->state = _PR_RUNNING;
+				if (_PR_PENDING_INTERRUPT(me)) {
+					me->flags &= ~_PR_INTERRUPT;
+					PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+					_PR_THREAD_UNLOCK(me);
+					return -1;
+				}
+				_PR_THREAD_UNLOCK(me);
+
+                _PR_MD_MAP_WRITE_ERROR(err);
+                return -1;
+            }
+
+            if (_native_threads_only && rv) {
+                _native_thread_io_nowait(me, rv, bytes);
+            } else if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+                PR_ASSERT(0);
+                return -1;
+            }
+
+            PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+            if (me->io_suspended) {
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                } else {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                return -1;
+            }
+
+            if (me->md.blocked_io_status == 0) {
+                _PR_MD_MAP_WRITE_ERROR(me->md.blocked_io_error);
+                return -1;
+            }
+
+            /*
+             * Moving the file pointer by a relative offset (FILE_CURRENT)
+             * does not work with a file on a network drive exported by a
+             * Win2K system.  We still don't know why.  A workaround is to
+             * move the file pointer by an absolute offset (FILE_BEGIN).
+             * (Bugzilla bug 70765)
+             */
+            offset.LowPart = me->md.overlapped.overlapped.Offset;
+            offset.HighPart = me->md.overlapped.overlapped.OffsetHigh;
+            offset.QuadPart += me->md.blocked_io_bytes;
+
+            SetFilePointer((HANDLE)f, offset.LowPart, &offset.HighPart, FILE_BEGIN);
+    
+            PR_ASSERT(me->io_pending == PR_FALSE);
+
+            return me->md.blocked_io_bytes;
+        }
+    } else {
+        rv = WriteFile((HANDLE)f,
+                       buf,
+                       len,
+                       &bytes,
+                       NULL);
+        if (rv == 0) {
+            _PR_MD_MAP_WRITE_ERROR(GetLastError());
+            return -1;
+        }
+        return bytes;
+    }
+}
+
+PRInt32
+_PR_MD_SOCKETAVAILABLE(PRFileDesc *fd)
+{
+    PRInt32 result;
+
+    if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+		PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError());
+        return -1;
+    }
+    return result;
+}
+
+PRInt32
+_PR_MD_PIPEAVAILABLE(PRFileDesc *fd)
+{
+    if (NULL == fd)
+		PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+	else
+		PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+}
+
+PROffset32
+_PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
+{
+    DWORD moveMethod;
+    PROffset32 rv;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            moveMethod = FILE_BEGIN;
+            break;
+        case PR_SEEK_CUR:
+            moveMethod = FILE_CURRENT;
+            break;
+        case PR_SEEK_END:
+            moveMethod = FILE_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return -1;
+    }
+
+    rv = SetFilePointer((HANDLE)fd->secret->md.osfd, offset, NULL, moveMethod);
+
+    /*
+     * If the lpDistanceToMoveHigh argument (third argument) is
+     * NULL, SetFilePointer returns 0xffffffff on failure.
+     */
+    if (-1 == rv) {
+        _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+    }
+    return rv;
+}
+
+PROffset64
+_PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
+{
+    DWORD moveMethod;
+    LARGE_INTEGER li;
+    DWORD err;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            moveMethod = FILE_BEGIN;
+            break;
+        case PR_SEEK_CUR:
+            moveMethod = FILE_CURRENT;
+            break;
+        case PR_SEEK_END:
+            moveMethod = FILE_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return -1;
+    }
+
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer((HANDLE)fd->secret->md.osfd,
+            li.LowPart, &li.HighPart, moveMethod);
+
+    if (0xffffffff == li.LowPart && (err = GetLastError()) != NO_ERROR) {
+        _PR_MD_MAP_LSEEK_ERROR(err);
+        li.QuadPart = -1;
+    }
+    return li.QuadPart;
+}
+
+/*
+ * This is documented to succeed on read-only files, but Win32's
+ * FlushFileBuffers functions fails with "access denied" in such a
+ * case.  So we only signal an error if the error is *not* "access
+ * denied".
+ */
+PRInt32
+_PR_MD_FSYNC(PRFileDesc *fd)
+{
+    /*
+     * From the documentation:
+     *
+     *	   On Windows NT, the function FlushFileBuffers fails if hFile
+     *	   is a handle to console output. That is because console
+     *	   output is not buffered. The function returns FALSE, and
+     *	   GetLastError returns ERROR_INVALID_HANDLE.
+     *
+     * On the other hand, on Win95, it returns without error.  I cannot
+     * assume that 0, 1, and 2 are console, because if someone closes
+     * System.out and then opens a file, they might get file descriptor
+     * 1.  An error on *that* version of 1 should be reported, whereas
+     * an error on System.out (which was the original 1) should be
+     * ignored.  So I use isatty() to ensure that such an error was
+     * because of this, and if it was, I ignore the error.
+     */
+
+    BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd);
+
+    if (!ok) {
+	DWORD err = GetLastError();
+
+	if (err != ERROR_ACCESS_DENIED) {	/* from winerror.h */
+			_PR_MD_MAP_FSYNC_ERROR(err);
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+PRInt32
+_PR_MD_CLOSE(PROsfd osfd, PRBool socket)
+{
+    PRInt32 rv;
+    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);
+        }
+    }
+    return rv;
+}
+
+PRStatus
+_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
+{
+    BOOL rv;
+
+    if (fd->secret->md.io_model_committed) {
+        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_MD_MAP_DEFAULT_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+} 
+
+void
+_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
+{
+    if (imported) {
+        fd->secret->inheritable = _PR_TRI_UNKNOWN;
+    } else {
+        fd->secret->inheritable = _PR_TRI_FALSE;
+    }
+}
+
+void
+_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
+{
+    DWORD flags;
+
+    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+    if (fd->secret->md.io_model_committed) {
+        return;
+    }
+    if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) {
+        if (flags & HANDLE_FLAG_INHERIT) {
+            fd->secret->inheritable = _PR_TRI_TRUE;
+        } else {
+            fd->secret->inheritable = _PR_TRI_FALSE;
+        }
+    }
+}
+
+
+/* --- 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;
+        }
+        cp = _mbsinc(cp);
+    }
+} /* end FlipSlashes() */
+
+/*
+**
+** Local implementations of standard Unix RTL functions which are not provided
+** by the VC RTL.
+**
+*/
+
+PRInt32
+_PR_MD_CLOSE_DIR(_MDDir *d)
+{
+    if ( d ) {
+        if (FindClose( d->d_hdl )) {
+            d->magic = (PRUint32)-1;
+            return 0;
+        } else {
+            _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError());
+            return -1;
+        }
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return -1;
+}
+
+
+PRStatus
+_PR_MD_OPEN_DIR(_MDDir *d, const char *name)
+{
+    char filename[ MAX_PATH ];
+    int len;
+
+    len = strlen(name);
+    /* Need 5 bytes for \*.* and the trailing null byte. */
+    if (len + 5 > MAX_PATH) {
+        PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+        return PR_FAILURE;
+    }
+    strcpy(filename, name);
+
+    /*
+     * If 'name' ends in a slash or backslash, do not append
+     * another backslash.
+     */
+    if (IsPrevCharSlash(filename, filename + len)) {
+        len--;
+    }
+    strcpy(&filename[len], "\\*.*");
+    FlipSlashes( filename, strlen(filename) );
+
+    d->d_hdl = FindFirstFile( filename, &(d->d_entry) );
+    if ( d->d_hdl == INVALID_HANDLE_VALUE ) {
+		_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    d->firstEntry = PR_TRUE;
+    d->magic = _MD_MAGIC_DIR;
+    return PR_SUCCESS;
+}
+
+char *
+_PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
+{
+    PRInt32 err;
+    BOOL rv;
+    char *fileName;
+
+    if ( d ) {
+        while (1) {
+            if (d->firstEntry) {
+                d->firstEntry = PR_FALSE;
+                rv = 1;
+            } else {
+                rv = FindNextFile(d->d_hdl, &(d->d_entry));
+            }
+            if (rv == 0) {
+                break;
+            }
+            fileName = GetFileFromDIR(d);
+            if ( (flags & PR_SKIP_DOT) &&
+                 (fileName[0] == '.') && (fileName[1] == '\0'))
+                 continue;
+            if ( (flags & PR_SKIP_DOT_DOT) &&
+                 (fileName[0] == '.') && (fileName[1] == '.') &&
+                 (fileName[2] == '\0'))
+                 continue;
+            if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d))
+                 continue;
+            return fileName;
+        }
+	err = GetLastError();
+	PR_ASSERT(NO_ERROR != err);
+			_PR_MD_MAP_READDIR_ERROR(err);
+	return NULL;
+		}
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;
+}
+
+PRInt32
+_PR_MD_DELETE(const char *name)
+{
+    if (DeleteFile(name)) {
+		return 0;
+	} else {
+		_PR_MD_MAP_DELETE_ERROR(GetLastError());
+		return -1;
+	}
+}
+
+void
+_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm)
+{
+    PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime));
+    CopyMemory(prtm, filetime, sizeof(PRTime));
+#ifdef __GNUC__
+    *prtm = (*prtm - _pr_filetime_offset) / 10LL;
+#else
+    *prtm = (*prtm - _pr_filetime_offset) / 10i64;
+#endif
+
+#ifdef DEBUG
+    /* Doublecheck our calculation. */
+    {
+        SYSTEMTIME systime;
+        PRExplodedTime etm;
+        PRTime cmp; /* for comparison */
+        BOOL rv;
+
+        rv = FileTimeToSystemTime(filetime, &systime);
+        PR_ASSERT(0 != rv);
+
+        /*
+         * PR_ImplodeTime ignores wday and yday.
+         */
+        etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC;
+        etm.tm_sec = systime.wSecond;
+        etm.tm_min = systime.wMinute;
+        etm.tm_hour = systime.wHour;
+        etm.tm_mday = systime.wDay;
+        etm.tm_month = systime.wMonth - 1;
+        etm.tm_year = systime.wYear;
+        /*
+         * It is not well-documented what time zone the FILETIME's
+         * are in.  WIN32_FIND_DATA is documented to be in UTC (GMT).
+         * But BY_HANDLE_FILE_INFORMATION is unclear about this.
+         * By our best judgement, we assume that FILETIME is in UTC.
+         */
+        etm.tm_params.tp_gmt_offset = 0;
+        etm.tm_params.tp_dst_offset = 0;
+        cmp = PR_ImplodeTime(&etm);
+
+        /*
+         * SYSTEMTIME is in milliseconds precision, so we convert PRTime's
+         * microseconds to milliseconds before doing the comparison.
+         */
+        PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC));
+    }
+#endif /* DEBUG */
+}
+
+PRInt32
+_PR_MD_STAT(const char *fn, struct stat *info)
+{
+    PRInt32 rv;
+
+    rv = _stat(fn, (struct _stat *)info);
+    if (-1 == rv) {
+        /*
+         * Check for MSVC runtime library _stat() bug.
+         * (It's really a bug in FindFirstFile().)
+         * If a pathname ends in a backslash or slash,
+         * e.g., c:\temp\ or c:/temp/, _stat() will fail.
+         * Note: a pathname ending in a slash (e.g., c:/temp/)
+         * can be handled by _stat() on NT but not on Win95.
+         *
+         * We remove the backslash or slash at the end and
+         * try again.
+         */
+
+        int len = strlen(fn);
+        if (len > 0 && len <= _MAX_PATH
+                && IsPrevCharSlash(fn, fn + len)) {
+            char newfn[_MAX_PATH + 1];
+
+            strcpy(newfn, fn);
+            newfn[len - 1] = '\0';
+            rv = _stat(newfn, (struct _stat *)info);
+        }
+    }
+
+    if (-1 == rv) {
+        _PR_MD_MAP_STAT_ERROR(errno);
+    }
+    return rv;
+}
+
+#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\')
+
+static PRBool
+IsPrevCharSlash(const char *str, const char *current)
+{
+    const char *prev;
+
+    if (str >= current)
+        return PR_FALSE;
+    prev = _mbsdec(str, current);
+    return (prev == current - 1) && _PR_IS_SLASH(*prev);
+}
+
+/*
+ * IsRootDirectory --
+ *
+ * Return PR_TRUE if the pathname 'fn' is a valid root directory,
+ * else return PR_FALSE.  The char buffer pointed to by 'fn' must
+ * be writable.  During the execution of this function, the contents
+ * of the buffer pointed to by 'fn' may be modified, but on return
+ * the original contents will be restored.  'buflen' is the size of
+ * the buffer pointed to by 'fn'.
+ *
+ * Root directories come in three formats:
+ * 1. / or \, meaning the root directory of the current drive.
+ * 2. C:/ or C:\, where C is a drive letter.
+ * 3. \\<server name>\<share point name>\ or
+ *    \\<server name>\<share point name>, meaning the root directory
+ *    of a UNC (Universal Naming Convention) name.
+ */
+
+static PRBool
+IsRootDirectory(char *fn, size_t buflen)
+{
+    char *p;
+    PRBool slashAdded = PR_FALSE;
+    PRBool rv = PR_FALSE;
+
+    if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') {
+        return PR_TRUE;
+    }
+
+    if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2])
+            && fn[3] == '\0') {
+        rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+        return rv;
+    }
+
+    /* The UNC root directory */
+
+    if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) {
+        /* The 'server' part should have at least one character. */
+        p = &fn[2];
+        if (*p == '\0' || _PR_IS_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the next slash */
+        do {
+            p = _mbsinc(p);
+        } while (*p != '\0' && !_PR_IS_SLASH(*p));
+        if (*p == '\0') {
+            return PR_FALSE;
+        }
+
+        /* The 'share' part should have at least one character. */
+        p++;
+        if (*p == '\0' || _PR_IS_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the final slash */
+        do {
+            p = _mbsinc(p);
+        } while (*p != '\0' && !_PR_IS_SLASH(*p));
+        if (_PR_IS_SLASH(*p) && p[1] != '\0') {
+            return PR_FALSE;
+        }
+        if (*p == '\0') {
+            /*
+             * GetDriveType() doesn't work correctly if the
+             * path is of the form \\server\share, so we add
+             * a final slash temporarily.
+             */
+            if ((p + 1) < (fn + buflen)) {
+                *p++ = '\\';
+                *p = '\0';
+                slashAdded = PR_TRUE;
+            } else {
+                return PR_FALSE; /* name too long */
+            }
+        }
+        rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+        /* restore the 'fn' buffer */
+        if (slashAdded) {
+            *--p = '\0';
+        }
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
+{
+    WIN32_FILE_ATTRIBUTE_DATA findFileData;
+    
+    if (NULL == fn || '\0' == *fn) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+
+    if (!GetFileAttributesEx(fn, GetFileExInfoStandard, &findFileData)) {
+        _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        info->type = PR_FILE_DIRECTORY;
+    } else {
+        info->type = PR_FILE_FILE;
+    }
+
+    info->size = findFileData.nFileSizeHigh;
+    info->size = (info->size << 32) + findFileData.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime);
+
+    if (0 == findFileData.ftCreationTime.dwLowDateTime &&
+            0 == findFileData.ftCreationTime.dwHighDateTime) {
+        info->creationTime = info->modifyTime;
+    } else {
+        _PR_FileTimeToPRTime(&findFileData.ftCreationTime,
+                &info->creationTime);
+    }
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
+{
+    PRFileInfo64 info64;
+    PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64);
+    if (0 == rv)
+    {
+        info->type = info64.type;
+        info->size = (PRUint32) info64.size;
+        info->modifyTime = info64.modifyTime;
+        info->creationTime = info64.creationTime;
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    int rv;
+
+    BY_HANDLE_FILE_INFORMATION hinfo;
+
+    rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo);
+    if (rv == FALSE) {
+		_PR_MD_MAP_FSTAT_ERROR(GetLastError());
+        return -1;
+	}
+
+    if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_FILE;
+
+    info->size = hinfo.nFileSizeHigh;
+    info->size = (info->size << 32) + hinfo.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) );
+    _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) );
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
+{
+    int rv;
+
+    BY_HANDLE_FILE_INFORMATION hinfo;
+
+    rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo);
+    if (rv == FALSE) {
+		_PR_MD_MAP_FSTAT_ERROR(GetLastError());
+        return -1;
+	}
+
+    if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_FILE;
+
+    info->size = hinfo.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) );
+    _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) );
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_RENAME(const char *from, const char *to)
+{
+    /* Does this work with dot-relative pathnames? */
+    if (MoveFile(from, to)) {
+		return 0;
+	} else {
+		_PR_MD_MAP_RENAME_ERROR(GetLastError());
+		return -1;
+	}
+}
+
+PRInt32
+_PR_MD_ACCESS(const char *name, PRAccessHow how)
+{
+    PRInt32 rv;
+
+    switch (how) {
+      case PR_ACCESS_WRITE_OK:
+        rv = _access(name, 02);
+		break;
+      case PR_ACCESS_READ_OK:
+        rv = _access(name, 04);
+		break;
+      case PR_ACCESS_EXISTS:
+        rv = _access(name, 00);
+		break;
+      default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+    }
+	if (rv < 0) {
+		_PR_MD_MAP_ACCESS_ERROR(errno);
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_MKDIR(const char *name, PRIntn mode)
+{
+    /* XXXMB - how to translate the "mode"??? */
+    if (CreateDirectory(name, NULL)) {
+        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;
+    }
+}
+
+PRStatus
+_PR_MD_LOCKFILE(PROsfd f)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+
+    rv = LockFileEx((HANDLE)f, 
+                    LOCKFILE_EXCLUSIVE_LOCK,
+                    0,
+                    0x7fffffff,
+                    0,
+                    &me->md.overlapped.overlapped);
+
+    if (_native_threads_only) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        if (rv == FALSE) {
+            err = GetLastError();
+            PR_ASSERT(err != ERROR_IO_PENDING);
+            _PR_MD_MAP_LOCKF_ERROR(err);
+            return PR_FAILURE;
+        }
+        return PR_SUCCESS;
+    }
+
+    /* HACK AROUND NT BUG
+     * NT 3.51 has a bug.  In NT 3.51, if LockFileEx returns true, you
+     * don't get any completion on the completion port.  This is a bug.
+     *
+     * They fixed it on NT4.0 so that you do get a completion.
+     *
+     * If we pretend we won't get a completion, NSPR gets confused later
+     * when the unexpected completion arrives.  If we assume we do get
+     * a completion, we hang on 3.51.  Worse, Microsoft informs me that the 
+     * behavior varies on 3.51 depending on if you are using a network
+     * file system or a local disk!
+     *
+     * Solution:  For now, _nt_version_gets_lockfile_completion is set
+     * depending on whether or not this system is EITHER
+     *      - running NT 4.0
+     *      - running NT 3.51 with a service pack greater than 5.
+     * 
+     * In the meantime, this code may not work on network file systems.
+     *
+     */
+
+    if ( rv == FALSE && ((err = GetLastError()) != ERROR_IO_PENDING)) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_LOCKF_ERROR(err);
+        return PR_FAILURE;
+    }
+#ifdef _NEED_351_FILE_LOCKING_HACK
+    else if (rv)  {
+        /* If this is NT 3.51 and the file is local, then we won't get a 
+         * completion back from LockFile when it succeeded.
+         */
+        if (_nt_version_gets_lockfile_completion == PR_FALSE) {
+            if ( IsFileLocal((HANDLE)f) == _PR_LOCAL_FILE) {
+                me->io_pending = PR_FALSE;
+                me->state = _PR_RUNNING;
+                return PR_SUCCESS; 
+            }
+        }
+    }
+#endif /* _NEED_351_FILE_LOCKING_HACK */
+
+    if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+		_PR_THREAD_LOCK(me);
+        me->io_pending = PR_FALSE;
+        me->state = _PR_RUNNING;
+		_PR_THREAD_UNLOCK(me);
+        return PR_FAILURE;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_LOCKF_ERROR(me->md.blocked_io_error);
+        return PR_FAILURE;
+    }
+
+    return PR_SUCCESS;
+}
+
+PRStatus
+_PR_MD_TLOCKFILE(PROsfd f)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+
+    rv = LockFileEx((HANDLE)f, 
+                    LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK,
+                    0,
+                    0x7fffffff,
+                    0,
+                    &me->md.overlapped.overlapped);
+    if (_native_threads_only) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        if (rv == FALSE) {
+            err = GetLastError();
+            PR_ASSERT(err != ERROR_IO_PENDING);
+            _PR_MD_MAP_LOCKF_ERROR(err);
+            return PR_FAILURE;
+        }
+        return PR_SUCCESS;
+    }
+    if ( rv == FALSE && ((err = GetLastError()) != ERROR_IO_PENDING)) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        _PR_MD_MAP_LOCKF_ERROR(err);
+        return PR_FAILURE;
+    }
+#ifdef _NEED_351_FILE_LOCKING_HACK
+    else if (rv)  {
+        /* If this is NT 3.51 and the file is local, then we won't get a 
+         * completion back from LockFile when it succeeded.
+         */
+        if (_nt_version_gets_lockfile_completion == PR_FALSE) {
+            if ( IsFileLocal((HANDLE)f) == _PR_LOCAL_FILE) {
+				_PR_THREAD_LOCK(me);
+				me->io_pending = PR_FALSE;
+				me->state = _PR_RUNNING;
+				if (_PR_PENDING_INTERRUPT(me)) {
+					me->flags &= ~_PR_INTERRUPT;
+					PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+					_PR_THREAD_UNLOCK(me);
+					return PR_FAILURE;
+				}
+				_PR_THREAD_UNLOCK(me);
+
+                return PR_SUCCESS; 
+            }
+        }
+    }
+#endif /* _NEED_351_FILE_LOCKING_HACK */
+
+    if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        return PR_FAILURE;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_LOCKF_ERROR(me->md.blocked_io_error);
+        return PR_FAILURE;
+    }
+
+    return PR_SUCCESS;
+}
+
+
+PRStatus
+_PR_MD_UNLOCKFILE(PROsfd f)
+{
+    PRInt32 rv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+
+    rv = UnlockFileEx((HANDLE)f,
+                      0,
+                      0x7fffffff,
+                      0,
+                      &me->md.overlapped.overlapped);
+
+    if (rv)
+        return PR_SUCCESS;
+    else {
+        int err = GetLastError();
+		_PR_MD_MAP_LOCKF_ERROR(err);
+        return PR_FAILURE;
+    }
+}
+
+void
+_PR_MD_MAKE_NONBLOCK(PRFileDesc *f)
+{
+    /*
+     * On NT, we either call _md_Associate() or _md_MakeNonblock(),
+     * depending on whether the socket is blocking or not.
+     *
+     * Once we associate a socket with the io completion port,
+     * there is no way to disassociate it from the io completion
+     * port.  So we have to call _md_Associate/_md_MakeNonblock
+     * lazily.
+     */
+}
+
+#ifdef _NEED_351_FILE_LOCKING_HACK
+/***************
+** 
+** Lockfile hacks
+**
+** The following code is a hack to work around a microsoft bug with lockfile.
+** The problem is that on NT 3.51, if LockFileEx() succeeds, you never
+** get a completion back for files that are on local disks.  So, we need to
+** know if a file is local or remote so we can tell if we should expect 
+** a completion.
+**
+** The only way to check if a file is local or remote based on the handle is
+** to get the serial number for the volume it is mounted on and then to 
+** compare that with mounted drives.  This code caches the volume numbers of
+** fixed disks and does a relatively quick check.
+**
+** Locking:  Since the only thing we ever do when multithreaded is a 32bit
+**           assignment, we probably don't need locking.  It is included just
+**           case anyway.
+**
+** Limitations:  Does not work on floppies because they are too slow
+**               Unknown if it will work on wierdo 3rd party file systems
+**
+****************
+*/
+
+/* There can only be 26 drive letters on NT */
+#define _PR_MAX_DRIVES 26
+
+_MDLock cachedVolumeLock;
+DWORD dwCachedVolumeSerialNumbers[_PR_MAX_DRIVES] = {0};
+DWORD dwLastCachedDrive = 0;
+DWORD dwRemoveableDrivesToCheck = 0; /* bitmask for removeable drives */
+
+PRBool IsFileLocalInit()
+{
+   TCHAR lpBuffer[_PR_MAX_DRIVES*5];
+   DWORD nBufferLength = _PR_MAX_DRIVES*5;
+   DWORD nBufferNeeded = GetLogicalDriveStrings(0, NULL);
+   DWORD dwIndex = 0;
+   DWORD dwDriveType;
+   DWORD dwVolumeSerialNumber;
+   DWORD dwDriveIndex = 0;
+   DWORD oldmode = (DWORD) -1;
+
+   _MD_NEW_LOCK(&cachedVolumeLock);
+
+   nBufferNeeded = GetLogicalDriveStrings(nBufferLength, lpBuffer);
+   if (nBufferNeeded == 0 || nBufferNeeded > nBufferLength)
+      return PR_FALSE;
+
+   // Calling GetVolumeInformation on a removeable drive where the
+   // disk is currently removed will cause a dialog box to the
+   // console.  This is not good.
+   // Temporarily disable the SEM_FAILCRITICALERRORS to avoid the
+   // damn dialog.
+
+   dwCachedVolumeSerialNumbers[dwDriveIndex] = 0;
+   oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
+
+   // now loop through the logical drives
+   while(lpBuffer[dwIndex] != TEXT('\0'))
+   {
+      // skip the floppy drives.  This is *SLOW*
+      if ((lpBuffer[dwIndex] == TEXT('A')) || (lpBuffer[dwIndex] == TEXT('B')))
+         /* Skip over floppies */;
+      else
+      {
+         dwDriveIndex = (lpBuffer[dwIndex] - TEXT('A'));
+
+         dwDriveType = GetDriveType(&lpBuffer[dwIndex]);
+
+         switch(dwDriveType)
+         {
+               // Ignore these drive types
+            case 0:
+            case 1:
+            case DRIVE_REMOTE:
+            default: // If the drive type is unknown, ignore it.
+               break;
+
+               // Removable media drives can have different serial numbers
+               // at different times, so cache the current serial number
+               // but keep track of them so they can be rechecked if necessary.
+            case DRIVE_REMOVABLE:
+
+               // CDROM is a removable media
+            case DRIVE_CDROM: 
+
+               // no idea if ramdisks can change serial numbers or not
+               // but it doesn't hurt to treat them as removable.
+              
+            case DRIVE_RAMDISK: 
+
+
+               // Here is where we keep track of removable drives.
+               dwRemoveableDrivesToCheck |= 1 << dwDriveIndex;
+
+               // removable drives fall through to fixed drives and get cached.
+
+            case DRIVE_FIXED:
+
+               // cache volume serial numbers. 
+               if (GetVolumeInformation(
+                   &lpBuffer[dwIndex],
+                   NULL, 0,
+                   &dwVolumeSerialNumber,
+                   NULL, NULL, NULL, 0)
+                  )
+                  {
+                     if (dwLastCachedDrive < dwDriveIndex)
+                        dwLastCachedDrive = dwDriveIndex;
+                     dwCachedVolumeSerialNumbers[dwDriveIndex] = dwVolumeSerialNumber;
+                  }
+ 
+               break;
+         }
+      }
+
+      dwIndex += lstrlen(&lpBuffer[dwIndex]) +1;
+   }
+
+   if (oldmode != (DWORD) -1) {
+       SetErrorMode(oldmode);
+       oldmode = (DWORD) -1;
+   }
+
+   return PR_TRUE;
+}
+
+PRInt32 IsFileLocal(HANDLE hFile)
+{
+   DWORD dwIndex = 0, dwMask;
+   BY_HANDLE_FILE_INFORMATION Info;
+   TCHAR szDrive[4] = TEXT("C:\\");
+   DWORD dwVolumeSerialNumber;
+   DWORD oldmode = (DWORD) -1;
+   int rv = _PR_REMOTE_FILE;
+
+   if (!GetFileInformationByHandle(hFile, &Info))
+      return -1;
+
+   // look to see if the volume serial number has been cached.
+   _MD_LOCK(&cachedVolumeLock);
+   while(dwIndex <= dwLastCachedDrive)
+      if (dwCachedVolumeSerialNumbers[dwIndex++] == Info.dwVolumeSerialNumber)
+      {
+         _MD_UNLOCK(&cachedVolumeLock);
+         return _PR_LOCAL_FILE;
+      }
+   _MD_UNLOCK(&cachedVolumeLock);
+
+   // volume serial number not found in the cache.  Check removable files.
+   // removable drives are noted as a bitmask.  If the bit associated with 
+   // a specific drive is set, then we should query its volume serial number
+   // as its possible it has changed.
+   dwMask = dwRemoveableDrivesToCheck;
+   dwIndex = 0;
+
+   while(dwMask)
+   {
+      while(!(dwMask & 1))
+      {
+         dwIndex++;
+         dwMask = dwMask >> 1;
+      }
+
+      szDrive[0] = TEXT('A')+ (TCHAR) dwIndex;
+
+      // Calling GetVolumeInformation on a removeable drive where the
+      // disk is currently removed will cause a dialog box to the
+      // console.  This is not good.
+      // Temporarily disable the SEM_FAILCRITICALERRORS to avoid the
+      // dialog.
+
+      oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
+
+      if (GetVolumeInformation(
+                  szDrive,
+                  NULL, 0,
+                  &dwVolumeSerialNumber,
+                  NULL, NULL, NULL, 0)
+         )
+      {
+         if (dwVolumeSerialNumber == Info.dwVolumeSerialNumber)
+         {
+            _MD_LOCK(&cachedVolumeLock);
+            if (dwLastCachedDrive < dwIndex)
+               dwLastCachedDrive = dwIndex;
+            dwCachedVolumeSerialNumbers[dwIndex] = dwVolumeSerialNumber;
+            _MD_UNLOCK(&cachedVolumeLock);
+            rv = _PR_LOCAL_FILE;
+         }
+      }
+      if (oldmode != (DWORD) -1) {
+          SetErrorMode(oldmode);
+          oldmode = (DWORD) -1;
+      }
+
+      if (rv == _PR_LOCAL_FILE)
+          return _PR_LOCAL_FILE;
+
+      dwIndex++;
+      dwMask = dwMask >> 1;
+   }
+
+   return _PR_REMOTE_FILE;
+}
+#endif /* _NEED_351_FILE_LOCKING_HACK */
+
+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) ||
+					(me->io_fd != bottom->secret->md.osfd)) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return PR_FAILURE;
+    }
+	/*
+	 * The CancelIO operation has to be issued by the same NT thread that
+	 * issued the I/O operation
+	 */
+	PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || (me->cpu == me->md.thr_bound_cpu));
+	if (me->io_pending) {
+		if (!CancelIo((HANDLE)bottom->secret->md.osfd)) {
+			PR_SetError(PR_INVALID_STATE_ERROR, GetLastError());
+			return PR_FAILURE;
+		}
+	}
+	_PR_THREAD_LOCK(me);
+	fWait = me->io_pending;
+	me->io_suspended = PR_FALSE;
+	me->state = _PR_IO_WAIT;
+	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);
+
+	_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);
+	return PR_SUCCESS;
+}
+
+static PROsfd _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr *addr, int *addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    SOCKET sock;
+    PRInt32 rv, err;
+    fd_set rd;
+    struct timeval tv, *tvp;
+
+    FD_ZERO(&rd);
+    FD_SET((SOCKET)osfd, &rd);
+    if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+        while ((sock = accept(osfd, addr, addrlen)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL,
+                        NULL)) == -1) {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    break;
+                }
+            } else {
+                _PR_MD_MAP_ACCEPT_ERROR(err);
+                break;
+            }
+        }
+    } else if (timeout == PR_INTERVAL_NO_WAIT) {
+        if ((sock = accept(osfd, addr, addrlen)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            } else {
+                _PR_MD_MAP_ACCEPT_ERROR(err);
+            }
+        }
+    } else {
+retry:
+        if ((sock = accept(osfd, addr, addrlen)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                    timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+
+                rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, tvp);
+                if (rv > 0) {
+                    goto retry;
+                } else if (rv == 0) {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                } else {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                }
+            } else {
+                _PR_MD_MAP_ACCEPT_ERROR(err);
+            }
+        }
+    }
+    return (PROsfd)sock;
+}
+
+static PRInt32 _nt_nonblock_connect(PRFileDesc *fd, struct sockaddr *addr, int addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv;
+    int err;
+    fd_set wr, ex;
+    struct timeval tv, *tvp;
+    int len;
+
+    if ((rv = connect(osfd, addr, addrlen)) == -1) {
+        if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) {
+            if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                    timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            FD_ZERO(&wr);
+            FD_ZERO(&ex);
+            FD_SET((SOCKET)osfd, &wr);
+            FD_SET((SOCKET)osfd, &ex);
+            if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wr, &ex,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                return rv;
+            }
+            if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                return -1;
+            }
+            /* Call Sleep(0) to work around a Winsock timeing bug. */
+            Sleep(0);
+            if (FD_ISSET((SOCKET)osfd, &ex)) {
+                len = sizeof(err);
+                if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
+                        (char *) &err, &len) == SOCKET_ERROR) {
+                    _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+                    return -1;
+                }
+                _PR_MD_MAP_CONNECT_ERROR(err);
+                return -1;
+            } 
+            PR_ASSERT(FD_ISSET((SOCKET)osfd, &wr));
+            rv = 0;
+        } else {
+            _PR_MD_MAP_CONNECT_ERROR(err);
+        }
+    }
+    return rv;
+}
+
+static PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    struct timeval tv, *tvp;
+    fd_set rd;
+    int osflags;
+
+    if (0 == flags) {
+        osflags = 0;
+    } else {
+        PR_ASSERT(PR_MSG_PEEK == flags);
+        osflags = MSG_PEEK;
+    }
+    while ((rv = recv(osfd,buf,len,osflags)) == -1) {
+        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                && (!fd->secret->nonblocking)) {
+            FD_ZERO(&rd);
+            FD_SET((SOCKET)osfd, &rd);
+            if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                break;
+            } else if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                rv = -1;
+                break;
+            }
+        } else {
+            _PR_MD_MAP_RECV_ERROR(err);
+            break;
+        }
+    }
+    return(rv);
+}
+
+static PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    struct timeval tv, *tvp;
+    fd_set wd;
+    PRInt32 bytesSent = 0;
+
+    while(bytesSent < len) {
+        while ((rv = send(osfd,buf,len,0)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                    tvp = NULL;
+                } else {
+                    tv.tv_sec = PR_IntervalToSeconds(timeout);
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        timeout - PR_SecondsToInterval(tv.tv_sec));
+                    tvp = &tv;
+                }
+                FD_ZERO(&wd);
+                FD_SET((SOCKET)osfd, &wd);
+                if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL,
+                        tvp)) == -1) {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    return -1;
+                }
+                if (rv == 0) {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                    return -1;
+                }
+            } else {
+                _PR_MD_MAP_SEND_ERROR(err);
+                return -1;
+            }
+        }
+        bytesSent += rv;
+        if (fd->secret->nonblocking) {
+            break;
+        }
+        if (bytesSent < len) {
+            if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                    timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            FD_ZERO(&wd);
+            FD_SET((SOCKET)osfd, &wd);
+            if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                return -1;
+            }
+            if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                return -1;
+            }
+        }
+    }
+    return bytesSent;
+}
+
+static PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime timeout)
+{
+    int index;
+    int sent = 0;
+    int rv;
+
+    for (index=0; index<size; index++) {
+        rv = _nt_nonblock_send(fd, iov[index].iov_base, iov[index].iov_len, timeout);
+        if (rv > 0) 
+            sent += rv;
+        if ( rv != iov[index].iov_len ) {
+            if (rv < 0) {
+                if (fd->secret->nonblocking
+                        && (PR_GetError() == PR_WOULD_BLOCK_ERROR)
+                        && (sent > 0)) {
+                    return sent;
+                } else {
+                    return -1;
+                }
+            }
+            /* Only a nonblocking socket can have partial sends */
+            PR_ASSERT(fd->secret->nonblocking);
+            return sent;
+        }
+    }
+
+    return sent;
+}
+
+static PRInt32 _nt_nonblock_sendto(
+    PRFileDesc *fd, const char *buf, int len,
+    const struct sockaddr *addr, int addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    struct timeval tv, *tvp;
+    fd_set wd;
+    PRInt32 bytesSent = 0;
+
+    while(bytesSent < len) {
+        while ((rv = sendto(osfd,buf,len,0, addr, addrlen)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                    tvp = NULL;
+                } else {
+                    tv.tv_sec = PR_IntervalToSeconds(timeout);
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        timeout - PR_SecondsToInterval(tv.tv_sec));
+                    tvp = &tv;
+                }
+                FD_ZERO(&wd);
+                FD_SET((SOCKET)osfd, &wd);
+                if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL,
+                        tvp)) == -1) {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    return -1;
+                }
+                if (rv == 0) {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                    return -1;
+                }
+            } else {
+                _PR_MD_MAP_SENDTO_ERROR(err);
+                return -1;
+            }
+        }
+        bytesSent += rv;
+        if (fd->secret->nonblocking) {
+            break;
+        }
+        if (bytesSent < len) {
+            if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                    timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            FD_ZERO(&wd);
+            FD_SET((SOCKET)osfd, &wd);
+            if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                return -1;
+            }
+            if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                return -1;
+            }
+        }
+    }
+    return bytesSent;
+}
+
+static PRInt32 _nt_nonblock_recvfrom(PRFileDesc *fd, char *buf, int len, struct sockaddr *addr, int *addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    struct timeval tv, *tvp;
+    fd_set rd;
+
+    while ((rv = recvfrom(osfd,buf,len,0,addr, addrlen)) == -1) {
+        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                && (!fd->secret->nonblocking)) {
+            if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            FD_ZERO(&rd);
+            FD_SET((SOCKET)osfd, &rd);
+            if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                break;
+            } else if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                rv = -1;
+                break;
+            }
+        } else {
+            _PR_MD_MAP_RECVFROM_ERROR(err);
+            break;
+        }
+    }
+    return(rv);
+}
+
+/*
+ * UDP support: the continuation thread functions and recvfrom and sendto.
+ */
+
+static void pt_InsertTimedInternal(pt_Continuation *op)
+{
+    PRInt32 delta = 0;
+    pt_Continuation *t_op = NULL;
+    PRIntervalTime now = PR_IntervalNow(), op_tmo, qd_tmo;
+
+    /*
+     * If this element operation isn't timed, it gets queued at the
+     * end of the list (just after pt_tq.tail) and we're
+     * finishd early.
+     */
+    if (PR_INTERVAL_NO_TIMEOUT == op->timeout)
+    {
+        t_op = pt_tq.tail;  /* put it at the end */
+        goto done;
+    }
+
+    /*
+     * The rest of this routine actaully deals with timed ops.
+     */
+
+    if (NULL != pt_tq.op)
+    {
+        /*
+         * To find where in the list to put the new operation, form
+         * the absolute time the operations in question will expire.
+         *
+         * The new operation ('op') will expire at now() + op->timeout.
+         *
+         * The operation that will time out furthest in the future will
+         * do so at pt_tq.epoch + pt_tq.op->timeout.
+         *
+         * Subsequently earlier timeouts are computed based on the latter
+         * knowledge by subracting the timeout deltas that are stored in
+         * the operation list. There are operation[n]->timeout ticks
+         * between the expiration of operation[n-1] and operation[n].e e 
+         *
+         * Therefore, the operation[n-1] will expire operation[n]->timeout
+         * ticks prior to operation[n].
+         *
+         * This should be easy!
+         */
+        t_op = pt_tq.op;  /* running pointer to queued op */
+        op_tmo = now + op->timeout;  /* that's in absolute ticks */
+        qd_tmo = pt_tq.epoch + t_op->timeout;  /* likewise */
+
+        do
+        {
+            /*
+             * If 'op' expires later than t_op, then insert 'op' just
+             * ahead of t_op. Otherwise, compute when operation[n-1]
+             * expires and try again.
+             *
+             * The actual different between the expiriation of 'op'
+             * and the current operation what becomes the new operaton's
+             * timeout interval. That interval is also subtracted from
+             * the interval of the operation immediately following where
+             * we stick 'op' (unless the next one isn't timed). The new
+             * timeout assigned to 'op' takes into account the values of
+             * now() and when the previous intervals were compured.
+             */
+            delta = op_tmo - qd_tmo;
+            if (delta >= 0)
+            {
+                op->timeout += (now - pt_tq.epoch);
+                goto done;
+            }
+
+            qd_tmo -= t_op->timeout;  /* previous operaton expiration */
+            t_op = t_op->prev;  /* point to previous operation */
+            if (NULL != t_op) qd_tmo += t_op->timeout;
+        } while (NULL != t_op);
+
+        /*
+         * If we got here we backed off the head of the list. That means that
+         * this timed entry has to go at the head of the list. This is just
+         * about like having an empty timer list.
+         */
+        delta = op->timeout;  /* $$$ is this right? */
+    }
+
+done:
+
+    /*
+     * Insert 'op' into the queue just after t_op or if t_op is null,
+     * at the head of the list.
+     *
+     * If t_op is NULL, the list is currently empty and this is pretty
+     * easy.
+     */
+    if (NULL == t_op)
+    {
+        op->prev = NULL;
+        op->next = pt_tq.head;
+        pt_tq.head = op;
+        if (NULL == pt_tq.tail) pt_tq.tail = op;
+        else op->next->prev = op;
+    }
+    else
+    {
+        op->prev = t_op;
+        op->next = t_op->next;
+        if (NULL != op->prev)
+            op->prev->next = op;
+        if (NULL != op->next)
+            op->next->prev = op;
+        if (t_op == pt_tq.tail)
+            pt_tq.tail = op;
+    }
+
+    /*
+     * Are we adjusting our epoch, etc? Are we replacing
+     * what was previously the element due to expire furthest
+     * out in the future? Is this even a timed operation?
+     */
+    if (PR_INTERVAL_NO_TIMEOUT != op->timeout)
+    {
+        if ((NULL == pt_tq.op)  /* we're the one and only */
+        || (t_op == pt_tq.op))  /* we're replacing */
+        {
+            pt_tq.op = op;
+            pt_tq.epoch = now;
+        }
+    }
+
+    pt_tq.op_count += 1;
+
+}  /* pt_InsertTimedInternal */
+
+/*
+ * function: pt_FinishTimed
+ *
+ * Takes the finished operation out of the timed queue. It
+ * notifies the initiating thread that the opertions is
+ * complete and returns to the caller the value of the next
+ * operation in the list (or NULL).
+ */
+static pt_Continuation *pt_FinishTimedInternal(pt_Continuation *op)
+{
+    pt_Continuation *next;
+
+    /* remove this one from the list */
+    if (NULL == op->prev) pt_tq.head = op->next;
+    else op->prev->next = op->next;
+    if (NULL == op->next) pt_tq.tail = op->prev;
+    else op->next->prev = op->prev;
+
+    /* did we happen to hit the timed op? */
+    if (op == pt_tq.op) pt_tq.op = op->prev;
+
+    next = op->next;
+    op->next = op->prev = NULL;
+    op->status = pt_continuation_done;
+
+    pt_tq.op_count -= 1;
+#if defined(DEBUG)
+    pt_debug.continuationsServed += 1;
+#endif
+    PR_NotifyCondVar(op->complete);
+
+    return next;
+}  /* pt_FinishTimedInternal */
+
+static void ContinuationThread(void *arg)
+{
+    /* initialization */
+    fd_set readSet, writeSet, exceptSet;
+    struct timeval tv;
+    SOCKET *pollingList = 0;                /* list built for polling */
+    PRIntn pollingListUsed;                 /* # entries used in the list */
+    PRIntn pollingListNeeded;               /* # entries needed this time */
+    PRIntn pollingSlotsAllocated = 0;       /* # entries available in list */
+    PRIntervalTime mx_select_ticks = PR_MillisecondsToInterval(PT_DEFAULT_SELECT_MSEC);
+
+    /* do some real work */
+    while (1)
+    {
+        PRIntn rv;
+        PRStatus status;
+        PRIntn pollIndex;
+        pt_Continuation *op;
+        PRIntervalTime now = PR_IntervalNow();
+        PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+
+        PR_Lock(pt_tq.ml);
+        while (NULL == pt_tq.head)
+        {
+            status = PR_WaitCondVar(pt_tq.new_op, PR_INTERVAL_NO_TIMEOUT);
+            if ((PR_FAILURE == status)
+                && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
+        }
+        pollingListNeeded = pt_tq.op_count;
+        PR_Unlock(pt_tq.ml);
+
+        /* Okay. We're history */
+        if ((PR_FAILURE == status)
+            && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
+
+	/*
+	 * We are not holding the pt_tq.ml lock now, so more items may
+	 * get added to pt_tq during this window of time.  We hope
+	 * that 10 more spaces in the polling list should be enough.
+	 */
+
+        FD_ZERO(&readSet);
+        FD_ZERO(&writeSet);
+        FD_ZERO(&exceptSet);
+        pollingListNeeded += 10;
+        if (pollingListNeeded > pollingSlotsAllocated)
+        {
+            if (NULL != pollingList) PR_DELETE(pollingList);
+            pollingList = PR_MALLOC(pollingListNeeded * sizeof(PRPollDesc));
+            PR_ASSERT(NULL != pollingList);
+            pollingSlotsAllocated = pollingListNeeded;
+        }
+
+#if defined(DEBUG)
+        if (pollingListNeeded > pt_debug.pollingListMax)
+            pt_debug.pollingListMax = pollingListUsed;
+#endif
+
+        /*
+         * Build up a polling list.
+         * This list is sorted on time. Operations that have been
+         * interrupted are completed and not included in the list.
+         * There is an assertion that the operation is in progress.
+         */
+        pollingListUsed = 0;
+        PR_Lock(pt_tq.ml);
+
+        for (op = pt_tq.head; NULL != op;)
+        {
+            if (pt_continuation_abort == op->status)
+            {
+                op->result.code = -1;
+                op->syserrno = WSAEINTR;
+                op = pt_FinishTimedInternal(op);
+            }
+            else
+            {
+                PR_ASSERT(pt_continuation_done != op->status);
+                op->status = pt_continuation_inprogress;
+                if (op->event & PR_POLL_READ) {
+                    FD_SET(op->arg1.osfd, &readSet);
+                }
+                if (op->event & PR_POLL_WRITE) {
+                    FD_SET(op->arg1.osfd, &writeSet);
+                }
+                if (op->event & PR_POLL_EXCEPT) {
+                    FD_SET(op->arg1.osfd, &exceptSet);
+                }
+                pollingList[pollingListUsed] = op->arg1.osfd;
+                pollingListUsed += 1;
+                if (pollingListUsed == pollingSlotsAllocated) break;
+                op = op->next;
+            }
+        }
+
+        PR_Unlock(pt_tq.ml);
+
+        /*
+         * If 'op' isn't NULL at this point, then we didn't get to
+         * the end of the list. That means that more items got added
+         * to the list than we anticipated. So, forget this iteration,
+         * go around the horn again.
+         * One would hope this doesn't happen all that often.
+         */
+        if (NULL != op)
+        {
+#if defined(DEBUG)
+            pt_debug.predictionsFoiled += 1;  /* keep track */
+#endif
+            continue;  /* make it rethink things */
+        }
+
+        /* there's a chance that all ops got blown away */
+        if (NULL == pt_tq.head) continue;
+        /* if not, we know this is the shortest timeout */
+        timeout = pt_tq.head->timeout;
+
+        /*
+         * We don't want to wait forever on this poll. So keep
+         * the interval down. The operations, if they are timed,
+         * still have to timeout, while those that are not timed
+         * should persist forever. But they may be aborted. That's
+         * what this anxiety is all about.
+         */
+        if (timeout > mx_select_ticks) timeout = mx_select_ticks;
+
+        if (PR_INTERVAL_NO_TIMEOUT != pt_tq.head->timeout)
+            pt_tq.head->timeout -= timeout;
+        tv.tv_sec = PR_IntervalToSeconds(timeout);
+        tv.tv_usec = PR_IntervalToMicroseconds(timeout) % PR_USEC_PER_SEC;
+
+        rv = select(0, &readSet, &writeSet, &exceptSet, &tv);
+
+        if (0 == rv)  /* poll timed out - what about leading op? */
+        {
+            if (0 == pt_tq.head->timeout)
+            {
+                /* 
+                 * The leading element of the timed queue has timed
+                 * out. Get rid of it. In any case go around the
+                 * loop again, computing the polling list, checking
+                 * for interrupted operations.
+                 */
+                PR_Lock(pt_tq.ml);
+                do
+                {
+                    pt_tq.head->result.code = -1;
+                    pt_tq.head->syserrno = WSAETIMEDOUT;
+                    op = pt_FinishTimedInternal(pt_tq.head);
+                } while ((NULL != op) && (0 == op->timeout));
+                PR_Unlock(pt_tq.ml);
+            }
+            continue;
+        }
+
+        if (-1 == rv && (WSAGetLastError() == WSAEINTR
+                || WSAGetLastError() == WSAEINPROGRESS))
+        {
+            continue;               /* go around the loop again */
+        }
+
+        /*
+         * select() says that something in our list is ready for some more
+         * action or is an invalid fd. Find it, load up the operation and
+         * see what happens.
+         */
+
+        PR_ASSERT(rv > 0 || WSAGetLastError() == WSAENOTSOCK);
+
+
+        /*
+         * $$$ There's a problem here. I'm running the operations list
+         * and I'm not holding any locks. I don't want to hold the lock
+         * and do the operation, so this is really messed up..
+         *
+         * This may work out okay. The rule is that only this thread,
+         * the continuation thread, can remove elements from the list.
+         * Therefore, the list is at worst, longer than when we built
+         * the polling list.
+         */
+        op = pt_tq.head;
+        for (pollIndex = 0; pollIndex < pollingListUsed; ++pollIndex)
+        {
+            PRInt16 revents = 0;
+
+            PR_ASSERT(NULL != op);
+
+            /*
+             * This one wants attention. Redo the operation.
+             * We know that there can only be more elements
+             * in the op list than we knew about when we created
+             * the poll list. Therefore, we might have to skip
+             * a few ops to find the right one to operation on.
+             */
+            while (pollingList[pollIndex] != op->arg1.osfd )
+            {
+                op = op->next;
+                PR_ASSERT(NULL != op);
+            }
+
+            if (FD_ISSET(op->arg1.osfd, &readSet)) {
+                revents |= PR_POLL_READ;
+            }
+            if (FD_ISSET(op->arg1.osfd, &writeSet)) {
+                revents |= PR_POLL_WRITE;
+            }
+            if (FD_ISSET(op->arg1.osfd, &exceptSet)) {
+                revents |= PR_POLL_EXCEPT;
+            }
+
+            /*
+             * Sip over all those not in progress. They'll be
+             * pruned next time we build a polling list. Call
+             * the continuation function. If it reports completion,
+             * finish off the operation.
+             */
+            if (revents && (pt_continuation_inprogress == op->status)
+                && (op->function(op, revents)))
+            {
+                PR_Lock(pt_tq.ml);
+                op = pt_FinishTimedInternal(op);
+                PR_Unlock(pt_tq.ml);
+            }
+        }
+    }
+    if (NULL != pollingList) PR_DELETE(pollingList);
+}  /* ContinuationThread */
+
+static int pt_Continue(pt_Continuation *op)
+{
+    PRStatus rv;
+    /* Finish filling in the blank slots */
+    op->status = pt_continuation_sumbitted;
+    op->complete = PR_NewCondVar(pt_tq.ml);
+
+    PR_Lock(pt_tq.ml);  /* we provide the locking */
+
+    pt_InsertTimedInternal(op);  /* insert in the structure */
+
+    PR_NotifyCondVar(pt_tq.new_op);  /* notify the continuation thread */
+
+    while (pt_continuation_done != op->status)  /* wait for completion */
+    {
+        rv = PR_WaitCondVar(op->complete, PR_INTERVAL_NO_TIMEOUT);
+        /*
+         * If we get interrupted, we set state the continuation thread will
+         * see and allow it to finish the I/O operation w/ error. That way
+         * the rule that only the continuation thread is removing elements
+         * from the list is still valid.
+         *
+         * Don't call interrupt on the continuation thread. That'll just
+         * piss him off. He's cycling around at least every mx_select_ticks
+         * anyhow and should notice the request in there.
+         */
+        if ((PR_FAILURE == rv)
+            && (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
+            op->status = pt_continuation_abort;  /* our status */
+    }
+
+    PR_Unlock(pt_tq.ml);  /* we provide the locking */
+
+    PR_DestroyCondVar(op->complete);
+
+    return op->result.code;  /* and the primary answer */
+}  /* pt_Continue */
+
+static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes = sendto(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags,
+        (struct sockaddr*)op->arg5.addr, sizeof(*(op->arg5.addr)));
+    op->syserrno = WSAGetLastError();
+    if (bytes > 0)  /* this is progress */
+    {
+        char *bp = op->arg2.buffer;
+        bp += bytes;  /* adjust the buffer pointer */
+        op->arg2.buffer = bp;
+        op->result.code += bytes;  /* accumulate the number sent */
+        op->arg3.amount -= bytes;  /* and reduce the required count */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else return ((-1 == bytes) && (WSAEWOULDBLOCK == op->syserrno)) ?
+	PR_FALSE : PR_TRUE;
+}  /* pt_sendto_cont */
+
+static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn addr_len = sizeof(*(op->arg5.addr));
+    op->result.code = recvfrom(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount,
+        op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len);
+    op->syserrno = WSAGetLastError();
+    return ((-1 == op->result.code) && (WSAEWOULDBLOCK == op->syserrno)) ?
+        PR_FALSE : PR_TRUE;
+}  /* pt_recvfrom_cont */
+
+static PRInt32 pt_SendTo(
+    SOCKET osfd, const void *buf,
+    PRInt32 amount, PRInt32 flags, const PRNetAddr *addr,
+    PRIntn addrlen, PRIntervalTime timeout)
+{
+    PRInt32 bytes = -1, err;
+    PRBool fNeedContinue = PR_FALSE;
+
+    bytes = sendto(
+            osfd, buf, amount, flags,
+            (struct sockaddr*)addr, PR_NETADDR_SIZE(addr));
+    if (bytes == -1) {
+		if ((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+        fNeedContinue = PR_TRUE;
+		else
+			_PR_MD_MAP_SENDTO_ERROR(err);
+    }
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = osfd;
+        op.arg2.buffer = (void*)buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.arg5.addr = (PRNetAddr*)addr;
+        op.timeout = timeout;
+        op.result.code = 0;  /* initialize the number sent */
+        op.function = pt_sendto_cont;
+        op.event = PR_POLL_WRITE | PR_POLL_EXCEPT;
+        bytes = pt_Continue(&op);
+        if (bytes < 0) {
+            WSASetLastError(op.syserrno);
+			_PR_MD_MAP_SENDTO_ERROR(op.syserrno);
+        }
+    }
+    return bytes;
+}  /* pt_SendTo */
+
+static PRInt32 pt_RecvFrom(SOCKET osfd, void *buf, PRInt32 amount,
+    PRInt32 flags, PRNetAddr *addr, PRIntn *addr_len, PRIntervalTime timeout)
+{
+    PRInt32 bytes = -1, err;
+    PRBool fNeedContinue = PR_FALSE;
+
+    bytes = recvfrom(
+            osfd, buf, amount, flags,
+            (struct sockaddr*)addr, addr_len);
+    if (bytes == -1) {
+		if ((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+        fNeedContinue = PR_TRUE;
+		else
+			_PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = osfd;
+        op.arg2.buffer = buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.arg5.addr = addr;
+        op.timeout = timeout;
+        op.function = pt_recvfrom_cont;
+        op.event = PR_POLL_READ | PR_POLL_EXCEPT;
+        bytes = pt_Continue(&op);
+        if (bytes < 0) {
+            WSASetLastError(op.syserrno);
+			_PR_MD_MAP_RECVFROM_ERROR(op.syserrno);
+        }
+    }
+    return bytes;
+}  /* pt_RecvFrom */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntmisc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntmisc.c
new file mode 100644
index 0000000..c47b599
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntmisc.c
@@ -0,0 +1,1208 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * ntmisc.c
+ *
+ */
+
+#include "primpl.h"
+#include <math.h>     /* for fabs() */
+#include <windows.h>
+
+char *_PR_MD_GET_ENV(const char *name)
+{
+    return getenv(name);
+}
+
+/*
+** _PR_MD_PUT_ENV() -- add or change environment variable
+**
+**
+*/
+PRIntn _PR_MD_PUT_ENV(const char *name)
+{
+    return(putenv(name));
+}
+
+
+/*
+ **************************************************************************
+ **************************************************************************
+ **
+ **     Date and time routines
+ **
+ **************************************************************************
+ **************************************************************************
+ */
+
+/*
+ * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
+ * We store the value in a PRTime variable for convenience.
+ */
+#ifdef __GNUC__
+const PRTime _pr_filetime_offset = 116444736000000000LL;
+const PRTime _pr_filetime_divisor = 10LL;
+#else
+const PRTime _pr_filetime_offset = 116444736000000000i64;
+const PRTime _pr_filetime_divisor = 10i64;
+#endif
+
+#ifdef WINCE
+
+#define FILETIME_TO_INT64(ft) \
+  (((PRInt64)ft.dwHighDateTime) << 32 | (PRInt64)ft.dwLowDateTime)
+
+static void
+LowResTime(LPFILETIME lpft)
+{
+    GetCurrentFT(lpft);
+}
+
+typedef struct CalibrationData {
+    long double freq;         /* The performance counter frequency */
+    long double offset;       /* The low res 'epoch' */
+    long double timer_offset; /* The high res 'epoch' */
+
+    /* The last high res time that we returned since recalibrating */
+    PRInt64 last;
+
+    PRBool calibrated;
+
+    CRITICAL_SECTION data_lock;
+    CRITICAL_SECTION calibration_lock;
+    PRInt64 granularity;
+} CalibrationData;
+
+static CalibrationData calibration;
+
+typedef void (*GetSystemTimeAsFileTimeFcn)(LPFILETIME);
+static GetSystemTimeAsFileTimeFcn ce6_GetSystemTimeAsFileTime = NULL;
+
+static void
+NowCalibrate(void)
+{
+    FILETIME ft, ftStart;
+    LARGE_INTEGER liFreq, now;
+
+    if (calibration.freq == 0.0) {
+	if(!QueryPerformanceFrequency(&liFreq)) {
+	    /* High-performance timer is unavailable */
+	    calibration.freq = -1.0;
+	} else {
+	    calibration.freq = (long double) liFreq.QuadPart;
+	}
+    }
+    if (calibration.freq > 0.0) {
+	PRInt64 calibrationDelta = 0;
+	/*
+	 * By wrapping a timeBegin/EndPeriod pair of calls around this loop,
+	 * the loop seems to take much less time (1 ms vs 15ms) on Vista. 
+	 */
+	timeBeginPeriod(1);
+	LowResTime(&ftStart);
+	do {
+	    LowResTime(&ft);
+	} while (memcmp(&ftStart,&ft, sizeof(ft)) == 0);
+	timeEndPeriod(1);
+
+	calibration.granularity = 
+	    (FILETIME_TO_INT64(ft) - FILETIME_TO_INT64(ftStart))/10;
+
+	QueryPerformanceCounter(&now);
+
+	calibration.offset = (long double) FILETIME_TO_INT64(ft);
+	calibration.timer_offset = (long double) now.QuadPart;
+	/*
+	 * The windows epoch is around 1600. The unix epoch is around 1970. 
+	 * _pr_filetime_offset is the difference (in windows time units which
+	 * are 10 times more highres than the JS time unit) 
+	 */
+	calibration.offset -= _pr_filetime_offset;
+	calibration.offset *= 0.1;
+	calibration.last = 0;
+
+	calibration.calibrated = PR_TRUE;
+    }
+}
+
+#define CALIBRATIONLOCK_SPINCOUNT 0
+#define DATALOCK_SPINCOUNT 4096
+#define LASTLOCK_SPINCOUNT 4096
+
+void
+_MD_InitTime(void)
+{
+    /* try for CE6 GetSystemTimeAsFileTime first */
+    HANDLE h = GetModuleHandleW(L"coredll.dll");
+    ce6_GetSystemTimeAsFileTime = (GetSystemTimeAsFileTimeFcn)
+        GetProcAddressA(h, "GetSystemTimeAsFileTime");
+
+    /* otherwise go the slow route */
+    if (ce6_GetSystemTimeAsFileTime == NULL) {
+        memset(&calibration, 0, sizeof(calibration));
+        NowCalibrate();
+        InitializeCriticalSection(&calibration.calibration_lock);
+        InitializeCriticalSection(&calibration.data_lock);
+    }
+}
+
+void
+_MD_CleanupTime(void)
+{
+    if (ce6_GetSystemTimeAsFileTime == NULL) {
+        DeleteCriticalSection(&calibration.calibration_lock);
+        DeleteCriticalSection(&calibration.data_lock);
+    }
+}
+
+#define MUTEX_SETSPINCOUNT(m, c)
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the
+ *     implementation for Windows.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+    long double lowresTime, highresTimerValue;
+    FILETIME ft;
+    LARGE_INTEGER now;
+    PRBool calibrated = PR_FALSE;
+    PRBool needsCalibration = PR_FALSE;
+    PRInt64 returnedTime;
+    long double cachedOffset = 0.0;
+
+    if (ce6_GetSystemTimeAsFileTime) {
+        union {
+            FILETIME ft;
+            PRTime prt;
+        } currentTime;
+
+        PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime));
+
+        ce6_GetSystemTimeAsFileTime(&currentTime.ft);
+
+        /* written this way on purpose, since the second term becomes
+         * a constant, and the entire expression is faster to execute.
+         */
+        return currentTime.prt/_pr_filetime_divisor -
+            _pr_filetime_offset/_pr_filetime_divisor;
+    }
+
+    do {
+	if (!calibration.calibrated || needsCalibration) {
+	    EnterCriticalSection(&calibration.calibration_lock);
+	    EnterCriticalSection(&calibration.data_lock);
+
+	    /* Recalibrate only if no one else did before us */
+	    if (calibration.offset == cachedOffset) {
+		/*
+		 * Since calibration can take a while, make any other
+		 * threads immediately wait 
+		 */
+		MUTEX_SETSPINCOUNT(&calibration.data_lock, 0);
+
+		NowCalibrate();
+
+		calibrated = PR_TRUE;
+
+		/* Restore spin count */
+		MUTEX_SETSPINCOUNT(&calibration.data_lock, DATALOCK_SPINCOUNT);
+	    }
+	    LeaveCriticalSection(&calibration.data_lock);
+	    LeaveCriticalSection(&calibration.calibration_lock);
+	}
+
+	/* Calculate a low resolution time */
+	LowResTime(&ft);
+	lowresTime =
+            ((long double)(FILETIME_TO_INT64(ft) - _pr_filetime_offset)) * 0.1;
+
+	if (calibration.freq > 0.0) {
+	    long double highresTime, diff;
+	    DWORD timeAdjustment, timeIncrement;
+	    BOOL timeAdjustmentDisabled;
+
+	    /* Default to 15.625 ms if the syscall fails */
+	    long double skewThreshold = 15625.25;
+
+	    /* Grab high resolution time */
+	    QueryPerformanceCounter(&now);
+	    highresTimerValue = (long double)now.QuadPart;
+
+	    EnterCriticalSection(&calibration.data_lock);
+	    highresTime = calibration.offset + 1000000L *
+		(highresTimerValue-calibration.timer_offset)/calibration.freq;
+	    cachedOffset = calibration.offset;
+
+	    /* 
+	     * On some dual processor/core systems, we might get an earlier 
+	     * time so we cache the last time that we returned.
+	     */
+	    calibration.last = PR_MAX(calibration.last,(PRInt64)highresTime);
+	    returnedTime = calibration.last;
+	    LeaveCriticalSection(&calibration.data_lock);
+
+	    /* Get an estimate of clock ticks per second from our own test */
+	    skewThreshold = calibration.granularity;
+	    /* Check for clock skew */
+	    diff = lowresTime - highresTime;
+
+	    /* 
+	     * For some reason that I have not determined, the skew can be
+	     * up to twice a kernel tick. This does not seem to happen by
+	     * itself, but I have only seen it triggered by another program
+	     * doing some kind of file I/O. The symptoms are a negative diff
+	     * followed by an equally large positive diff. 
+	     */
+	    if (fabs(diff) > 2*skewThreshold) {
+		if (calibrated) {
+		    /*
+		     * If we already calibrated once this instance, and the
+		     * clock is still skewed, then either the processor(s) are
+		     * wildly changing clockspeed or the system is so busy that
+		     * we get switched out for long periods of time. In either
+		     * case, it would be infeasible to make use of high
+		     * resolution results for anything, so let's resort to old
+		     * behavior for this call. It's possible that in the
+		     * future, the user will want the high resolution timer, so
+		     * we don't disable it entirely. 
+		     */
+		    returnedTime = (PRInt64)lowresTime;
+		    needsCalibration = PR_FALSE;
+		} else {
+		    /*
+		     * It is possible that when we recalibrate, we will return 
+		     * a value less than what we have returned before; this is
+		     * unavoidable. We cannot tell the different between a
+		     * faulty QueryPerformanceCounter implementation and user
+		     * changes to the operating system time. Since we must
+		     * respect user changes to the operating system time, we
+		     * cannot maintain the invariant that Date.now() never
+		     * decreases; the old implementation has this behavior as
+		     * well. 
+		     */
+		    needsCalibration = PR_TRUE;
+		}
+	    } else {
+		/* No detectable clock skew */
+		returnedTime = (PRInt64)highresTime;
+		needsCalibration = PR_FALSE;
+	    }
+	} else {
+	    /* No high resolution timer is available, so fall back */
+	    returnedTime = (PRInt64)lowresTime;
+	}
+    } while (needsCalibration);
+
+    return returnedTime;
+}
+
+#else
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+    PRTime prt;
+    FILETIME ft;
+    SYSTEMTIME st;
+
+    GetSystemTime(&st);
+    SystemTimeToFileTime(&st, &ft);
+    _PR_FileTimeToPRTime(&ft, &prt);
+    return prt;       
+}
+
+#endif
+
+/*
+ ***********************************************************************
+ ***********************************************************************
+ *
+ * Process creation routines
+ *
+ ***********************************************************************
+ ***********************************************************************
+ */
+
+/*
+ * Assemble the command line by concatenating the argv array.
+ * On success, this function returns 0 and the resulting command
+ * line is returned in *cmdLine.  On failure, it returns -1.
+ */
+static int assembleCmdLine(char *const *argv, char **cmdLine)
+{
+    char *const *arg;
+    char *p, *q;
+    size_t cmdLineSize;
+    int numBackslashes;
+    int i;
+    int argNeedQuotes;
+
+    /*
+     * Find out how large the command line buffer should be.
+     */
+    cmdLineSize = 0;
+    for (arg = argv; *arg; arg++) {
+        /*
+         * \ and " need to be escaped by a \.  In the worst case,
+         * every character is a \ or ", so the string of length
+         * may double.  If we quote an argument, that needs two ".
+         * Finally, we need a space between arguments, and
+         * a null byte at the end of command line.
+         */
+        cmdLineSize += 2 * strlen(*arg)  /* \ and " need to be escaped */
+                + 2                      /* we quote every argument */
+                + 1;                     /* space in between, or final null */
+    }
+    p = *cmdLine = PR_MALLOC((PRUint32) cmdLineSize);
+    if (p == NULL) {
+        return -1;
+    }
+
+    for (arg = argv; *arg; arg++) {
+        /* Add a space to separates the arguments */
+        if (arg != argv) {
+            *p++ = ' '; 
+        }
+        q = *arg;
+        numBackslashes = 0;
+        argNeedQuotes = 0;
+
+        /*
+         * If the argument is empty or contains white space, it needs to
+         * be quoted.
+         */
+        if (**arg == '\0' || strpbrk(*arg, " \f\n\r\t\v")) {
+            argNeedQuotes = 1;
+        }
+
+        if (argNeedQuotes) {
+            *p++ = '"';
+        }
+        while (*q) {
+            if (*q == '\\') {
+                numBackslashes++;
+                q++;
+            } else if (*q == '"') {
+                if (numBackslashes) {
+                    /*
+                     * Double the backslashes since they are followed
+                     * by a quote
+                     */
+                    for (i = 0; i < 2 * numBackslashes; i++) {
+                        *p++ = '\\';
+                    }
+                    numBackslashes = 0;
+                }
+                /* To escape the quote */
+                *p++ = '\\';
+                *p++ = *q++;
+            } else {
+                if (numBackslashes) {
+                    /*
+                     * Backslashes are not followed by a quote, so
+                     * don't need to double the backslashes.
+                     */
+                    for (i = 0; i < numBackslashes; i++) {
+                        *p++ = '\\';
+                    }
+                    numBackslashes = 0;
+                }
+                *p++ = *q++;
+            }
+        }
+
+        /* Now we are at the end of this argument */
+        if (numBackslashes) {
+            /*
+             * Double the backslashes if we have a quote string
+             * delimiter at the end.
+             */
+            if (argNeedQuotes) {
+                numBackslashes *= 2;
+            }
+            for (i = 0; i < numBackslashes; i++) {
+                *p++ = '\\';
+            }
+        }
+        if (argNeedQuotes) {
+            *p++ = '"';
+        }
+    } 
+
+    *p = '\0';
+    return 0;
+}
+
+/*
+ * Assemble the environment block by concatenating the envp array
+ * (preserving the terminating null byte in each array element)
+ * and adding a null byte at the end.
+ *
+ * Returns 0 on success.  The resulting environment block is returned
+ * in *envBlock.  Note that if envp is NULL, a NULL pointer is returned
+ * in *envBlock.  Returns -1 on failure.
+ */
+static int assembleEnvBlock(char **envp, char **envBlock)
+{
+    char *p;
+    char *q;
+    char **env;
+    char *curEnv;
+    char *cwdStart, *cwdEnd;
+    size_t envBlockSize;
+
+    if (envp == NULL) {
+        *envBlock = NULL;
+        return 0;
+    }
+
+#ifdef WINCE
+    {
+        PRUnichar *wideCurEnv = mozce_GetEnvString();
+        int len = WideCharToMultiByte(CP_ACP, 0, wideCurEnv, -1,
+                                      NULL, 0, NULL, NULL);
+        curEnv = (char *) PR_MALLOC(len * sizeof(char));
+        WideCharToMultiByte(CP_ACP, 0, wideCurEnv, -1,
+                            curEnv, len, NULL, NULL);
+        free(wideCurEnv);
+    }
+#else
+    curEnv = GetEnvironmentStrings();
+#endif
+
+    cwdStart = curEnv;
+    while (*cwdStart) {
+        if (cwdStart[0] == '=' && cwdStart[1] != '\0'
+                && cwdStart[2] == ':' && cwdStart[3] == '=') {
+            break;
+        }
+        cwdStart += strlen(cwdStart) + 1;
+    }
+    cwdEnd = cwdStart;
+    if (*cwdEnd) {
+        cwdEnd += strlen(cwdEnd) + 1;
+        while (*cwdEnd) {
+            if (cwdEnd[0] != '=' || cwdEnd[1] == '\0'
+                    || cwdEnd[2] != ':' || cwdEnd[3] != '=') {
+                break;
+            }
+            cwdEnd += strlen(cwdEnd) + 1;
+        }
+    }
+    envBlockSize = cwdEnd - cwdStart;
+
+    for (env = envp; *env; env++) {
+        envBlockSize += strlen(*env) + 1;
+    }
+    envBlockSize++;
+
+    p = *envBlock = PR_MALLOC((PRUint32) envBlockSize);
+    if (p == NULL) {
+#ifdef WINCE
+        PR_Free(curEnv);
+#else
+        FreeEnvironmentStrings(curEnv);
+#endif
+        return -1;
+    }
+
+    q = cwdStart;
+    while (q < cwdEnd) {
+        *p++ = *q++;
+    }
+#ifdef WINCE
+    PR_Free(curEnv);
+#else
+    FreeEnvironmentStrings(curEnv);
+#endif
+
+    for (env = envp; *env; env++) {
+        q = *env;
+        while (*q) {
+            *p++ = *q++;
+        }
+        *p++ = '\0';
+    }
+    *p = '\0';
+    return 0;
+}
+
+/*
+ * For qsort.  We sort (case-insensitive) the environment strings
+ * before generating the environment block.
+ */
+static int compare(const void *arg1, const void *arg2)
+{
+    return _stricmp(* (char**)arg1, * (char**)arg2);
+}
+
+PRProcess * _PR_CreateWindowsProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+#ifdef WINCE
+    STARTUPINFOW startupInfo;
+    PRUnichar *wideCmdLine;
+    PRUnichar *wideCwd;
+    int len = 0;
+#else
+    STARTUPINFO startupInfo;
+#endif
+    PROCESS_INFORMATION procInfo;
+    BOOL retVal;
+    char *cmdLine = NULL;
+    char *envBlock = NULL;
+    char **newEnvp = NULL;
+    const char *cwd = NULL; /* current working directory */
+    PRProcess *proc = NULL;
+    PRBool hasFdInheritBuffer;
+
+    proc = PR_NEW(PRProcess);
+    if (!proc) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+    if (assembleCmdLine(argv, &cmdLine) == -1) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+#ifndef WINCE
+    /*
+     * If attr->fdInheritBuffer is not NULL, we need to insert
+     * it into the envp array, so envp cannot be NULL.
+     */
+    hasFdInheritBuffer = (attr && attr->fdInheritBuffer);
+    if ((envp == NULL) && hasFdInheritBuffer) {
+        envp = environ;
+    }
+
+    if (envp != NULL) {
+        int idx;
+        int numEnv;
+        PRBool found = PR_FALSE;
+
+        numEnv = 0;
+        while (envp[numEnv]) {
+            numEnv++;
+        }
+        newEnvp = (char **) PR_MALLOC((numEnv + 2) * sizeof(char *));
+        for (idx = 0; idx < numEnv; idx++) {
+            newEnvp[idx] = envp[idx];
+            if (hasFdInheritBuffer && !found
+                    && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) {
+                newEnvp[idx] = attr->fdInheritBuffer;
+                found = PR_TRUE;
+            }
+        }
+        if (hasFdInheritBuffer && !found) {
+            newEnvp[idx++] = attr->fdInheritBuffer;
+        }
+        newEnvp[idx] = NULL;
+        qsort((void *) newEnvp, (size_t) idx, sizeof(char *), compare);
+    }
+    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+    ZeroMemory(&startupInfo, sizeof(startupInfo));
+    startupInfo.cb = sizeof(startupInfo);
+
+    if (attr) {
+        PRBool redirected = PR_FALSE;
+
+        /*
+         * XXX the default value for stdin, stdout, and stderr
+         * should probably be the console input and output, not
+         * those of the parent process.
+         */
+        startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+        startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+        startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+        if (attr->stdinFd) {
+            startupInfo.hStdInput = (HANDLE) attr->stdinFd->secret->md.osfd;
+            redirected = PR_TRUE;
+        }
+        if (attr->stdoutFd) {
+            startupInfo.hStdOutput = (HANDLE) attr->stdoutFd->secret->md.osfd;
+            redirected = PR_TRUE;
+        }
+        if (attr->stderrFd) {
+            startupInfo.hStdError = (HANDLE) attr->stderrFd->secret->md.osfd;
+            redirected = PR_TRUE;
+        }
+        if (redirected) {
+            startupInfo.dwFlags |= STARTF_USESTDHANDLES;
+        }
+        cwd = attr->currentDirectory;
+    }
+#endif
+
+#ifdef WINCE
+    len = MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, NULL, 0);
+    wideCmdLine = (PRUnichar *)PR_MALLOC(len * sizeof(PRUnichar));
+    MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, wideCmdLine, len);
+    len = MultiByteToWideChar(CP_ACP, 0, cwd, -1, NULL, 0);
+    wideCwd = PR_MALLOC(len * sizeof(PRUnichar));
+    MultiByteToWideChar(CP_ACP, 0, cwd, -1, wideCwd, len);
+    retVal = CreateProcessW(NULL,
+                            wideCmdLine,
+                            NULL,  /* security attributes for the new
+                                    * process */
+                            NULL,  /* security attributes for the primary
+                                    * thread in the new process */
+                            TRUE,  /* inherit handles */
+                            0,     /* creation flags */
+                            envBlock,  /* an environment block, consisting
+                                        * of a null-terminated block of
+                                        * null-terminated strings.  Each
+                                        * string is in the form:
+                                        *     name=value
+                                        * XXX: usually NULL */
+                            wideCwd,  /* current drive and directory */
+                            &startupInfo,
+                            &procInfo
+                           );
+    PR_Free(wideCmdLine);
+    PR_Free(wideCwd);
+#else
+    retVal = CreateProcess(NULL,
+                           cmdLine,
+                           NULL,  /* security attributes for the new
+                                   * process */
+                           NULL,  /* security attributes for the primary
+                                   * thread in the new process */
+                           TRUE,  /* inherit handles */
+                           0,     /* creation flags */
+                           envBlock,  /* an environment block, consisting
+                                       * of a null-terminated block of
+                                       * null-terminated strings.  Each
+                                       * string is in the form:
+                                       *     name=value
+                                       * XXX: usually NULL */
+                           cwd,  /* current drive and directory */
+                           &startupInfo,
+                           &procInfo
+                          );
+#endif
+
+    if (retVal == FALSE) {
+        /* XXX what error code? */
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        goto errorExit;
+    }
+
+    CloseHandle(procInfo.hThread);
+    proc->md.handle = procInfo.hProcess;
+    proc->md.id = procInfo.dwProcessId;
+
+    PR_DELETE(cmdLine);
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+    if (envBlock) {
+        PR_DELETE(envBlock);
+    }
+    return proc;
+
+errorExit:
+    if (cmdLine) {
+        PR_DELETE(cmdLine);
+    }
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+    if (envBlock) {
+        PR_DELETE(envBlock);
+    }
+    if (proc) {
+        PR_DELETE(proc);
+    }
+    return NULL;
+}  /* _PR_CreateWindowsProcess */
+
+PRStatus _PR_DetachWindowsProcess(PRProcess *process)
+{
+    CloseHandle(process->md.handle);
+    PR_DELETE(process);
+    return PR_SUCCESS;
+}
+
+/*
+ * XXX: This implementation is a temporary quick solution.
+ * It can be called by native threads only (not by fibers).
+ */
+PRStatus _PR_WaitWindowsProcess(PRProcess *process,
+    PRInt32 *exitCode)
+{
+    DWORD dwRetVal;
+
+    dwRetVal = WaitForSingleObject(process->md.handle, INFINITE);
+    if (dwRetVal == WAIT_FAILED) {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+    PR_ASSERT(dwRetVal == WAIT_OBJECT_0);
+    if (exitCode != NULL &&
+            GetExitCodeProcess(process->md.handle, exitCode) == FALSE) {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+    CloseHandle(process->md.handle);
+    PR_DELETE(process);
+    return PR_SUCCESS;
+}
+
+PRStatus _PR_KillWindowsProcess(PRProcess *process)
+{
+    /*
+     * On Unix, if a process terminates normally, its exit code is
+     * between 0 and 255.  So here on Windows, we use the exit code
+     * 256 to indicate that the process is killed.
+     */
+    if (TerminateProcess(process->md.handle, 256)) {
+	return PR_SUCCESS;
+    }
+    PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+    return PR_FAILURE;
+}
+
+PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen)
+{
+    PRIntn rv;
+    PRInt32 syserror;
+
+    rv = gethostname(name, (PRInt32) namelen);
+    if (0 == rv) {
+        return PR_SUCCESS;
+    }
+    syserror = WSAGetLastError();
+    PR_ASSERT(WSANOTINITIALISED != syserror);
+	_PR_MD_MAP_GETHOSTNAME_ERROR(syserror);
+    return PR_FAILURE;
+}
+
+PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen)
+{
+	OSVERSIONINFO osvi;
+
+	PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE));
+
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+	if (! GetVersionEx (&osvi) ) {
+		_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+    	return PR_FAILURE;
+	}
+
+	switch (osvi.dwPlatformId) {
+		case VER_PLATFORM_WIN32_NT:
+			if (PR_SI_SYSNAME == cmd)
+				(void)PR_snprintf(name, namelen, "Windows_NT");
+			else if (PR_SI_RELEASE == cmd)
+				(void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
+            							osvi.dwMinorVersion);
+			break;
+		case VER_PLATFORM_WIN32_WINDOWS:
+			if (PR_SI_SYSNAME == cmd) {
+				if ((osvi.dwMajorVersion > 4) || 
+					((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0)))
+					(void)PR_snprintf(name, namelen, "Windows_98");
+				else
+					(void)PR_snprintf(name, namelen, "Windows_95");
+			} else if (PR_SI_RELEASE == cmd) {
+				(void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
+            							osvi.dwMinorVersion);
+			}
+			break;
+#ifdef VER_PLATFORM_WIN32_CE
+    case VER_PLATFORM_WIN32_CE:
+			if (PR_SI_SYSNAME == cmd)
+				(void)PR_snprintf(name, namelen, "Windows_CE");
+			else if (PR_SI_RELEASE == cmd)
+				(void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
+            							osvi.dwMinorVersion);
+			break;
+#endif
+   		default:
+			if (PR_SI_SYSNAME == cmd)
+				(void)PR_snprintf(name, namelen, "Windows_Unknown");
+			else if (PR_SI_RELEASE == cmd)
+				(void)PR_snprintf(name, namelen, "%d.%d",0,0);
+			break;
+	}
+	return PR_SUCCESS;
+}
+
+PRStatus _MD_WindowsGetReleaseName(char *name, PRUint32 namelen)
+{
+	OSVERSIONINFO osvi;
+
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+	if (! GetVersionEx (&osvi) ) {
+		_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+    	return PR_FAILURE;
+	}
+
+	switch (osvi.dwPlatformId) {
+		case VER_PLATFORM_WIN32_NT:
+		case VER_PLATFORM_WIN32_WINDOWS:
+			(void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
+            							osvi.dwMinorVersion);
+			break;
+   		default:
+			(void)PR_snprintf(name, namelen, "%d.%d",0,0);
+			break;
+	}
+	return PR_SUCCESS;
+}
+
+/*
+ **********************************************************************
+ *
+ * Memory-mapped files
+ *
+ **********************************************************************
+ */
+
+PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
+{
+    DWORD dwHi, dwLo;
+    DWORD flProtect;
+    PROsfd osfd;
+
+    osfd = ( fmap->fd == (PRFileDesc*)-1 )?  -1 : fmap->fd->secret->md.osfd;
+
+    dwLo = (DWORD) (size & 0xffffffff);
+    dwHi = (DWORD) (((PRUint64) size >> 32) & 0xffffffff);
+
+    if (fmap->prot == PR_PROT_READONLY) {
+        flProtect = PAGE_READONLY;
+        fmap->md.dwAccess = FILE_MAP_READ;
+    } else if (fmap->prot == PR_PROT_READWRITE) {
+        flProtect = PAGE_READWRITE;
+        fmap->md.dwAccess = FILE_MAP_WRITE;
+    } else {
+        PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY);
+#ifdef WINCE
+        /* WINCE does not have FILE_MAP_COPY. */
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        return PR_FAILURE;
+#else
+        flProtect = PAGE_WRITECOPY;
+        fmap->md.dwAccess = FILE_MAP_COPY;
+#endif
+    }
+
+    fmap->md.hFileMap = CreateFileMapping(
+        (HANDLE) osfd,
+        NULL,
+        flProtect,
+        dwHi,
+        dwLo,
+        NULL);
+
+    if (fmap->md.hFileMap == NULL) {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRInt32 _MD_GetMemMapAlignment(void)
+{
+    SYSTEM_INFO info;
+    GetSystemInfo(&info);
+    return info.dwAllocationGranularity;
+}
+
+extern PRLogModuleInfo *_pr_shma_lm;
+
+void * _MD_MemMap(
+    PRFileMap *fmap,
+    PROffset64 offset,
+    PRUint32 len)
+{
+    DWORD dwHi, dwLo;
+    void *addr;
+
+    dwLo = (DWORD) (offset & 0xffffffff);
+    dwHi = (DWORD) (((PRUint64) offset >> 32) & 0xffffffff);
+    if ((addr = MapViewOfFile(fmap->md.hFileMap, fmap->md.dwAccess,
+            dwHi, dwLo, len)) == NULL) {
+        {
+            LPVOID lpMsgBuf; 
+            
+            FormatMessage( 
+                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                NULL,
+                GetLastError(),
+                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                (LPTSTR) &lpMsgBuf,
+                0,
+                NULL 
+            );
+            PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, ("md_memmap(): %s", lpMsgBuf ));
+        }
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+    }
+    return addr;
+}
+
+PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
+{
+    if (UnmapViewOfFile(addr)) {
+        return PR_SUCCESS;
+    } else {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus _MD_CloseFileMap(PRFileMap *fmap)
+{
+    CloseHandle(fmap->md.hFileMap);
+    PR_DELETE(fmap);
+    return PR_SUCCESS;
+}
+
+/*
+ ***********************************************************************
+ *
+ * Atomic increment and decrement operations for x86 processors
+ *
+ * We don't use InterlockedIncrement and InterlockedDecrement
+ * because on NT 3.51 and Win95, they return a number with
+ * the same sign as the incremented/decremented result, rather
+ * than the result itself.  On NT 4.0 these functions do return
+ * the incremented/decremented result.
+ *
+ * The result is returned in the eax register by the inline
+ * assembly code.  We disable the harmless "no return value"
+ * warning (4035) for these two functions.
+ *
+ ***********************************************************************
+ */
+
+#if defined(_M_IX86) || defined(_X86_)
+
+#pragma warning(disable: 4035)
+PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{    
+#if defined(__GNUC__)
+  PRInt32 result;
+  asm volatile ("lock ; xadd %0, %1" 
+                : "=r"(result), "=m"(*val)
+                : "0"(1), "m"(*val));
+  return result + 1;
+#else
+    __asm
+    {
+        mov ecx, val
+        mov eax, 1
+        lock xadd dword ptr [ecx], eax
+        inc eax
+    }
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#pragma warning(disable: 4035)
+PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+#if defined(__GNUC__)
+  PRInt32 result;
+  asm volatile ("lock ; xadd %0, %1" 
+                : "=r"(result), "=m"(*val)
+                : "0"(-1), "m"(*val));
+  //asm volatile("lock ; xadd %0, %1" : "=m" (val), "=a" (result) : "-1" (1));
+  return result - 1;
+#else
+    __asm
+    {
+        mov ecx, val
+        mov eax, 0ffffffffh
+        lock xadd dword ptr [ecx], eax
+        dec eax
+    }
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#pragma warning(disable: 4035)
+PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *intp, PRInt32 val)
+{
+#if defined(__GNUC__)
+  PRInt32 result;
+  //asm volatile("lock ; xadd %1, %0" : "=m" (intp), "=a" (result) : "1" (val));
+  asm volatile ("lock ; xadd %0, %1" 
+                : "=r"(result), "=m"(*intp)
+                : "0"(val), "m"(*intp));
+  return result + val;
+#else
+    __asm
+    {
+        mov ecx, intp
+        mov eax, val
+        mov edx, eax
+        lock xadd dword ptr [ecx], eax
+        add eax, edx
+    }
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#ifdef _PR_HAVE_ATOMIC_CAS
+
+#pragma warning(disable: 4035)
+void 
+PR_StackPush(PRStack *stack, PRStackElem *stack_elem)
+{
+#if defined(__GNUC__)
+  void **tos = (void **) stack;
+  void *tmp;
+  
+ retry:
+  if (*tos == (void *) -1)
+    goto retry;
+  
+  __asm__("xchg %0,%1"
+          : "=r" (tmp), "=m"(*tos)
+          : "0" (-1), "m"(*tos));
+  
+  if (tmp == (void *) -1)
+    goto retry;
+  
+  *(void **)stack_elem = tmp;
+  __asm__("" : : : "memory");
+  *tos = stack_elem;
+#else
+    __asm
+    {
+	mov ebx, stack
+	mov ecx, stack_elem
+retry:	mov eax,[ebx]
+	cmp eax,-1
+	je retry
+	mov eax,-1
+	xchg dword ptr [ebx], eax
+	cmp eax,-1
+	je  retry
+	mov [ecx],eax
+	mov [ebx],ecx
+    }
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#pragma warning(disable: 4035)
+PRStackElem * 
+PR_StackPop(PRStack *stack)
+{
+#if defined(__GNUC__)
+  void **tos = (void **) stack;
+  void *tmp;
+  
+ retry:
+  if (*tos == (void *) -1)
+    goto retry;
+  
+  __asm__("xchg %0,%1"
+          : "=r" (tmp), "=m"(*tos)
+          : "0" (-1), "m"(*tos));
+
+  if (tmp == (void *) -1)
+    goto retry;
+  
+  if (tmp != (void *) 0)
+    {
+      void *next = *(void **)tmp;
+      *tos = next;
+      *(void **)tmp = 0;
+    }
+  else
+    *tos = tmp;
+  
+  return tmp;
+#else
+    __asm
+    {
+	mov ebx, stack
+retry:	mov eax,[ebx]
+	cmp eax,-1
+	je retry
+	mov eax,-1
+	xchg dword ptr [ebx], eax
+	cmp eax,-1
+	je  retry
+	cmp eax,0
+	je  empty
+	mov ecx,[eax]
+	mov [ebx],ecx
+	mov [eax],0
+	jmp done
+empty:
+	mov [ebx],eax
+done:	
+	}
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#endif /* _PR_HAVE_ATOMIC_CAS */
+
+#endif /* x86 processors */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntsec.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntsec.c
new file mode 100644
index 0000000..1acb6c4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntsec.c
@@ -0,0 +1,293 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#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)
+{
+#ifdef WINCE /* not supported */
+    return;
+#else
+    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
+    HANDLE hToken = NULL; /* initialized to an arbitrary value to
+                           * silence a Purify UMR warning */
+    PSID infoBuffer[1024/sizeof(PSID)]; /* defined as an array of PSIDs
+                                         * to force proper alignment */
+    PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer;
+    PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup
+            = (PTOKEN_PRIMARY_GROUP) infoBuffer;
+    DWORD dwLength;
+    BOOL rv;
+
+    /*
+     * 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);
+    if (rv == 0) {
+        /*
+         * On non-NT systems, this function is not implemented
+         * (error code ERROR_CALL_NOT_IMPLEMENTED), and neither are
+         * the other security functions.  There is no point in
+         * going further.
+         *
+         * A process with insufficient access permissions may fail
+         * with the error code ERROR_ACCESS_DENIED.
+         */
+        PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+                ("_PR_NT_InitSids: OpenProcessToken() failed. Error: %d",
+                GetLastError()));
+        return;
+    }
+
+    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);
+
+    /* Create a well-known SID for the Everyone group. */
+    rv = AllocateAndInitializeSid(&SIDAuthWorld, 1,
+            SECURITY_WORLD_RID,
+            0, 0, 0, 0, 0, 0, 0,
+            &_pr_nt_sids.everyone);
+    PR_ASSERT(rv != 0);
+#endif
+}
+
+/*
+ * 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)
+{
+#ifdef WINCE
+    return;
+#else
+    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);
+    }
+#endif
+}
+
+/*
+ * 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)
+{
+#ifdef WINCE
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+#else
+    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;
+#endif
+}
+
+/*
+ * 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);
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntsem.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntsem.c
new file mode 100644
index 0000000..b25fac6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntsem.c
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * NT-specific semaphore handling code.
+ *
+ */
+
+
+#include "primpl.h"
+
+
+void 
+_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value)
+{
+    md->sem = CreateSemaphore(NULL, value, 0x7fffffff, NULL);
+}
+
+void 
+_PR_MD_DESTROY_SEM(_MDSemaphore *md)
+{
+    CloseHandle(md->sem);
+}
+
+PRStatus 
+_PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks)
+{
+    int rv;
+
+    rv = WaitForSingleObject(md->sem, PR_IntervalToMilliseconds(ticks));
+
+    if (rv == WAIT_OBJECT_0)
+        return PR_SUCCESS;
+    else
+        return PR_FAILURE;
+}
+
+PRStatus 
+_PR_MD_WAIT_SEM(_MDSemaphore *md)
+{
+    return _PR_MD_TIMED_WAIT_SEM(md, PR_INTERVAL_NO_TIMEOUT);
+}
+
+void 
+_PR_MD_POST_SEM(_MDSemaphore *md)
+{
+    int old_count;
+
+    ReleaseSemaphore(md->sem, 1, &old_count);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntthread.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntthread.c
new file mode 100644
index 0000000..4c8fa62
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/ntthread.c
@@ -0,0 +1,560 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <process.h>  /* for _beginthreadex() */
+
+/* --- globals ------------------------------------------------ */
+PRLock                       *_pr_schedLock = NULL;
+_PRInterruptTable             _pr_interruptTable[] = { { 0 } };
+
+BOOL _pr_use_static_tls = TRUE;
+__declspec(thread) PRThread  *_pr_current_fiber;
+__declspec(thread) PRThread  *_pr_fiber_last_run;
+__declspec(thread) _PRCPU    *_pr_current_cpu;
+__declspec(thread) PRUintn    _pr_ints_off;
+DWORD _pr_currentFiberIndex;
+DWORD _pr_lastFiberIndex;
+DWORD _pr_currentCPUIndex;
+DWORD _pr_intsOffIndex;
+
+_MDLock                       _nt_idleLock;
+PRCList                       _nt_idleList;
+PRUint32                        _nt_idleCount;
+
+extern __declspec(thread) PRThread *_pr_io_restarted_io;
+extern DWORD _pr_io_restartedIOIndex;
+
+/* Must check the restarted_io *before* decrementing no_sched to 0 */
+#define POST_SWITCH_WORK() \
+    PR_BEGIN_MACRO \
+        PRThread *restarted_io = \
+            (_pr_use_static_tls ? _pr_io_restarted_io \
+            : (PRThread *) TlsGetValue(_pr_io_restartedIOIndex)); \
+        if (restarted_io) { \
+            _nt_handle_restarted_io(restarted_io); \
+        } \
+        _PR_MD_LAST_THREAD()->no_sched = 0; \
+    PR_END_MACRO
+
+void
+_nt_handle_restarted_io(PRThread *restarted_io)
+{
+    /* After the switch we can resume an IO if needed.
+     * XXXMB - this needs to be done in create thread, since that could
+     * be the result for a context switch too..
+     */
+    PR_ASSERT(restarted_io->io_suspended == PR_TRUE);
+    PR_ASSERT(restarted_io->md.thr_bound_cpu == restarted_io->cpu);
+
+    _PR_THREAD_LOCK(restarted_io);
+    if (restarted_io->io_pending == PR_FALSE) {
+
+        /* The IO already completed, put us back on the runq. */
+        int pri = restarted_io->priority;
+
+        restarted_io->state = _PR_RUNNABLE;
+        _PR_RUNQ_LOCK(restarted_io->cpu);
+        _PR_ADD_RUNQ(restarted_io, restarted_io->cpu, pri);
+        _PR_RUNQ_UNLOCK(restarted_io->cpu);
+    } else {
+        _PR_SLEEPQ_LOCK(restarted_io->cpu);
+        _PR_ADD_SLEEPQ(restarted_io, restarted_io->sleep);
+        _PR_SLEEPQ_UNLOCK(restarted_io->cpu);
+    }
+    restarted_io->io_suspended = PR_FALSE;
+    restarted_io->md.thr_bound_cpu = NULL;
+
+    _PR_THREAD_UNLOCK(restarted_io);
+
+    if (_pr_use_static_tls) {
+        _pr_io_restarted_io = NULL;
+    } else {
+        TlsSetValue(_pr_io_restartedIOIndex, NULL);
+    }
+}
+
+void
+_PR_MD_EARLY_INIT()
+{
+    _MD_NEW_LOCK( &_nt_idleLock );
+    _nt_idleCount = 0;
+    PR_INIT_CLIST(&_nt_idleList);
+
+#if 0
+    /* Make the clock tick at least once per millisecond */
+    if ( timeBeginPeriod(1) == TIMERR_NOCANDO) {
+        /* deep yoghurt; clock doesn't tick fast enough! */
+        PR_ASSERT(0);
+    }
+#endif
+
+    if (!_pr_use_static_tls) {
+        _pr_currentFiberIndex = TlsAlloc();
+        _pr_lastFiberIndex = TlsAlloc();
+        _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);
+    }
+}
+
+PRStatus
+_PR_MD_INIT_THREAD(PRThread *thread)
+{
+    thread->md.overlapped.ioModel = _MD_BlockingIO;
+    thread->md.overlapped.data.mdThread = &thread->md;
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+            /*
+            ** Warning:
+            ** --------
+            ** NSPR requires a real handle to every thread.
+            ** GetCurrentThread() returns a pseudo-handle which
+            ** is not suitable for some thread operations (e.g.,
+            ** suspending).  Therefore, get a real handle from
+            ** the pseudo handle via DuplicateHandle(...)
+            */
+            DuplicateHandle(
+                    GetCurrentProcess(),     /* Process of source handle */
+                    GetCurrentThread(),      /* Pseudo Handle to dup */
+                    GetCurrentProcess(),     /* Process of handle */
+                    &(thread->md.handle),    /* resulting handle */
+                    0L,                      /* access flags */
+                    FALSE,                   /* Inheritable */
+                    DUPLICATE_SAME_ACCESS);  /* Options */
+        }
+
+        /* Create the blocking IO semaphore */
+        thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL);
+        if (thread->md.blocked_sema == NULL) {
+            return PR_FAILURE;
+        }
+		if (_native_threads_only) {
+			/* Create the blocking IO semaphore */
+			thread->md.thr_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+			if (thread->md.thr_event == NULL) {
+				return PR_FAILURE;
+			}
+		}
+    }
+
+    return PR_SUCCESS;
+}
+
+static unsigned __stdcall
+pr_root(void *arg)
+{
+    PRThread *thread = (PRThread *)arg;
+    thread->md.start(thread);
+    return 0;
+}
+
+PRStatus 
+_PR_MD_CREATE_THREAD(PRThread *thread, 
+                  void (*start)(void *), 
+                  PRThreadPriority priority, 
+                  PRThreadScope scope, 
+                  PRThreadState state, 
+                  PRUint32 stackSize)
+{
+
+    thread->md.start = start;
+    thread->md.handle = (HANDLE) _beginthreadex(
+                    NULL,
+                    thread->stack->stackSize,
+                    pr_root,
+                    (void *)thread,
+                    CREATE_SUSPENDED,
+                    &(thread->id));
+    if(!thread->md.handle) {
+        PRErrorCode prerror;
+        thread->md.fiber_last_error = GetLastError();
+        switch (errno) {
+            case ENOMEM:
+                prerror = PR_OUT_OF_MEMORY_ERROR;
+                break;
+            case EAGAIN:
+                prerror = PR_INSUFFICIENT_RESOURCES_ERROR;
+                break;
+            case EINVAL:
+                prerror = PR_INVALID_ARGUMENT_ERROR;
+                break;
+            default:
+                prerror = PR_UNKNOWN_ERROR;
+        }
+        PR_SetError(prerror, errno);
+        return PR_FAILURE;
+    }
+
+    thread->md.id = thread->id;
+    /*
+     * On windows, a thread is created with a thread priority of
+     * THREAD_PRIORITY_NORMAL.
+     */
+    if (priority != PR_PRIORITY_NORMAL) {
+        _PR_MD_SET_PRIORITY(&(thread->md), priority);
+    }
+
+    /* Activate the thread */
+    if ( ResumeThread( thread->md.handle ) != -1)
+        return PR_SUCCESS;
+
+    PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+    return PR_FAILURE;
+}
+
+void
+_PR_MD_JOIN_THREAD(_MDThread *md)
+{
+    DWORD rv;
+
+    rv = WaitForSingleObject(md->handle, INFINITE);
+    PR_ASSERT(WAIT_OBJECT_0 == rv);
+}
+
+void
+_PR_MD_END_THREAD(void)
+{
+    _endthreadex(0);
+}
+
+void    
+_PR_MD_YIELD(void)
+{
+    /* Can NT really yield at all? */
+    Sleep(0);
+}
+
+void     
+_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
+{
+    int nativePri;
+    BOOL rv;
+
+    if (newPri < PR_PRIORITY_FIRST) {
+        newPri = PR_PRIORITY_FIRST;
+    } else if (newPri > PR_PRIORITY_LAST) {
+        newPri = PR_PRIORITY_LAST;
+    }
+    switch (newPri) {
+        case PR_PRIORITY_LOW:
+            nativePri = THREAD_PRIORITY_BELOW_NORMAL;
+            break;
+        case PR_PRIORITY_NORMAL:
+            nativePri = THREAD_PRIORITY_NORMAL;
+            break;
+        case PR_PRIORITY_HIGH:
+            nativePri = THREAD_PRIORITY_ABOVE_NORMAL;
+            break;
+        case PR_PRIORITY_URGENT:
+            nativePri = THREAD_PRIORITY_HIGHEST;
+    }
+    rv = SetThreadPriority(thread->handle, nativePri);
+    PR_ASSERT(rv);
+    if (!rv) {
+	PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+                ("PR_SetThreadPriority: can't set thread priority\n"));
+    }
+    return;
+}
+
+void
+_PR_MD_CLEAN_THREAD(PRThread *thread)
+{
+    BOOL rv;
+
+    if (thread->md.acceptex_buf) {
+        PR_DELETE(thread->md.acceptex_buf);
+    }
+
+    if (thread->md.xmit_bufs) {
+        PR_DELETE(thread->md.xmit_bufs);
+    }
+
+    if (thread->md.blocked_sema) {
+        rv = CloseHandle(thread->md.blocked_sema);
+        PR_ASSERT(rv);
+        thread->md.blocked_sema = 0;
+    }
+	if (_native_threads_only) {
+		if (thread->md.thr_event) {
+			rv = CloseHandle(thread->md.thr_event);
+			PR_ASSERT(rv);
+			thread->md.thr_event = 0;
+		}
+	}
+
+    if (thread->md.handle) {
+        rv = CloseHandle(thread->md.handle);
+        PR_ASSERT(rv);
+        thread->md.handle = 0;
+    }
+
+    /* Don't call DeleteFiber on current fiber or we'll kill the whole thread.
+     * Don't call free(thread) until we've switched off the thread.
+     * So put this fiber (or thread) on a list to be deleted by the idle
+     * fiber next time we have a chance.
+     */
+    if (!(thread->flags & (_PR_ATTACHED|_PR_GLOBAL_SCOPE))) {
+        _MD_LOCK(&_nt_idleLock);
+        _nt_idleCount++;
+        PR_APPEND_LINK(&thread->links, &_nt_idleList);
+        _MD_UNLOCK(&_nt_idleLock);
+    }
+}
+
+void
+_PR_MD_EXIT_THREAD(PRThread *thread)
+{
+    BOOL rv;
+
+    if (thread->md.acceptex_buf) {
+        PR_DELETE(thread->md.acceptex_buf);
+    }
+
+    if (thread->md.xmit_bufs) {
+        PR_DELETE(thread->md.xmit_bufs);
+    }
+
+    if (thread->md.blocked_sema) {
+        rv = CloseHandle(thread->md.blocked_sema);
+        PR_ASSERT(rv);
+        thread->md.blocked_sema = 0;
+    }
+
+	if (_native_threads_only) {
+		if (thread->md.thr_event) {
+			rv = CloseHandle(thread->md.thr_event);
+			PR_ASSERT(rv);
+			thread->md.thr_event = 0;
+		}
+	}
+
+    if (thread->md.handle) {
+        rv = CloseHandle(thread->md.handle);
+        PR_ASSERT(rv);
+        thread->md.handle = 0;
+    }
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        _MD_SET_CURRENT_THREAD(NULL);
+    }
+}
+
+
+void
+_PR_MD_EXIT(PRIntn status)
+{
+    _exit(status);
+}
+
+#ifdef HAVE_FIBERS
+
+void
+_pr_fiber_mainline(void *unused) 
+{
+    PRThread *fiber = _PR_MD_CURRENT_THREAD();
+
+    POST_SWITCH_WORK();
+
+    fiber->md.fiber_fn(fiber->md.fiber_arg);
+}
+
+PRThread *_PR_MD_CREATE_USER_THREAD(
+    PRUint32 stacksize, void (*start)(void *), void *arg)
+{
+    PRThread *thread;
+
+    if ( (thread = PR_NEW(PRThread)) == NULL ) {
+        return NULL;
+    }
+    
+    memset(thread, 0, sizeof(PRThread));
+    thread->md.fiber_fn = start;
+    thread->md.fiber_arg = arg;
+    thread->md.fiber_stacksize = stacksize;
+    return thread;
+}
+
+void
+_PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *thread)
+{
+    thread->md.fiber_id = ConvertThreadToFiber(NULL);
+    PR_ASSERT(thread->md.fiber_id);
+    _MD_SET_CURRENT_THREAD(thread);
+    _MD_SET_LAST_THREAD(thread);
+    thread->no_sched = 1;
+    return;
+}
+
+void
+_PR_MD_INIT_CONTEXT(PRThread *thread, char *top, void (*start) (void), PRBool *status)
+{
+    thread->md.fiber_fn = (void (*)(void *))start;
+    thread->md.fiber_id = CreateFiber(thread->md.fiber_stacksize, 
+        (LPFIBER_START_ROUTINE)_pr_fiber_mainline, NULL);
+    if (thread->md.fiber_id != 0)
+        *status = PR_TRUE;
+    else {
+        DWORD oserror = GetLastError();
+        PRErrorCode prerror;
+        if (oserror == ERROR_NOT_ENOUGH_MEMORY) {
+            prerror = PR_OUT_OF_MEMORY_ERROR;
+        } else {
+            prerror = PR_UNKNOWN_ERROR;
+        }
+        PR_SetError(prerror, oserror);
+        *status = PR_FALSE;
+    }
+}
+
+void
+_PR_MD_SWITCH_CONTEXT(PRThread *thread)
+{
+    PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
+
+    thread->md.fiber_last_error = GetLastError();
+    _PR_Schedule();
+}
+
+void
+_PR_MD_RESTORE_CONTEXT(PRThread *thread)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
+
+    /* The user-level code for yielding will happily add ourselves to the runq
+     * and then switch to ourselves; the NT fibers can't handle switching to 
+     * ourselves.
+     */
+    if (thread != me) {
+        SetLastError(thread->md.fiber_last_error);
+        _MD_SET_CURRENT_THREAD(thread);
+        _PR_MD_SET_LAST_THREAD(me);
+        thread->no_sched = 1;
+        SwitchToFiber(thread->md.fiber_id);
+        POST_SWITCH_WORK();
+    }
+}
+
+
+#endif /* HAVE_FIBERS */
+
+PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
+{
+    int rv;
+
+    rv = SetThreadAffinityMask(thread->md.handle, mask);
+
+    return rv?0:-1;
+}
+
+PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
+{
+    PRInt32 rv, system_mask;
+
+    rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask);
+    
+    return rv?0:-1;
+}
+
+void 
+_PR_MD_SUSPEND_CPU(_PRCPU *cpu) 
+{
+    _PR_MD_SUSPEND_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_RESUME_CPU(_PRCPU *cpu)
+{
+    _PR_MD_RESUME_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_SUSPEND_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        /*
+        ** There seems to be some doubt about whether or not SuspendThread
+        ** is a synchronous function. The test afterwards is to help veriry
+        ** that it is, which is what Microsoft says it is.
+        */
+        PRUintn rv = SuspendThread(thread->md.handle);
+        PR_ASSERT(0xffffffffUL != rv);
+    }
+}
+
+void
+_PR_MD_RESUME_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        ResumeThread(thread->md.handle);
+    }
+}
+
+PRThread*
+_MD_CURRENT_THREAD(void)
+{
+PRThread *thread;
+
+	thread = _MD_GET_ATTACHED_THREAD();
+
+   	if (NULL == thread) {
+		thread = _PRI_AttachThread(
+            PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+	}
+	PR_ASSERT(thread != NULL);
+	return thread;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/objs.mk b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/objs.mk
new file mode 100644
index 0000000..82ee36e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/objs.mk
@@ -0,0 +1,80 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+ifeq ($(OS_TARGET),WINNT)
+CSRCS = ntmisc.c \
+	ntsec.c \
+	ntsem.c \
+	ntinrval.c \
+	ntgc.c \
+	ntio.c \
+	ntthread.c \
+	ntdllmn.c \
+	win32_errors.c \
+	w32ipcsem.c \
+	w32poll.c \
+	w32rng.c \
+	w32shm.c
+else
+ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET)))
+CSRCS =	ntmisc.c \
+	ntsec.c \
+	ntsem.c \
+	ntinrval.c \
+	ntgc.c \
+	w95thred.c \
+	w95io.c \
+	w95cv.c \
+	w95sock.c \
+	win32_errors.c \
+	w32ipcsem.c \
+	w32poll.c \
+	w32rng.c \
+	w32shm.c \
+	w95dllmain.c
+else
+endif # win95
+endif # winnt
+
+CSRCS	+= $(PR_MD_CSRCS)
+ASFILES += $(PR_MD_ASFILES)
+
+OBJS += $(addprefix md/windows/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)))  \
+	$(addprefix md/windows/$(OBJDIR)/,$(ASFILES:.s=.$(OBJ_SUFFIX)))
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32ipcsem.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32ipcsem.c
new file mode 100644
index 0000000..443cd7f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32ipcsem.c
@@ -0,0 +1,260 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: w32ipcsem.c
+ * Description: implements named semaphores for NT and WIN95.
+ */
+
+#include "primpl.h"
+
+#ifdef WINCE
+static HANDLE OpenSemaphore(DWORD inDesiredAccess,
+                            BOOL inInheritHandle,
+                            const char *inName)
+{
+    HANDLE retval = NULL;
+    HANDLE semaphore = NULL;
+    PRUnichar wideName[MAX_PATH];  /* name size is limited to MAX_PATH */
+    
+    MultiByteToWideChar(CP_ACP, 0, inName, -1, wideName, MAX_PATH);
+    /* 0x7fffffff is the max count for our semaphore */
+    semaphore = CreateSemaphoreW(NULL, 0, 0x7fffffff, wideName);
+    if (NULL != semaphore) {
+        DWORD lastErr = GetLastError();
+      
+        if (ERROR_ALREADY_EXISTS != lastErr)
+            CloseHandle(semaphore);
+        else
+            retval = semaphore;
+    }
+    return retval;
+}
+#endif
+
+/*
+ * 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.
+ */
+
+/*
+ * Arguments, return value, and error code for WaitForSingleObject
+ */
+struct WaitSingleArg {
+    HANDLE handle;
+    DWORD timeout;
+    DWORD rv;
+    DWORD error;
+};
+
+static void WaitSingleThread(void *arg)
+{
+    struct WaitSingleArg *warg = (struct WaitSingleArg *) arg;
+
+    warg->rv = WaitForSingleObject(warg->handle, warg->timeout);
+    if (warg->rv == WAIT_FAILED) {
+        warg->error = GetLastError();
+    }
+}
+
+static DWORD FiberSafeWaitForSingleObject(
+    HANDLE hHandle,
+    DWORD dwMilliseconds
+)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_PR_IS_NATIVE_THREAD(me)) {
+        return WaitForSingleObject(hHandle, dwMilliseconds);
+    } else {
+        PRThread *waitThread;
+        struct WaitSingleArg warg;
+        PRStatus rv;
+
+        warg.handle = hHandle;
+        warg.timeout = dwMilliseconds;
+        waitThread = PR_CreateThread(
+            PR_USER_THREAD, WaitSingleThread, &warg,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (waitThread == NULL) {
+            return WAIT_FAILED;
+        }
+
+        rv = PR_JoinThread(waitThread);
+        PR_ASSERT(rv == PR_SUCCESS);
+        if (rv == PR_FAILURE) {
+            return WAIT_FAILED;
+        }
+        if (warg.rv == WAIT_FAILED) {
+            SetLastError(warg.error);
+        }
+        return warg.rv;
+    }
+}
+
+#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) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, semAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+#ifdef WINCE
+        {
+            /* The size of a sem's name is limited to MAX_PATH. */
+            PRUnichar wosname[MAX_PATH]; 
+            MultiByteToWideChar(CP_ACP, 0, osname, -1, wosname, MAX_PATH);
+            sem->sem = CreateSemaphoreW(lpSA, value, 0x7fffffff, wosname);
+        }
+#else
+        sem->sem = CreateSemaphoreA(lpSA, value, 0x7fffffff, osname);
+#endif
+        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_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
+             */
+            if (err == ERROR_INVALID_NAME) {
+                PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+            } else {
+                _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+            }
+            PR_DELETE(sem);
+            return NULL;
+        }
+    }
+    return sem;
+}
+
+PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem)
+{
+    DWORD rv;
+
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    rv = WaitForSingleObject(sem->sem, INFINITE);
+#else
+    rv = FiberSafeWaitForSingleObject(sem->sem, INFINITE);
+#endif
+    PR_ASSERT(rv == WAIT_FAILED || rv == WAIT_OBJECT_0);
+    if (rv == WAIT_FAILED) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    if (rv != WAIT_OBJECT_0) {
+        /* Should not happen */
+        PR_SetError(PR_UNKNOWN_ERROR, 0);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem)
+{
+    if (ReleaseSemaphore(sem->sem, 1, NULL) == FALSE) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem)
+{
+    if (CloseHandle(sem->sem) == FALSE) {
+        _PR_MD_MAP_CLOSE_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    PR_DELETE(sem);
+    return PR_SUCCESS;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32poll.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32poll.c
new file mode 100644
index 0000000..2caaac2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32poll.c
@@ -0,0 +1,357 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This file implements _PR_MD_PR_POLL for Win32.
+ */
+
+/* The default value of FD_SETSIZE is 64. */
+#define FD_SETSIZE 1024
+
+#include "primpl.h"
+
+#if !defined(_PR_GLOBAL_THREADS_ONLY)
+
+struct select_data_s {
+    PRInt32 status;
+    PRInt32 error;
+    fd_set *rd, *wt, *ex;
+    const struct timeval *tv;
+};
+
+static void
+_PR_MD_select_thread(void *cdata)
+{
+    struct select_data_s *cd = (struct select_data_s *)cdata;
+
+    cd->status = select(0, cd->rd, cd->wt, cd->ex, cd->tv);
+
+    if (cd->status == SOCKET_ERROR) {
+        cd->error = WSAGetLastError();
+    }
+}
+
+int _PR_NTFiberSafeSelect(
+    int nfds,
+    fd_set *readfds,
+    fd_set *writefds,
+    fd_set *exceptfds,
+    const struct timeval *timeout)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    int ready;
+
+    if (_PR_IS_NATIVE_THREAD(me)) {
+        ready = _MD_SELECT(nfds, readfds, writefds, exceptfds, timeout);
+    }
+    else
+    {
+        /*
+        ** Creating a new thread on each call!!
+        ** I guess web server doesn't use non-block I/O.
+        */
+        PRThread *selectThread;
+        struct select_data_s data;
+        data.status = 0;
+        data.error = 0;
+        data.rd = readfds;
+        data.wt = writefds;
+        data.ex = exceptfds;
+        data.tv = timeout;
+
+        selectThread = PR_CreateThread(
+            PR_USER_THREAD, _PR_MD_select_thread, &data,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (selectThread == NULL) return -1;
+
+        PR_JoinThread(selectThread);
+        ready = data.status;
+        if (ready == SOCKET_ERROR) WSASetLastError(data.error);
+    }
+    return ready;
+}
+
+#endif /* !defined(_PR_GLOBAL_THREADS_ONLY) */
+
+PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    int ready, err;
+    fd_set rd, wt, ex;
+    fd_set *rdp, *wtp, *exp;
+    int nrd, nwt, nex;
+    PRFileDesc *bottom;
+    PRPollDesc *pd, *epd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    struct timeval tv, *tvp = NULL;
+
+    if (_PR_PENDING_INTERRUPT(me))
+    {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        return -1;
+    }
+
+    /*
+    ** Is it an empty set? If so, just sleep for the timeout and return
+    */
+    if (0 == npds)
+    {
+        PR_Sleep(timeout);
+        return 0;
+    }
+
+    nrd = nwt = nex = 0;
+    FD_ZERO(&rd);
+    FD_ZERO(&wt);
+    FD_ZERO(&ex);
+
+    ready = 0;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        SOCKET osfd;
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            if (pd->in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pd->fd->methods->poll)(
+                    pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_WRITE),
+                    &out_flags_read);
+            }
+            if (pd->in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pd->fd->methods->poll)(
+                    pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_READ),
+                    &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read))
+            || (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one's ready right now (buffered input) */
+                if (0 == ready)
+                {
+                    /*
+                     * We will have to return without calling the
+                     * system poll/select function.  So zero the
+                     * out_flags fields of all the poll descriptors
+                     * before this one.
+                     */
+                    PRPollDesc *prev;
+                    for (prev = pds; prev < pd; prev++)
+                    {
+                        prev->out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pd->out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pd->out_flags = 0;  /* pre-condition */
+                /* make sure this is an NSPR supported stack */
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom)
+                && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        osfd = (SOCKET) bottom->secret->md.osfd;
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
+                            FD_SET(osfd, &rd);
+                            nrd++;
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+                            FD_SET(osfd, &wt);
+                            nwt++;
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+                            FD_SET(osfd, &rd);
+                            nrd++;
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+                            FD_SET(osfd, &wt);
+                            nwt++;
+                        }
+                        if (pd->in_flags & PR_POLL_EXCEPT) {
+                            FD_SET(osfd, &ex);
+                            nex++;
+                        }
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        PRPollDesc *prev;
+                        for (prev = pds; prev < pd; prev++)
+                        {
+                            prev->out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+        else
+        {
+            pd->out_flags = 0;
+        }
+    }
+
+    if (0 != ready) return ready;  /* no need to block */
+
+    /*
+     * FD_SET does nothing if the fd_set's internal fd_array is full.  If
+     * nrd, nwt, or nex is greater than FD_SETSIZE, we know FD_SET must
+     * have failed to insert an osfd into the corresponding fd_set, and
+     * therefore we should fail.
+     */
+    if ((nrd > FD_SETSIZE) || (nwt > FD_SETSIZE) || (nex > FD_SETSIZE)) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+
+    rdp = (0 == nrd) ? NULL : &rd;
+    wtp = (0 == nwt) ? NULL : &wt;
+    exp = (0 == nex) ? NULL : &ex;
+
+    if ((NULL == rdp) && (NULL == wtp) && (NULL == exp)) {
+        PR_Sleep(timeout);
+        return 0;
+    }
+
+    if (timeout != PR_INTERVAL_NO_TIMEOUT)
+    {
+        PRInt32 ticksPerSecond = PR_TicksPerSecond();
+        tv.tv_sec = timeout / ticksPerSecond;
+        tv.tv_usec = PR_IntervalToMicroseconds( timeout % ticksPerSecond );
+        tvp = &tv;
+    }
+
+#if defined(_PR_GLOBAL_THREADS_ONLY)
+    ready = _MD_SELECT(0, rdp, wtp, exp, tvp);
+#else
+    ready = _PR_NTFiberSafeSelect(0, rdp, wtp, exp, tvp);
+#endif
+
+    /*
+    ** Now to unravel the select sets back into the client's poll
+    ** descriptor list. Is this possibly an area for pissing away
+    ** a few cycles or what?
+    */
+    if (ready > 0)
+    {
+        ready = 0;
+        for (pd = pds, epd = pd + npds; pd < epd; pd++)
+        {
+            PRInt16 out_flags = 0;
+            if ((NULL != pd->fd) && (0 != pd->in_flags))
+            {
+                SOCKET osfd;
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);
+
+                osfd = (SOCKET) bottom->secret->md.osfd;
+
+                if (FD_ISSET(osfd, &rd))
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+                if (FD_ISSET(osfd, &wt))
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+                if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
+            }
+            pd->out_flags = out_flags;
+            if (out_flags) ready++;
+        }
+        PR_ASSERT(ready > 0);
+    }
+    else if (ready == SOCKET_ERROR)
+    {
+        err = WSAGetLastError();
+        if (err == WSAENOTSOCK)
+        {
+            /* Find the bad fds */
+            int optval;
+            int optlen = sizeof(optval);
+            ready = 0;
+            for (pd = pds, epd = pd + npds; pd < epd; pd++)
+            {
+                pd->out_flags = 0;
+                if ((NULL != pd->fd) && (0 != pd->in_flags))
+                {
+                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                    if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
+                        SO_TYPE, (char *) &optval, &optlen) == -1)
+                    {
+                        PR_ASSERT(WSAGetLastError() == WSAENOTSOCK);
+                        if (WSAGetLastError() == WSAENOTSOCK)
+                        {
+                            pd->out_flags = PR_POLL_NVAL;
+                            ready++;
+                        }
+                    }
+                }
+            }
+            PR_ASSERT(ready > 0);
+        }
+        else _PR_MD_MAP_SELECT_ERROR(err);
+    }
+
+    return ready;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32rng.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32rng.c
new file mode 100644
index 0000000..5232b5f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32rng.c
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <windows.h>
+#include <time.h>
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <primpl.h>
+
+static BOOL
+CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow)
+{
+    LARGE_INTEGER   liCount;
+
+    if (!QueryPerformanceCounter(&liCount))
+        return FALSE;
+
+    *lpdwHigh = liCount.u.HighPart;
+    *lpdwLow = liCount.u.LowPart;
+    return TRUE;
+}
+
+extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
+{
+    DWORD   dwHigh, dwLow, dwVal;
+    size_t  n = 0;
+    size_t  nBytes;
+    time_t  sTime;
+
+    if (size <= 0)
+        return 0;
+
+    CurrentClockTickTime(&dwHigh, &dwLow);
+
+    // get the maximally changing bits first
+    nBytes = sizeof(dwLow) > size ? size : sizeof(dwLow);
+    memcpy((char *)buf, &dwLow, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+        return n;
+
+    nBytes = sizeof(dwHigh) > size ? size : sizeof(dwHigh);
+    memcpy(((char *)buf) + n, &dwHigh, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+        return n;
+
+    // get the number of milliseconds that have elapsed since Windows started
+    dwVal = GetTickCount();
+
+    nBytes = sizeof(dwVal) > size ? size : sizeof(dwVal);
+    memcpy(((char *)buf) + n, &dwVal, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+        return n;
+
+    // get the time in seconds since midnight Jan 1, 1970
+    time(&sTime);
+    nBytes = sizeof(sTime) > size ? size : sizeof(sTime);
+    memcpy(((char *)buf) + n, &sTime, nBytes);
+    n += nBytes;
+
+    return n;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32shm.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32shm.c
new file mode 100644
index 0000000..e34a436
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w32shm.c
@@ -0,0 +1,379 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <private/primpl.h>       
+#include <string.h>
+#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);
+    }
+
+    shm = PR_NEWZAP( PRSharedMemory );
+    if ( NULL == shm ) 
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 
+        return(NULL);
+    }
+
+    shm->ipcname = PR_MALLOC( (PRUint32) (strlen( ipcname ) + 1) );
+    if ( NULL == shm->ipcname )
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 
+        PR_DELETE(shm);
+        return(NULL);
+    }
+
+    /* 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 ) {
+        dwHi = (DWORD) (((PRUint64) shm->size >> 32) & 0xffffffff);
+        dwLo = (DWORD) (shm->size & 0xffffffff);
+
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+#ifdef WINCE
+        {
+            /*
+             * This is assuming that the name will never be larger than
+             * MAX_PATH.  Should we dynamically allocate?
+             */
+            PRUnichar wideIpcName[MAX_PATH];
+            MultiByteToWideChar(CP_ACP, 0, shm->ipcname, -1,
+                                wideIpcName, MAX_PATH);
+            shm->handle = CreateFileMappingW(
+                (HANDLE)-1 ,
+                lpSA,
+                flProtect,
+                dwHi,
+                dwLo,
+                wideIpcName);
+        }
+#else
+        shm->handle = CreateFileMappingA(
+            (HANDLE)-1 ,
+            lpSA,
+            flProtect,
+            dwHi,
+            dwLo,
+            shm->ipcname);
+#endif
+        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_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 )); 
+                PR_SetError( PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS );
+                CloseHandle( shm->handle );
+                PR_FREEIF( shm->ipcname )
+                PR_DELETE( shm );
+                return(NULL);
+            } else {
+                PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+                    ( "PR_OpenSharedMemory: CreateFileMapping() success: %s, handle: %d",
+                        shm->ipcname, shm->handle ));
+                return(shm);
+            }
+        }
+    } else {
+#ifdef WINCE
+        PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+        shm->handle = NULL;  /* OpenFileMapping not supported */
+#else
+        shm->handle = OpenFileMapping( FILE_MAP_WRITE, TRUE, shm->ipcname );
+#endif
+        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);
+        } else {
+            PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+                ( "PR_OpenSharedMemory: OpenFileMapping() success: %s, handle: %d",
+                    shm->ipcname, shm->handle )); 
+                return(shm);
+        }
+    }
+    /* returns from separate paths */
+}
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
+{
+    PRUint32    access = FILE_MAP_WRITE;
+    void        *addr;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    if ( PR_SHM_READONLY & flags )
+        access = FILE_MAP_READ;
+
+    addr = MapViewOfFile( shm->handle,
+        access,
+        0, 0,
+        shm->size );
+
+    if ( NULL == addr ) {
+        _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
+        PR_LOG( _pr_shm_lm, PR_LOG_ERROR, 
+            ("_MD_AttachSharedMemory: MapViewOfFile() failed. OSerror: %d", PR_GetOSError()));
+    }
+
+    return( addr );
+} /* end _MD_ATTACH_SHARED_MEMORY() */
+
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
+{
+    PRStatus rc = PR_SUCCESS;
+    BOOL        wrc;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    wrc = UnmapViewOfFile( addr );
+    if ( FALSE == wrc ) 
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
+        PR_LOG( _pr_shm_lm, PR_LOG_ERROR, 
+            ("_MD_DetachSharedMemory: UnmapViewOfFile() failed. OSerror: %d", PR_GetOSError()));
+        rc = PR_FAILURE;
+    }
+
+    return( rc );
+}
+
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
+{
+    PRStatus rc = PR_SUCCESS;
+    BOOL wrc;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    wrc = CloseHandle( shm->handle );
+    if ( FALSE == wrc )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
+        PR_LOG( _pr_shm_lm, PR_LOG_ERROR, 
+            ("_MD_CloseSharedMemory: CloseHandle() failed. OSerror: %d", PR_GetOSError()));
+        rc = PR_FAILURE;
+    }
+    PR_FREEIF( shm->ipcname );
+    PR_DELETE( shm );
+
+    return( rc );
+} /* end _MD_CLOSE_SHARED_MEMORY() */
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name )
+{
+    return( PR_SUCCESS );
+}    
+
+
+/*
+** Windows implementation of anonymous memory (file) map
+*/
+extern PRLogModuleInfo *_pr_shma_lm;
+
+extern PRFileMap* _md_OpenAnonFileMap( 
+    const char *dirName,
+    PRSize      size,
+    PRFileMapProtect prot
+)
+{
+    PRFileMap   *fm;
+    HANDLE      hFileMap;
+
+    fm = PR_CreateFileMap( (PRFileDesc*)-1, size, prot );
+    if ( NULL == fm )  {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): PR_CreateFileMap(): failed"));
+        goto Finished;
+    }
+
+    /*
+    ** Make fm->md.hFileMap inheritable. We can't use
+    ** GetHandleInformation and SetHandleInformation
+    ** because these two functions fail with
+    ** ERROR_CALL_NOT_IMPLEMENTED on Win95.
+    */
+    if (DuplicateHandle(GetCurrentProcess(), fm->md.hFileMap,
+            GetCurrentProcess(), &hFileMap,
+            0, TRUE /* inheritable */,
+            DUPLICATE_SAME_ACCESS) == FALSE) {
+        PR_SetError( PR_UNKNOWN_ERROR, GetLastError() );
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): DuplicateHandle(): failed"));
+        PR_CloseFileMap( fm );
+        fm = NULL;
+        goto Finished;
+    }
+    CloseHandle(fm->md.hFileMap);
+    fm->md.hFileMap = hFileMap;
+
+Finished:    
+    return(fm);
+} /* end md_OpenAnonFileMap() */
+
+/*
+** _md_ExportFileMapAsString()
+**
+*/
+extern PRStatus _md_ExportFileMapAsString(
+    PRFileMap *fm,
+    PRSize    bufSize,
+    char      *buf
+)
+{
+    PRIntn  written;
+
+    written = PR_snprintf( buf, (PRUint32) bufSize, "%d:%" PR_PRIdOSFD ":%ld",
+        (PRIntn)fm->prot, (PROsfd)fm->md.hFileMap, (PRInt32)fm->md.dwAccess );
+
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_ExportFileMapAsString(): prot: %x, hFileMap: %x, dwAccess: %x",
+            fm->prot, fm->md.hFileMap, fm->md.dwAccess ));
+        
+    return((written == -1)? PR_FAILURE : PR_SUCCESS);
+} /* end _md_ExportFileMapAsString() */
+
+
+/*
+** _md_ImportFileMapFromString()
+**
+*/
+extern PRFileMap * _md_ImportFileMapFromString(
+    const char *fmstring
+)
+{
+    PRIntn  prot;
+    PROsfd hFileMap;
+    PRInt32 dwAccess;
+    PRFileMap *fm = NULL;
+
+    PR_sscanf( fmstring, "%d:%" PR_SCNdOSFD ":%ld",
+        &prot, &hFileMap, &dwAccess );
+
+    fm = PR_NEWZAP(PRFileMap);
+    if ( NULL == fm ) {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_ImportFileMapFromString(): PR_NEWZAP(): Failed"));
+        return(fm);
+    }
+
+    fm->prot = (PRFileMapProtect)prot;
+    fm->md.hFileMap = (HANDLE)hFileMap;
+    fm->md.dwAccess = (DWORD)dwAccess;
+    fm->fd = (PRFileDesc*)-1;
+
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_ImportFileMapFromString(): fm: %p, prot: %d, hFileMap: %8.8x, dwAccess: %8.8x, fd: %x",
+            fm, prot, fm->md.hFileMap, fm->md.dwAccess, fm->fd));
+    return(fm);
+} /* end _md_ImportFileMapFromString() */
+
+#else
+Error! Why is PR_HAVE_WIN32_NAMED_SHARED_MEMORY not defined? 
+#endif /* PR_HAVE_WIN32_NAMED_SHARED_MEMORY */
+/* --- end w32shm.c --- */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95cv.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95cv.c
new file mode 100644
index 0000000..975ac4b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95cv.c
@@ -0,0 +1,347 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *  w95cv.c -- Windows 95 Machine-Dependent Code for Condition Variables
+ *
+ *  We implement our own condition variable wait queue.  Each thread
+ *  has a semaphore object (thread->md.blocked_sema) to block on while
+ *  waiting on a condition variable.
+ *
+ *  We use a deferred condition notify algorithm.  When PR_NotifyCondVar
+ *  or PR_NotifyAllCondVar is called, the condition notifies are simply
+ *  recorded in the _MDLock structure.  We defer the condition notifies
+ *  until right after we unlock the lock.  This way the awakened threads
+ *  have a better chance to reaquire the lock.
+ */
+ 
+#include "primpl.h"
+
+/*
+ * AddThreadToCVWaitQueueInternal --
+ *
+ * Add the thread to the end of the condition variable's wait queue.
+ * The CV's lock must be locked when this function is called.
+ */
+
+static void
+AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv)
+{
+    PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
+            || (cv->waitTail == NULL && cv->waitHead == NULL));
+    cv->nwait += 1;
+    thred->md.inCVWaitQueue = PR_TRUE;
+    thred->md.next = NULL;
+    thred->md.prev = cv->waitTail;
+    if (cv->waitHead == NULL) {
+        cv->waitHead = thred;
+    } else {
+        cv->waitTail->md.next = thred;
+    }
+    cv->waitTail = thred;
+}
+
+/*
+ * md_UnlockAndPostNotifies --
+ *
+ * Unlock the lock, and then do the deferred condition notifies.
+ * If waitThred and waitCV are not NULL, waitThred is added to
+ * the wait queue of waitCV before the lock is unlocked.
+ *
+ * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK,
+ * the two places where a lock is unlocked.
+ */
+static void
+md_UnlockAndPostNotifies(
+    _MDLock *lock,
+    PRThread *waitThred,
+    _MDCVar *waitCV)
+{
+    PRIntn index;
+    _MDNotified post;
+    _MDNotified *notified, *prev = NULL;
+
+    /*
+     * Time to actually notify any conditions that were affected
+     * while the lock was held.  Get a copy of the list that's in
+     * the lock structure and then zero the original.  If it's
+     * linked to other such structures, we own that storage.
+     */
+    post = lock->notified;  /* a safe copy; we own the lock */
+
+#if defined(DEBUG)
+    ZeroMemory(&lock->notified, sizeof(_MDNotified));  /* reset */
+#else
+    lock->notified.length = 0;  /* these are really sufficient */
+    lock->notified.link = NULL;
+#endif
+
+    /* 
+     * Figure out how many threads we need to wake up.
+     */
+    notified = &post;  /* this is where we start */
+    do {
+        for (index = 0; index < notified->length; ++index) {
+            _MDCVar *cv = notified->cv[index].cv;
+            PRThread *thred;
+            int i;
+            
+            /* Fast special case: no waiting threads */
+            if (cv->waitHead == NULL) {
+                notified->cv[index].notifyHead = NULL;
+                continue;
+            }
+
+            /* General case */
+            if (-1 == notified->cv[index].times) {
+                /* broadcast */
+                thred = cv->waitHead;
+                while (thred != NULL) {
+                    thred->md.inCVWaitQueue = PR_FALSE;
+                    thred = thred->md.next;
+                }
+                notified->cv[index].notifyHead = cv->waitHead;
+                cv->waitHead = cv->waitTail = NULL;
+                cv->nwait = 0;
+            } else {
+                thred = cv->waitHead;
+                i = notified->cv[index].times;
+                while (thred != NULL && i > 0) {
+                    thred->md.inCVWaitQueue = PR_FALSE;
+                    thred = thred->md.next;
+                    i--;
+                }
+                notified->cv[index].notifyHead = cv->waitHead;
+                cv->waitHead = thred;
+                if (cv->waitHead == NULL) {
+                    cv->waitTail = NULL;
+                } else {
+                    if (cv->waitHead->md.prev != NULL) {
+                        cv->waitHead->md.prev->md.next = NULL;
+                        cv->waitHead->md.prev = NULL;
+                    }
+                }
+                cv->nwait -= notified->cv[index].times - i;
+            }
+        }
+        notified = notified->link;
+    } while (NULL != notified);
+
+    if (waitThred) {
+        AddThreadToCVWaitQueueInternal(waitThred, waitCV);
+    }
+
+    /* Release the lock before notifying */
+        LeaveCriticalSection(&lock->mutex);
+
+    notified = &post;  /* this is where we start */
+    do {
+        for (index = 0; index < notified->length; ++index) {
+            PRThread *thred;
+            PRThread *next;
+
+            thred = notified->cv[index].notifyHead;
+            while (thred != NULL) {
+                BOOL rv;
+
+                next = thred->md.next;
+                thred->md.prev = thred->md.next = NULL;
+
+                rv = ReleaseSemaphore(thred->md.blocked_sema, 1, NULL);
+                PR_ASSERT(rv != 0);
+                thred = next;
+            }
+        }
+        prev = notified;
+        notified = notified->link;
+        if (&post != prev) PR_DELETE(prev);
+    } while (NULL != notified);
+}
+
+/*
+ * Notifies just get posted to the protecting mutex.  The
+ * actual notification is done when the lock is released so that
+ * MP systems don't contend for a lock that they can't have.
+ */
+static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock,
+        PRBool broadcast)
+{
+    PRIntn index = 0;
+    _MDNotified *notified = &lock->notified;
+
+    while (1) {
+        for (index = 0; index < notified->length; ++index) {
+            if (notified->cv[index].cv == cvar) {
+                if (broadcast) {
+                    notified->cv[index].times = -1;
+                } else if (-1 != notified->cv[index].times) {
+                    notified->cv[index].times += 1;
+                }
+                return;
+            }
+        }
+        /* if not full, enter new CV in this array */
+        if (notified->length < _MD_CV_NOTIFIED_LENGTH) break;
+
+        /* if there's no link, create an empty array and link it */
+        if (NULL == notified->link) {
+            notified->link = PR_NEWZAP(_MDNotified);
+        }
+
+        notified = notified->link;
+    }
+
+    /* A brand new entry in the array */
+    notified->cv[index].times = (broadcast) ? -1 : 1;
+    notified->cv[index].cv = cvar;
+    notified->length += 1;
+}
+
+/*
+ * _PR_MD_NEW_CV() -- Creating new condition variable
+ * ... Solaris uses cond_init() in similar function.
+ *
+ * returns: -1 on failure
+ *          0 when it succeeds.
+ *
+ */
+PRInt32 
+_PR_MD_NEW_CV(_MDCVar *cv)
+{
+    cv->magic = _MD_MAGIC_CV;
+    /*
+     * The waitHead, waitTail, and nwait fields are zeroed
+     * when the PRCondVar structure is created.
+     */
+    return 0;
+} 
+
+void _PR_MD_FREE_CV(_MDCVar *cv)
+{
+    cv->magic = (PRUint32)-1;
+    return;
+}
+
+/*
+ *  _PR_MD_WAIT_CV() -- Wait on condition variable
+ */
+void _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
+{
+    PRThread *thred = _PR_MD_CURRENT_THREAD();
+    DWORD rv;
+    DWORD msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ?
+            INFINITE : PR_IntervalToMilliseconds(timeout);
+
+    /*
+     * If we have pending notifies, post them now.
+     */
+    if (0 != lock->notified.length) {
+        md_UnlockAndPostNotifies(lock, thred, cv);
+    } else {
+        AddThreadToCVWaitQueueInternal(thred, cv);
+        LeaveCriticalSection(&lock->mutex);
+    }
+
+    /* Wait for notification or timeout; don't really care which */
+    rv = WaitForSingleObject(thred->md.blocked_sema, msecs);
+
+    EnterCriticalSection(&(lock->mutex));
+
+    PR_ASSERT(rv != WAIT_ABANDONED);
+    PR_ASSERT(rv != WAIT_FAILED);
+    PR_ASSERT(rv != WAIT_OBJECT_0 || thred->md.inCVWaitQueue == PR_FALSE);
+
+    if (rv == WAIT_TIMEOUT) {
+        if (thred->md.inCVWaitQueue) {
+            PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
+                    || (cv->waitTail == NULL && cv->waitHead == NULL));
+            cv->nwait -= 1;
+            thred->md.inCVWaitQueue = PR_FALSE;
+            if (cv->waitHead == thred) {
+                cv->waitHead = thred->md.next;
+                if (cv->waitHead == NULL) {
+                    cv->waitTail = NULL;
+                } else {
+                    cv->waitHead->md.prev = NULL;
+                }
+            } else {
+                PR_ASSERT(thred->md.prev != NULL);
+                thred->md.prev->md.next = thred->md.next;
+                if (thred->md.next != NULL) {
+                    thred->md.next->md.prev = thred->md.prev;
+                } else {
+                    PR_ASSERT(cv->waitTail == thred);
+                    cv->waitTail = thred->md.prev;
+                }
+            }
+            thred->md.next = thred->md.prev = NULL;
+        } else {
+            /*
+             * This thread must have been notified, but the
+             * ReleaseSemaphore call happens after WaitForSingleObject
+             * times out.  Wait on the semaphore again to make it
+             * non-signaled.  We assume this wait won't take long.
+             */
+            rv = WaitForSingleObject(thred->md.blocked_sema, INFINITE);
+            PR_ASSERT(rv == WAIT_OBJECT_0);
+        }
+    }
+    PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE);
+    return;
+} /* --- end _PR_MD_WAIT_CV() --- */
+
+void _PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock)
+{
+    md_PostNotifyToCvar(cv, lock, PR_FALSE);
+    return;
+}
+
+void _PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock)
+{
+    md_PostNotifyToCvar(cv, lock, PR_TRUE);
+    return;
+}
+
+void _PR_MD_UNLOCK(_MDLock *lock)
+{
+    if (0 != lock->notified.length) {
+        md_UnlockAndPostNotifies(lock, NULL, NULL);
+    } else {
+        LeaveCriticalSection(&lock->mutex);
+    }
+    return;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95dllmain.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95dllmain.c
new file mode 100644
index 0000000..1dafe7a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95dllmain.c
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * The DLL entry point (DllMain) for NSPR.
+ *
+ * This is used to detach threads that were automatically attached by
+ * nspr.
+ */
+
+#include <windows.h>
+#include <primpl.h>
+
+BOOL WINAPI DllMain(
+    HINSTANCE hinstDLL,
+    DWORD fdwReason,
+    LPVOID lpvReserved)
+{
+PRThread *me;
+
+    switch (fdwReason) {
+        case DLL_PROCESS_ATTACH:
+            break;
+        case DLL_THREAD_ATTACH:
+            break;
+        case DLL_THREAD_DETACH:
+            if (_pr_initialized) {
+                me = _MD_GET_ATTACHED_THREAD();
+                if ((me != NULL) && (me->flags & _PR_ATTACHED))
+                    _PRI_DetachThread();
+            }
+            break;
+        case DLL_PROCESS_DETACH:
+            break;
+    }
+    return TRUE;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95io.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95io.c
new file mode 100644
index 0000000..86f952a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95io.c
@@ -0,0 +1,1786 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Masayuki Nakano <masayuki@d-toybox.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Windows 95 IO module
+ *
+ * Assumes synchronous I/O.
+ *
+ */
+
+#include "primpl.h"
+#include <direct.h>
+#include <mbstring.h>
+#ifdef MOZ_UNICODE
+#include <wchar.h>
+#endif /* MOZ_UNICODE */
+
+#ifdef WINCE
+
+static HANDLE CreateFileA(LPCSTR lpFileName,
+                          DWORD dwDesiredAccess,
+                          DWORD dwShareMode,
+                          LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+                          DWORD dwCreationDisposition,
+                          DWORD dwFlagsAndAttributes,
+                          HANDLE hTemplateFile)
+{
+    PRUnichar wFileName[MAX_PATH];
+    MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, wFileName, MAX_PATH);
+    return CreateFileW(wFileName, dwDesiredAccess, dwShareMode,
+                       lpSecurityAttributes, dwCreationDisposition,
+                       dwFlagsAndAttributes, hTemplateFile);
+}
+
+/*
+ * We seem to call FindFirstFileA and FindNextFileA just to get
+ * the file names in a directory listing.  If so, we could define
+ * a custom WIN32_FIND_DATAA structure with just the cFileName
+ * member, and the CopyFindFileDataW2A function could just
+ * copy/convert the cFileName member.
+ */
+static void CopyFindFileDataW2A(LPWIN32_FIND_DATAW from,
+                                LPWIN32_FIND_DATAA to)
+{
+    /*
+     * WIN32_FIND_DATAA and WIN32_FIND_DATAW are slightly different.
+     * The dwReserved0, dwReserved1, and cAlternateFileName members
+     * exist only in WIN32_FIND_DATAA.  The dwOID member exists only
+     * in WIN32_FIND_DATAW.
+     */
+    to->dwFileAttributes = from->dwFileAttributes;
+    to->ftCreationTime = from->ftCreationTime;
+    to->ftLastAccessTime = from->ftLastAccessTime;
+    to->ftLastWriteTime = from->ftLastWriteTime;
+    to->nFileSizeHigh = from->nFileSizeHigh;
+    to->nFileSizeLow = from->nFileSizeLow;
+    to->dwReserved0 = 0;
+    to->dwReserved1 = 0;
+    WideCharToMultiByte(CP_ACP, 0, from->cFileName, -1,
+                        to->cFileName, MAX_PATH, NULL, NULL);
+    to->cAlternateFileName[0] = '\0';
+}
+
+static HANDLE FindFirstFileA(LPCSTR lpFileName,
+                             LPWIN32_FIND_DATAA lpFindFileData)
+{
+    PRUnichar wFileName[MAX_PATH];
+    HANDLE hFindFile;
+    WIN32_FIND_DATAW wFindFileData;
+    
+    MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, wFileName, MAX_PATH);
+    hFindFile = FindFirstFileW(wFileName, &wFindFileData);
+    if (hFindFile != INVALID_HANDLE_VALUE) {
+        CopyFindFileDataW2A(&wFindFileData, lpFindFileData);
+    }
+    return hFindFile;
+}
+
+static BOOL FindNextFileA(HANDLE hFindFile,
+                          LPWIN32_FIND_DATAA lpFindFileData)
+{
+    WIN32_FIND_DATAW wFindFileData;
+    BOOL rv;
+
+    rv = FindNextFileW(hFindFile, &wFindFileData);
+    if (rv) {
+        CopyFindFileDataW2A(&wFindFileData, lpFindFileData);
+    }
+    return rv;
+}
+
+static BOOL GetFileAttributesExA(LPCSTR lpFileName,
+                                 GET_FILEEX_INFO_LEVELS fInfoLevelId,
+                                 LPVOID lpFileInformation)
+{
+    PRUnichar wFileName[MAX_PATH];
+    MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, wFileName, MAX_PATH);
+    return GetFileAttributesExW(wFileName, fInfoLevelId, lpFileInformation);
+}
+
+static BOOL DeleteFileA(LPCSTR lpFileName)
+{
+    PRUnichar wFileName[MAX_PATH];
+    MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, wFileName, MAX_PATH);
+    return DeleteFileW(wFileName);
+}
+
+static BOOL MoveFileA(LPCSTR from, LPCSTR to)
+{
+    PRUnichar wFrom[MAX_PATH];
+    PRUnichar wTo[MAX_PATH];
+    MultiByteToWideChar(CP_ACP, 0, from, -1, wFrom, MAX_PATH);
+    MultiByteToWideChar(CP_ACP, 0, to, -1, wTo, MAX_PATH);
+    return MoveFileW(wFrom, wTo);
+}
+
+static BOOL CreateDirectoryA(LPCSTR lpPathName,
+                             LPSECURITY_ATTRIBUTES lpSecurityAttributes)
+{
+    PRUnichar wPathName[MAX_PATH];
+    MultiByteToWideChar(CP_ACP, 0, lpPathName, -1, wPathName, MAX_PATH);
+    return CreateDirectoryW(wPathName, lpSecurityAttributes);
+}
+
+static BOOL RemoveDirectoryA(LPCSTR lpPathName)
+{
+    PRUnichar wPathName[MAX_PATH];
+    MultiByteToWideChar(CP_ACP, 0, lpPathName, -1, wPathName, MAX_PATH);
+    return RemoveDirectoryW(wPathName);
+}
+
+static long GetDriveType(const char *lpRootPathName)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return 0; // The drive type cannot be determined.
+}
+
+static DWORD GetFullPathName(const char *lpFileName,
+                             DWORD nBufferLength,
+                             const char *lpBuffer,
+                             const char **lpFilePart)
+{
+    // needs work dft
+    DWORD len = strlen(lpFileName);
+    if (len > nBufferLength)
+        return len;
+  
+    strncpy((char *)lpBuffer, lpFileName, len);
+    ((char *)lpBuffer)[len] = '\0';
+  
+    if (lpFilePart) {
+        char *sep = strrchr(lpBuffer, '\\');
+        if (sep) {
+            sep++; // pass the seperator
+            *lpFilePart = sep;
+        } else {
+            *lpFilePart = lpBuffer;
+        }
+    }
+    return len;
+}
+
+static BOOL LockFile(HANDLE hFile,
+                     DWORD dwFileOffsetLow,
+                     DWORD dwFileOffsetHigh,
+                     DWORD nNumberOfBytesToLockLow,
+                     DWORD nNumberOfBytesToLockHigh)
+{
+    OVERLAPPED overlapped = {0};
+    overlapped.Offset = dwFileOffsetLow;
+    overlapped.OffsetHigh = dwFileOffsetHigh;
+    return LockFileEx(hFile,
+                      LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
+                      0, // reserved
+                      nNumberOfBytesToLockLow,
+                      nNumberOfBytesToLockHigh, &overlapped);
+}
+
+static BOOL UnlockFile(HANDLE hFile,
+                       DWORD dwFileOffsetLow,
+                       DWORD dwFileOffsetHigh,
+                       DWORD nNumberOfBytesToUnlockLow,
+                       DWORD nNumberOfBytesToUnlockHigh)
+{
+    OVERLAPPED overlapped = {0};
+    overlapped.Offset = dwFileOffsetLow;
+    overlapped.OffsetHigh = dwFileOffsetHigh;
+    return UnlockFileEx(hFile,
+                        0, // reserved
+                        nNumberOfBytesToUnlockLow,
+                        nNumberOfBytesToUnlockHigh, &overlapped);
+}
+
+static unsigned char *_mbsdec(const unsigned char *string1,
+                              const unsigned char *string2)
+{
+    // needs work dft
+    return NULL;
+}
+
+static unsigned char *_mbsinc(const unsigned char *inCurrent)
+{
+    // needs work dft
+    return (unsigned char *)(inCurrent + 1);
+}
+
+#endif
+
+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
+};
+
+/* Windows CE has GetFileAttributesEx. */
+#ifndef WINCE
+typedef BOOL (WINAPI *GetFileAttributesExFn)(LPCTSTR,
+                                             GET_FILEEX_INFO_LEVELS,
+                                             LPVOID); 
+static GetFileAttributesExFn getFileAttributesEx;
+static void InitGetFileInfo(void);
+#endif
+
+static void InitUnicodeSupport(void);
+
+static PRBool IsPrevCharSlash(const char *str, const char *current);
+
+void
+_PR_MD_INIT_IO()
+{
+    WORD WSAVersion = 0x0101;
+    WSADATA WSAData;
+    int err;
+
+    err = WSAStartup( WSAVersion, &WSAData );
+    PR_ASSERT(0 == err);
+
+#ifdef DEBUG
+    /* Doublecheck _pr_filetime_offset's hard-coded value is correct. */
+    {
+        SYSTEMTIME systime;
+        union {
+           PRTime prt;
+           FILETIME ft;
+        } filetime;
+        BOOL rv;
+
+        systime.wYear = 1970;
+        systime.wMonth = 1;
+        /* wDayOfWeek is ignored */
+        systime.wDay = 1;
+        systime.wHour = 0;
+        systime.wMinute = 0;
+        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();
+
+#ifndef WINCE
+    InitGetFileInfo();
+#endif
+
+    InitUnicodeSupport();
+
+    _PR_MD_InitSockets();
+}
+
+PRStatus
+_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    DWORD rv;
+
+    PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+        INFINITE : PR_IntervalToMilliseconds(ticks);
+    rv = WaitForSingleObject(thread->md.blocked_sema, msecs);
+    switch(rv) 
+    {
+        case WAIT_OBJECT_0:
+            return PR_SUCCESS;
+            break;
+        case WAIT_TIMEOUT:
+            _PR_THREAD_LOCK(thread);
+            if (thread->state == _PR_IO_WAIT) {
+			  ;
+            } else {
+                if (thread->wait.cvar != NULL) {
+                    thread->wait.cvar = NULL;
+                    _PR_THREAD_UNLOCK(thread);
+                } else {
+                    /* The CVAR was notified just as the timeout
+                     * occurred.  This led to us being notified twice.
+                     * call WaitForSingleObject() to clear the semaphore.
+                     */
+                    _PR_THREAD_UNLOCK(thread);
+                    rv = WaitForSingleObject(thread->md.blocked_sema, 0);
+                    PR_ASSERT(rv == WAIT_OBJECT_0);
+                }
+            }
+            return PR_SUCCESS;
+            break;
+        default:
+            return PR_FAILURE;
+            break;
+    }
+}
+PRStatus
+_PR_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if ( _PR_IS_NATIVE_THREAD(thread) ) 
+    {
+        if (ReleaseSemaphore(thread->md.blocked_sema, 1, NULL) == FALSE)
+            return PR_FAILURE;
+        else
+			return PR_SUCCESS;
+	}
+}
+
+
+/* --- FILE IO ----------------------------------------------------------- */
+/*
+ *  _PR_MD_OPEN() -- Open a file
+ *
+ *  returns: a fileHandle
+ *
+ *  The NSPR open flags (osflags) are translated into flags for Win95
+ *
+ *  Mode seems to be passed in as a unix style file permissions argument
+ *  as in 0666, in the case of opening the logFile. 
+ *
+ */
+PROsfd
+_PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    
+    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 = CreateFileA(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; 
+	}
+
+    return (PROsfd)file;
+}
+
+PROsfd
+_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 = CreateFileA(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 (PROsfd)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,
+            &bytes,
+            NULL);
+    
+    if (rv == 0) 
+    {
+        err = GetLastError();
+        /* ERROR_HANDLE_EOF can only be returned by async io */
+        PR_ASSERT(err != ERROR_HANDLE_EOF);
+        if (err == ERROR_BROKEN_PIPE)
+            return 0;
+		else {
+			_PR_MD_MAP_READ_ERROR(err);
+        return -1;
+    }
+    }
+    return bytes;
+}
+
+PRInt32
+_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
+{
+    PROsfd f = fd->secret->md.osfd;
+    PRInt32 bytes;
+    int rv;
+    
+    rv = WriteFile((HANDLE)f,
+            buf,
+            len,
+            &bytes,
+            NULL );
+            
+    if (rv == 0) 
+    {
+		_PR_MD_MAP_WRITE_ERROR(GetLastError());
+        return -1;
+    }
+    return bytes;
+} /* --- end _PR_MD_WRITE() --- */
+
+PROffset32
+_PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
+{
+    DWORD moveMethod;
+    PROffset32 rv;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            moveMethod = FILE_BEGIN;
+            break;
+        case PR_SEEK_CUR:
+            moveMethod = FILE_CURRENT;
+            break;
+        case PR_SEEK_END:
+            moveMethod = FILE_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return -1;
+    }
+
+    rv = SetFilePointer((HANDLE)fd->secret->md.osfd, offset, NULL, moveMethod);
+
+    /*
+     * If the lpDistanceToMoveHigh argument (third argument) is
+     * NULL, SetFilePointer returns 0xffffffff on failure.
+     */
+    if (-1 == rv) {
+        _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+    }
+    return rv;
+}
+
+PROffset64
+_PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
+{
+    DWORD moveMethod;
+    LARGE_INTEGER li;
+    DWORD err;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            moveMethod = FILE_BEGIN;
+            break;
+        case PR_SEEK_CUR:
+            moveMethod = FILE_CURRENT;
+            break;
+        case PR_SEEK_END:
+            moveMethod = FILE_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return -1;
+    }
+
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer((HANDLE)fd->secret->md.osfd,
+            li.LowPart, &li.HighPart, moveMethod);
+
+    if (0xffffffff == li.LowPart && (err = GetLastError()) != NO_ERROR) {
+        _PR_MD_MAP_LSEEK_ERROR(err);
+        li.QuadPart = -1;
+    }
+    return li.QuadPart;
+}
+
+/*
+ * This is documented to succeed on read-only files, but Win32's
+ * FlushFileBuffers functions fails with "access denied" in such a
+ * case.  So we only signal an error if the error is *not* "access
+ * denied".
+ */
+PRInt32
+_PR_MD_FSYNC(PRFileDesc *fd)
+{
+    /*
+     * From the documentation:
+     *
+     *	   On Windows NT, the function FlushFileBuffers fails if hFile
+     *	   is a handle to console output. That is because console
+     *	   output is not buffered. The function returns FALSE, and
+     *	   GetLastError returns ERROR_INVALID_HANDLE.
+     *
+     * On the other hand, on Win95, it returns without error.  I cannot
+     * assume that 0, 1, and 2 are console, because if someone closes
+     * System.out and then opens a file, they might get file descriptor
+     * 1.  An error on *that* version of 1 should be reported, whereas
+     * an error on System.out (which was the original 1) should be
+     * ignored.  So I use isatty() to ensure that such an error was due
+     * to this bogosity, and if it was, I ignore the error.
+     */
+
+    BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd);
+
+    if (!ok) {
+	DWORD err = GetLastError();
+	if (err != ERROR_ACCESS_DENIED) {	// from winerror.h
+			_PR_MD_MAP_FSYNC_ERROR(err);
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+PRInt32
+_MD_CloseFile(PROsfd osfd)
+{
+    PRInt32 rv;
+    
+    rv = (CloseHandle((HANDLE)osfd))?0:-1;
+	if (rv == -1)
+		_PR_MD_MAP_CLOSE_ERROR(GetLastError());
+    return rv;
+}
+
+
+/* --- DIR IO ------------------------------------------------------------ */
+#define GetFileFromDIR(d)       (d)->d_entry.cFileName
+#define FileIsHidden(d)	((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+
+static void FlipSlashes(char *cp, size_t len)
+{
+    while (len-- > 0) {
+        if (cp[0] == '/') {
+            cp[0] = PR_DIRECTORY_SEPARATOR;
+        }
+        cp = _mbsinc(cp);
+    }
+} /* end FlipSlashes() */
+
+
+/*
+**
+** Local implementations of standard Unix RTL functions which are not provided
+** by the VC RTL.
+**
+*/
+
+PRInt32
+_PR_MD_CLOSE_DIR(_MDDir *d)
+{
+    if ( d ) {
+        if (FindClose(d->d_hdl)) {
+        d->magic = (PRUint32)-1;
+        return 0;
+		} else {
+			_PR_MD_MAP_CLOSEDIR_ERROR(GetLastError());
+        	return -1;
+		}
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return -1;
+}
+
+
+PRStatus
+_PR_MD_OPEN_DIR(_MDDir *d, const char *name)
+{
+    char filename[ MAX_PATH ];
+    size_t len;
+
+    len = strlen(name);
+    /* Need 5 bytes for \*.* and the trailing null byte. */
+    if (len + 5 > MAX_PATH) {
+        PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+        return PR_FAILURE;
+    }
+    strcpy(filename, name);
+
+    /*
+     * If 'name' ends in a slash or backslash, do not append
+     * another backslash.
+     */
+    if (IsPrevCharSlash(filename, filename + len)) {
+        len--;
+    }
+    strcpy(&filename[len], "\\*.*");
+    FlipSlashes( filename, strlen(filename) );
+
+    d->d_hdl = FindFirstFileA( filename, &(d->d_entry) );
+    if ( d->d_hdl == INVALID_HANDLE_VALUE ) {
+		_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    d->firstEntry = PR_TRUE;
+    d->magic = _MD_MAGIC_DIR;
+    return PR_SUCCESS;
+}
+
+char *
+_PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
+{
+    PRInt32 err;
+    BOOL rv;
+    char *fileName;
+
+    if ( d ) {
+        while (1) {
+            if (d->firstEntry) {
+                d->firstEntry = PR_FALSE;
+                rv = 1;
+            } else {
+                rv = FindNextFileA(d->d_hdl, &(d->d_entry));
+            }
+            if (rv == 0) {
+                break;
+            }
+            fileName = GetFileFromDIR(d);
+            if ( (flags & PR_SKIP_DOT) &&
+                 (fileName[0] == '.') && (fileName[1] == '\0'))
+                 continue;
+            if ( (flags & PR_SKIP_DOT_DOT) &&
+                 (fileName[0] == '.') && (fileName[1] == '.') &&
+                 (fileName[2] == '\0'))
+                 continue;
+            if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d))
+                 continue;
+            return fileName;
+        }
+        err = GetLastError();
+        PR_ASSERT(NO_ERROR != err);
+			_PR_MD_MAP_READDIR_ERROR(err);
+        return NULL;
+		}
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;
+}
+
+PRInt32
+_PR_MD_DELETE(const char *name)
+{
+    if (DeleteFileA(name)) {
+        return 0;
+    } else {
+		_PR_MD_MAP_DELETE_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+void
+_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm)
+{
+    PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime));
+    CopyMemory(prtm, filetime, sizeof(PRTime));
+#if defined(__MINGW32__)
+    *prtm = (*prtm - _pr_filetime_offset) / 10LL;
+#else
+    *prtm = (*prtm - _pr_filetime_offset) / 10i64;
+#endif
+
+#ifdef DEBUG
+    /* Doublecheck our calculation. */
+    {
+        SYSTEMTIME systime;
+        PRExplodedTime etm;
+        PRTime cmp; /* for comparison */
+        BOOL rv;
+
+        rv = FileTimeToSystemTime(filetime, &systime);
+        PR_ASSERT(0 != rv);
+
+        /*
+         * PR_ImplodeTime ignores wday and yday.
+         */
+        etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC;
+        etm.tm_sec = systime.wSecond;
+        etm.tm_min = systime.wMinute;
+        etm.tm_hour = systime.wHour;
+        etm.tm_mday = systime.wDay;
+        etm.tm_month = systime.wMonth - 1;
+        etm.tm_year = systime.wYear;
+        /*
+         * It is not well-documented what time zone the FILETIME's
+         * are in.  WIN32_FIND_DATA is documented to be in UTC (GMT).
+         * But BY_HANDLE_FILE_INFORMATION is unclear about this.
+         * By our best judgement, we assume that FILETIME is in UTC.
+         */
+        etm.tm_params.tp_gmt_offset = 0;
+        etm.tm_params.tp_dst_offset = 0;
+        cmp = PR_ImplodeTime(&etm);
+
+        /*
+         * SYSTEMTIME is in milliseconds precision, so we convert PRTime's
+         * microseconds to milliseconds before doing the comparison.
+         */
+        PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC));
+    }
+#endif /* DEBUG */
+}
+
+PRInt32
+_PR_MD_STAT(const char *fn, struct stat *info)
+{
+#ifdef WINCE
+    // needs work. dft
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+#else
+    PRInt32 rv;
+
+    rv = _stat(fn, (struct _stat *)info);
+    if (-1 == rv) {
+        /*
+         * Check for MSVC runtime library _stat() bug.
+         * (It's really a bug in FindFirstFile().)
+         * If a pathname ends in a backslash or slash,
+         * e.g., c:\temp\ or c:/temp/, _stat() will fail.
+         * Note: a pathname ending in a slash (e.g., c:/temp/)
+         * can be handled by _stat() on NT but not on Win95.
+         *
+         * We remove the backslash or slash at the end and
+         * try again.
+         */
+
+        size_t len = strlen(fn);
+        if (len > 0 && len <= _MAX_PATH
+                && IsPrevCharSlash(fn, fn + len)) {
+            char newfn[_MAX_PATH + 1];
+
+            strcpy(newfn, fn);
+            newfn[len - 1] = '\0';
+            rv = _stat(newfn, (struct _stat *)info);
+        }
+    }
+
+    if (-1 == rv) {
+        _PR_MD_MAP_STAT_ERROR(errno);
+    }
+    return rv;
+#endif
+}
+
+#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\')
+
+static PRBool
+IsPrevCharSlash(const char *str, const char *current)
+{
+    const char *prev;
+
+    if (str >= current)
+        return PR_FALSE;
+    prev = _mbsdec(str, current);
+    return (prev == current - 1) && _PR_IS_SLASH(*prev);
+}
+
+/*
+ * IsRootDirectory --
+ *
+ * Return PR_TRUE if the pathname 'fn' is a valid root directory,
+ * else return PR_FALSE.  The char buffer pointed to by 'fn' must
+ * be writable.  During the execution of this function, the contents
+ * of the buffer pointed to by 'fn' may be modified, but on return
+ * the original contents will be restored.  'buflen' is the size of
+ * the buffer pointed to by 'fn'.
+ *
+ * Root directories come in three formats:
+ * 1. / or \, meaning the root directory of the current drive.
+ * 2. C:/ or C:\, where C is a drive letter.
+ * 3. \\<server name>\<share point name>\ or
+ *    \\<server name>\<share point name>, meaning the root directory
+ *    of a UNC (Universal Naming Convention) name.
+ */
+
+static PRBool
+IsRootDirectory(char *fn, size_t buflen)
+{
+    char *p;
+    PRBool slashAdded = PR_FALSE;
+    PRBool rv = PR_FALSE;
+
+    if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') {
+        return PR_TRUE;
+    }
+
+    if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2])
+            && fn[3] == '\0') {
+        rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+        return rv;
+    }
+
+    /* The UNC root directory */
+
+    if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) {
+        /* The 'server' part should have at least one character. */
+        p = &fn[2];
+        if (*p == '\0' || _PR_IS_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the next slash */
+        do {
+            p = _mbsinc(p);
+        } while (*p != '\0' && !_PR_IS_SLASH(*p));
+        if (*p == '\0') {
+            return PR_FALSE;
+        }
+
+        /* The 'share' part should have at least one character. */
+        p++;
+        if (*p == '\0' || _PR_IS_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the final slash */
+        do {
+            p = _mbsinc(p);
+        } while (*p != '\0' && !_PR_IS_SLASH(*p));
+        if (_PR_IS_SLASH(*p) && p[1] != '\0') {
+            return PR_FALSE;
+        }
+        if (*p == '\0') {
+            /*
+             * GetDriveType() doesn't work correctly if the
+             * path is of the form \\server\share, so we add
+             * a final slash temporarily.
+             */
+            if ((p + 1) < (fn + buflen)) {
+                *p++ = '\\';
+                *p = '\0';
+                slashAdded = PR_TRUE;
+            } else {
+                return PR_FALSE; /* name too long */
+            }
+        }
+        rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+        /* restore the 'fn' buffer */
+        if (slashAdded) {
+            *--p = '\0';
+        }
+    }
+    return rv;
+}
+
+#ifndef WINCE
+/*
+ * InitGetFileInfo --
+ *
+ * Called during IO init. Checks for the existence of the system function
+ * GetFileAttributeEx, which when available is used in GETFILEINFO calls. 
+ * If the routine exists, then the address of the routine is stored in the
+ * variable getFileAttributesEx, which will be used to call the routine.
+ */
+static void InitGetFileInfo(void)
+{
+    HMODULE module;
+    module = GetModuleHandle("Kernel32.dll");
+    if (!module) {
+        PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+                ("InitGetFileInfo: GetModuleHandle() failed: %d",
+                GetLastError()));
+        return;
+    }
+
+    getFileAttributesEx = (GetFileAttributesExFn)
+            GetProcAddress(module, "GetFileAttributesExA");
+}
+
+/*
+ * If GetFileAttributeEx doesn't exist, we call FindFirstFile as a
+ * fallback.
+ */
+static BOOL
+GetFileAttributesExFB(const char *fn, WIN32_FIND_DATA *findFileData)
+{
+    HANDLE hFindFile;
+
+    /*
+     * FindFirstFile() expands wildcard characters.  So
+     * we make sure the pathname contains no wildcard.
+     */
+    if (NULL != _mbspbrk(fn, "?*")) {
+        SetLastError(ERROR_INVALID_NAME);
+        return FALSE;
+    }
+
+    hFindFile = FindFirstFile(fn, findFileData);
+    if (INVALID_HANDLE_VALUE == hFindFile) {
+        DWORD len;
+        char *filePart;
+        char pathbuf[MAX_PATH + 1];
+
+        /*
+         * FindFirstFile() does not work correctly on root directories.
+         * It also doesn't work correctly on a pathname that ends in a
+         * slash.  So we first check to see if the pathname specifies a
+         * 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 == _mbspbrk(fn, ".\\/")) {
+            return FALSE;
+        } 
+        len = GetFullPathName(fn, sizeof(pathbuf), pathbuf,
+                &filePart);
+        if (0 == len) {
+            return FALSE;
+        }
+        if (len > sizeof(pathbuf)) {
+            SetLastError(ERROR_FILENAME_EXCED_RANGE);
+            return FALSE;
+        }
+        if (IsRootDirectory(pathbuf, sizeof(pathbuf))) {
+            findFileData->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
+            /* The file size doesn't have a meaning for directories. */
+            findFileData->nFileSizeHigh = 0;
+            findFileData->nFileSizeLow = 0;
+            /*
+             * For a directory, these timestamps all specify when the
+             * directory is created.  The creation time doesn't make
+             * sense for root directories, so we set it to (NSPR) time 0.
+             */
+            memcpy(&findFileData->ftCreationTime, &_pr_filetime_offset, 8);
+            findFileData->ftLastAccessTime = findFileData->ftCreationTime;
+            findFileData->ftLastWriteTime = findFileData->ftCreationTime;
+            return TRUE;
+        }
+        if (!IsPrevCharSlash(pathbuf, pathbuf + len)) {
+            return FALSE;
+        } else {
+            pathbuf[len - 1] = '\0';
+            hFindFile = FindFirstFile(pathbuf, findFileData);
+            if (INVALID_HANDLE_VALUE == hFindFile) {
+                return FALSE;
+            }
+        }
+    }
+
+    FindClose(hFindFile);
+    return TRUE;
+}
+#endif
+
+PRInt32
+_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
+{
+#ifdef WINCE
+    WIN32_FILE_ATTRIBUTE_DATA findFileData;
+#else
+    WIN32_FIND_DATA findFileData;
+#endif
+    BOOL rv;
+    
+    if (NULL == fn || '\0' == *fn) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+
+#ifdef WINCE
+    rv = GetFileAttributesExA(fn, GetFileExInfoStandard, &findFileData);
+#else
+    /* GetFileAttributesEx is supported on Win 2K and up. */
+    if (getFileAttributesEx) {
+        rv = getFileAttributesEx(fn, GetFileExInfoStandard, &findFileData);
+    } else {
+        rv = GetFileAttributesExFB(fn, &findFileData);
+    }
+#endif
+    if (!rv) {
+        _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        info->type = PR_FILE_DIRECTORY;
+    } else {
+        info->type = PR_FILE_FILE;
+    }
+
+    info->size = findFileData.nFileSizeHigh;
+    info->size = (info->size << 32) + findFileData.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime);
+
+    if (0 == findFileData.ftCreationTime.dwLowDateTime &&
+            0 == findFileData.ftCreationTime.dwHighDateTime) {
+        info->creationTime = info->modifyTime;
+    } else {
+        _PR_FileTimeToPRTime(&findFileData.ftCreationTime,
+                &info->creationTime);
+    }
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
+{
+    PRFileInfo64 info64;
+    PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64);
+    if (0 == rv)
+    {
+        info->type = info64.type;
+        info->size = (PRUint32) info64.size;
+        info->modifyTime = info64.modifyTime;
+        info->creationTime = info64.creationTime;
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    int rv;
+
+    BY_HANDLE_FILE_INFORMATION hinfo;
+
+    rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo);
+    if (rv == FALSE) {
+		_PR_MD_MAP_FSTAT_ERROR(GetLastError());
+        return -1;
+	}
+
+    if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_FILE;
+
+    info->size = hinfo.nFileSizeHigh;
+    info->size = (info->size << 32) + hinfo.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) );
+    _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) );
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
+{
+    PRFileInfo64 info64;
+    int rv = _PR_MD_GETOPENFILEINFO64(fd, &info64);
+    if (0 == rv)
+    {
+        info->type = info64.type;
+        info->modifyTime = info64.modifyTime;
+        info->creationTime = info64.creationTime;
+        LL_L2I(info->size, info64.size);
+    }
+    return rv;
+}
+
+PRStatus
+_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
+{
+#ifdef WINCE
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+#else
+    BOOL rv;
+
+    /*
+     * The SetHandleInformation function fails with the
+     * ERROR_CALL_NOT_IMPLEMENTED error on Win95.
+     */
+    rv = SetHandleInformation(
+            (HANDLE)fd->secret->md.osfd,
+            HANDLE_FLAG_INHERIT,
+            inheritable ? HANDLE_FLAG_INHERIT : 0);
+    if (0 == rv) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+#endif
+} 
+
+void
+_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
+{
+    if (imported) {
+        fd->secret->inheritable = _PR_TRI_UNKNOWN;
+    } else {
+        fd->secret->inheritable = _PR_TRI_FALSE;
+    }
+}
+
+void
+_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
+{
+#ifdef WINCE
+    fd->secret->inheritable = _PR_TRI_FALSE;
+#else
+    DWORD flags;
+
+    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+    if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) {
+        if (flags & HANDLE_FLAG_INHERIT) {
+            fd->secret->inheritable = _PR_TRI_TRUE;
+        } else {
+            fd->secret->inheritable = _PR_TRI_FALSE;
+        }
+    }
+#endif
+}
+
+PRInt32
+_PR_MD_RENAME(const char *from, const char *to)
+{
+    /* Does this work with dot-relative pathnames? */
+    if (MoveFileA(from, to)) {
+        return 0;
+    } else {
+		_PR_MD_MAP_RENAME_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_ACCESS(const char *name, PRAccessHow how)
+{
+#ifdef WINCE
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+#else
+PRInt32 rv;
+    switch (how) {
+      case PR_ACCESS_WRITE_OK:
+        rv = _access(name, 02);
+		break;
+      case PR_ACCESS_READ_OK:
+        rv = _access(name, 04);
+		break;
+      case PR_ACCESS_EXISTS:
+        return _access(name, 00);
+	  	break;
+      default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+    }
+	if (rv < 0)
+		_PR_MD_MAP_ACCESS_ERROR(errno);
+    return rv;
+#endif
+}
+
+PRInt32
+_PR_MD_MKDIR(const char *name, PRIntn mode)
+{
+    /* XXXMB - how to translate the "mode"??? */
+    if (CreateDirectoryA(name, NULL)) {
+        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 = CreateDirectoryA(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 (RemoveDirectoryA(name)) {
+        return 0;
+    } else {
+		_PR_MD_MAP_RMDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRStatus
+_PR_MD_LOCKFILE(PROsfd f)
+{
+    PRStatus  rc = PR_SUCCESS;
+	DWORD     rv;
+
+	rv = LockFile( (HANDLE)f,
+		0l, 0l,
+		0x0l, 0xffffffffl ); 
+	if ( rv == 0 ) {
+        DWORD rc = GetLastError();
+        PR_LOG( _pr_io_lm, PR_LOG_ERROR,
+            ("_PR_MD_LOCKFILE() failed. Error: %d", rc ));
+        rc = PR_FAILURE;
+    }
+
+    return rc;
+} /* end _PR_MD_LOCKFILE() */
+
+PRStatus
+_PR_MD_TLOCKFILE(PROsfd f)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return PR_FAILURE;
+} /* end _PR_MD_TLOCKFILE() */
+
+
+PRStatus
+_PR_MD_UNLOCKFILE(PROsfd f)
+{
+	PRInt32   rv;
+    
+    rv = UnlockFile( (HANDLE) f,
+    		0l, 0l,
+            0x0l, 0xffffffffl ); 
+            
+    if ( rv )
+    {
+    	return PR_SUCCESS;
+    }
+    else
+    {
+		_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+		return PR_FAILURE;
+    }
+} /* end _PR_MD_UNLOCKFILE() */
+
+PRInt32
+_PR_MD_PIPEAVAILABLE(PRFileDesc *fd)
+{
+    if (NULL == fd)
+		PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+	else
+		PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+}
+
+#ifdef MOZ_UNICODE
+
+typedef HANDLE (WINAPI *CreateFileWFn) (LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
+static CreateFileWFn createFileW = CreateFileW;
+typedef HANDLE (WINAPI *FindFirstFileWFn) (LPCWSTR, LPWIN32_FIND_DATAW);
+static FindFirstFileWFn findFirstFileW = FindFirstFileW;
+typedef BOOL (WINAPI *FindNextFileWFn) (HANDLE, LPWIN32_FIND_DATAW);
+static FindNextFileWFn findNextFileW = FindNextFileW;
+typedef DWORD (WINAPI *GetFullPathNameWFn) (LPCWSTR, DWORD, LPWSTR, LPWSTR *);
+static GetFullPathNameWFn getFullPathNameW = GetFullPathNameW;
+typedef UINT (WINAPI *GetDriveTypeWFn) (LPCWSTR);
+static GetDriveTypeWFn getDriveTypeW = GetDriveTypeW;
+
+#endif /* MOZ_UNICODE */
+
+PRBool _pr_useUnicode = PR_FALSE;
+
+static void InitUnicodeSupport(void)
+{
+#ifdef WINCE
+    /* The A functions don't even exist in Windows Mobile. */
+    _pr_useUnicode = PR_TRUE;
+#else
+    /*
+     * The W functions exist on Win9x as stubs that fail with the
+     * ERROR_CALL_NOT_IMPLEMENTED error.  We plan to emulate the
+     * MSLU W functions on Win9x in the future.
+     */
+
+    /* Find out if we are running on a Unicode enabled version of Windows */
+    OSVERSIONINFOA osvi = {0};
+
+    osvi.dwOSVersionInfoSize = sizeof(osvi);
+    if (GetVersionExA(&osvi)) {
+        _pr_useUnicode = (osvi.dwPlatformId >= VER_PLATFORM_WIN32_NT);
+    } else {
+        _pr_useUnicode = PR_FALSE;
+    }
+#ifdef DEBUG
+    /*
+     * In debug builds, allow explicit use of ANSI methods to simulate
+     * a Win9x environment for testing purposes.
+     */
+    if (getenv("WINAPI_USE_ANSI"))
+        _pr_useUnicode = PR_FALSE;
+#endif
+#endif
+}
+
+#ifdef MOZ_UNICODE
+
+/* ================ UTF16 Interfaces ================================ */
+static void FlipSlashesW(PRUnichar *cp, size_t len)
+{
+    while (len-- > 0) {
+        if (cp[0] == L'/') {
+            cp[0] = L'\\';
+        }
+        cp++;
+    }
+} /* end FlipSlashesW() */
+
+PROsfd
+_PR_MD_OPEN_FILE_UTF16(const PRUnichar *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 = createFileW(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 (PROsfd)file;
+}
+ 
+PRStatus
+_PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *d, const PRUnichar *name)
+{
+    PRUnichar filename[ MAX_PATH ];
+    int len;
+
+    len = wcslen(name);
+    /* Need 5 bytes for \*.* and the trailing null byte. */
+    if (len + 5 > MAX_PATH) {
+        PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+        return PR_FAILURE;
+    }
+    wcscpy(filename, name);
+
+    /*
+     * If 'name' ends in a slash or backslash, do not append
+     * another backslash.
+     */
+    if (filename[len - 1] == L'/' || filename[len - 1] == L'\\') {
+        len--;
+    }
+    wcscpy(&filename[len], L"\\*.*");
+    FlipSlashesW( filename, wcslen(filename) );
+
+    d->d_hdl = findFirstFileW( filename, &(d->d_entry) );
+    if ( d->d_hdl == INVALID_HANDLE_VALUE ) {
+        _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    d->firstEntry = PR_TRUE;
+    d->magic = _MD_MAGIC_DIR;
+    return PR_SUCCESS;
+}
+
+PRUnichar *
+_PR_MD_READ_DIR_UTF16(_MDDirUTF16 *d, PRIntn flags)
+{
+    PRInt32 err;
+    BOOL rv;
+    PRUnichar *fileName;
+
+    if ( d ) {
+        while (1) {
+            if (d->firstEntry) {
+                d->firstEntry = PR_FALSE;
+                rv = 1;
+            } else {
+                rv = findNextFileW(d->d_hdl, &(d->d_entry));
+            }
+            if (rv == 0) {
+                break;
+            }
+            fileName = GetFileFromDIR(d);
+            if ( (flags & PR_SKIP_DOT) &&
+                 (fileName[0] == L'.') && (fileName[1] == L'\0'))
+                continue;
+            if ( (flags & PR_SKIP_DOT_DOT) &&
+                 (fileName[0] == L'.') && (fileName[1] == L'.') &&
+                 (fileName[2] == L'\0'))
+                continue;
+            if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d))
+                continue;
+            return fileName;
+        }
+        err = GetLastError();
+        PR_ASSERT(NO_ERROR != err);
+        _PR_MD_MAP_READDIR_ERROR(err);
+        return NULL;
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;
+}
+ 
+PRInt32
+_PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *d)
+{
+    if ( d ) {
+        if (FindClose(d->d_hdl)) {
+            d->magic = (PRUint32)-1;
+            return 0;
+        } else {
+            _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError());
+            return -1;
+        }
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return -1;
+}
+
+#define _PR_IS_W_SLASH(ch) ((ch) == L'/' || (ch) == L'\\')
+
+/*
+ * IsRootDirectoryW --
+ *
+ * Return PR_TRUE if the pathname 'fn' is a valid root directory,
+ * else return PR_FALSE.  The PRUnichar buffer pointed to by 'fn' must
+ * be writable.  During the execution of this function, the contents
+ * of the buffer pointed to by 'fn' may be modified, but on return
+ * the original contents will be restored.  'buflen' is the size of
+ * the buffer pointed to by 'fn', in PRUnichars.
+ *
+ * Root directories come in three formats:
+ * 1. / or \, meaning the root directory of the current drive.
+ * 2. C:/ or C:\, where C is a drive letter.
+ * 3. \\<server name>\<share point name>\ or
+ *    \\<server name>\<share point name>, meaning the root directory
+ *    of a UNC (Universal Naming Convention) name.
+ */
+
+static PRBool
+IsRootDirectoryW(PRUnichar *fn, size_t buflen)
+{
+    PRUnichar *p;
+    PRBool slashAdded = PR_FALSE;
+    PRBool rv = PR_FALSE;
+
+    if (_PR_IS_W_SLASH(fn[0]) && fn[1] == L'\0') {
+        return PR_TRUE;
+    }
+
+    if (iswalpha(fn[0]) && fn[1] == L':' && _PR_IS_W_SLASH(fn[2])
+            && fn[3] == L'\0') {
+        rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE;
+        return rv;
+    }
+
+    /* The UNC root directory */
+
+    if (_PR_IS_W_SLASH(fn[0]) && _PR_IS_W_SLASH(fn[1])) {
+        /* The 'server' part should have at least one character. */
+        p = &fn[2];
+        if (*p == L'\0' || _PR_IS_W_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the next slash */
+        do {
+            p++;
+        } while (*p != L'\0' && !_PR_IS_W_SLASH(*p));
+        if (*p == L'\0') {
+            return PR_FALSE;
+        }
+
+        /* The 'share' part should have at least one character. */
+        p++;
+        if (*p == L'\0' || _PR_IS_W_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the final slash */
+        do {
+            p++;
+        } while (*p != L'\0' && !_PR_IS_W_SLASH(*p));
+        if (_PR_IS_W_SLASH(*p) && p[1] != L'\0') {
+            return PR_FALSE;
+        }
+        if (*p == L'\0') {
+            /*
+             * GetDriveType() doesn't work correctly if the
+             * path is of the form \\server\share, so we add
+             * a final slash temporarily.
+             */
+            if ((p + 1) < (fn + buflen)) {
+                *p++ = L'\\';
+                *p = L'\0';
+                slashAdded = PR_TRUE;
+            } else {
+                return PR_FALSE; /* name too long */
+            }
+        }
+        rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE;
+        /* restore the 'fn' buffer */
+        if (slashAdded) {
+            *--p = L'\0';
+        }
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info)
+{
+    HANDLE hFindFile;
+    WIN32_FIND_DATAW findFileData;
+    PRUnichar pathbuf[MAX_PATH + 1];
+
+    if (NULL == fn || L'\0' == *fn) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+
+    /*
+     * FindFirstFile() expands wildcard characters.  So
+     * we make sure the pathname contains no wildcard.
+     */
+    if (NULL != wcspbrk(fn, L"?*")) {
+        PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
+        return -1;
+    }
+
+    hFindFile = findFirstFileW(fn, &findFileData);
+    if (INVALID_HANDLE_VALUE == hFindFile) {
+        DWORD len;
+        PRUnichar *filePart;
+
+        /*
+         * FindFirstFile() does not work correctly on root directories.
+         * It also doesn't work correctly on a pathname that ends in a
+         * slash.  So we first check to see if the pathname specifies a
+         * 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 == wcspbrk(fn, L".\\/")) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        } 
+        len = getFullPathNameW(fn, sizeof(pathbuf)/sizeof(pathbuf[0]), pathbuf,
+                &filePart);
+        if (0 == len) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        }
+        if (len > sizeof(pathbuf)/sizeof(pathbuf[0])) {
+            PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+            return -1;
+        }
+        if (IsRootDirectoryW(pathbuf, sizeof(pathbuf)/sizeof(pathbuf[0]))) {
+            info->type = PR_FILE_DIRECTORY;
+            info->size = 0;
+            /*
+             * These timestamps don't make sense for root directories.
+             */
+            info->modifyTime = 0;
+            info->creationTime = 0;
+            return 0;
+        }
+        if (!_PR_IS_W_SLASH(pathbuf[len - 1])) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        } else {
+            pathbuf[len - 1] = L'\0';
+            hFindFile = findFirstFileW(pathbuf, &findFileData);
+            if (INVALID_HANDLE_VALUE == hFindFile) {
+                _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+                return -1;
+            }
+        }
+    }
+
+    FindClose(hFindFile);
+
+    if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        info->type = PR_FILE_DIRECTORY;
+    } else {
+        info->type = PR_FILE_FILE;
+    }
+
+    info->size = findFileData.nFileSizeHigh;
+    info->size = (info->size << 32) + findFileData.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime);
+
+    if (0 == findFileData.ftCreationTime.dwLowDateTime &&
+            0 == findFileData.ftCreationTime.dwHighDateTime) {
+        info->creationTime = info->modifyTime;
+    } else {
+        _PR_FileTimeToPRTime(&findFileData.ftCreationTime,
+                &info->creationTime);
+    }
+
+    return 0;
+}
+/* ================ end of UTF16 Interfaces ================================ */
+#endif /* MOZ_UNICODE */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95sock.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95sock.c
new file mode 100644
index 0000000..4e67a22
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95sock.c
@@ -0,0 +1,771 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Win95 Sockets module
+ *
+ */
+
+#include "primpl.h"
+
+#define READ_FD     1
+#define WRITE_FD    2
+#define CONNECT_FD  3
+
+static PRInt32 socket_io_wait(
+    PROsfd osfd, 
+    PRInt32 fd_type,
+    PRIntervalTime timeout);
+
+
+/* --- SOCKET IO --------------------------------------------------------- */
+
+/*
+ * we only want to call WSAIoctl() on Vista and later
+ * so don't pay for it at build time (and avoid including winsock2.h)
+ */
+
+/* from ws2def.h */
+#define IOC_IN                      0x80000000      /* copy in parameters */
+#define IOC_VENDOR                  0x18000000
+#define _WSAIOW(x,y)                (IOC_IN|(x)|(y))
+/* from MSWSockDef.h */
+#define SIO_SET_COMPATIBILITY_MODE  _WSAIOW(IOC_VENDOR,300)
+
+typedef enum _WSA_COMPATIBILITY_BEHAVIOR_ID {
+    WsaBehaviorAll = 0,
+    WsaBehaviorReceiveBuffering,
+    WsaBehaviorAutoTuning
+} WSA_COMPATIBILITY_BEHAVIOR_ID, *PWSA_COMPATIBILITY_BEHAVIOR_ID;
+
+/* from sdkddkver.h */
+#define NTDDI_WIN6              0x06000000  /* Windows Vista */
+
+/* from winsock2.h */
+#define WSAEVENT                HANDLE
+
+#define WSAOVERLAPPED           OVERLAPPED
+typedef struct _OVERLAPPED *    LPWSAOVERLAPPED;
+
+typedef void (CALLBACK * LPWSAOVERLAPPED_COMPLETION_ROUTINE)(
+    IN DWORD dwError,
+    IN DWORD cbTransferred,
+    IN LPWSAOVERLAPPED lpOverlapped,
+    IN DWORD dwFlags
+);
+
+typedef int (__stdcall * WSAIOCTLPROC) (
+    SOCKET s,
+    DWORD dwIoControlCode,
+    LPVOID lpvInBuffer,
+    DWORD cbInBuffer,
+    LPVOID lpvOutBuffer,
+    DWORD cbOutBuffer,
+    LPDWORD lpcbBytesReturned,
+    LPWSAOVERLAPPED lpOverlapped,
+    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+);
+
+typedef struct _WSA_COMPATIBILITY_MODE {
+    WSA_COMPATIBILITY_BEHAVIOR_ID BehaviorId;
+    ULONG TargetOsVersion;
+} WSA_COMPATIBILITY_MODE, *PWSA_COMPATIBILITY_MODE;
+
+static HMODULE libWinsock2 = NULL;
+static WSAIOCTLPROC wsaioctlProc = NULL;
+static PRBool socketSetCompatMode = PR_FALSE;
+
+void _PR_MD_InitSockets(void)
+{
+    OSVERSIONINFO osvi;
+
+    memset(&osvi, 0, sizeof(osvi));
+    osvi.dwOSVersionInfoSize = sizeof(osvi);
+    GetVersionEx(&osvi);
+
+    /* if Vista or later... */
+    if (osvi.dwMajorVersion >= 6)
+    {
+        libWinsock2 = LoadLibraryW(L"Ws2_32.dll");
+        if (libWinsock2)
+        {
+            wsaioctlProc = (WSAIOCTLPROC)GetProcAddress(libWinsock2, 
+                                                        "WSAIoctl");
+            if (wsaioctlProc)
+            {
+                socketSetCompatMode = PR_TRUE;
+            }
+        }
+    }
+}
+
+void _PR_MD_CleanupSockets(void)
+{
+    socketSetCompatMode = PR_FALSE;
+    wsaioctlProc = NULL;
+    if (libWinsock2)
+    {
+        FreeLibrary(libWinsock2);
+        libWinsock2 = NULL;
+    }
+}
+
+PROsfd
+_PR_MD_SOCKET(int af, int type, int flags)
+{
+    SOCKET sock;
+    u_long one = 1;
+
+    sock = socket(af, type, flags);
+
+    if (sock == INVALID_SOCKET ) 
+    {
+        _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError());
+        return (PROsfd)sock;
+    }
+
+    /*
+    ** Make the socket Non-Blocking
+    */
+    if (ioctlsocket( sock, FIONBIO, &one) != 0)
+    {
+        PR_SetError(PR_UNKNOWN_ERROR, WSAGetLastError());
+        closesocket(sock);
+        return -1;
+    }
+
+    if ((af == AF_INET || af == AF_INET6) && 
+        type == SOCK_STREAM && socketSetCompatMode)
+    {
+        WSA_COMPATIBILITY_MODE mode;
+        char dummy[4];
+        int ret_dummy;
+
+        mode.BehaviorId = WsaBehaviorAutoTuning;
+        mode.TargetOsVersion = NTDDI_WIN6;
+        if (wsaioctlProc(sock, SIO_SET_COMPATIBILITY_MODE,  
+                         (char *)&mode, sizeof(mode),
+                         dummy, 4, &ret_dummy, 0, NULL) == SOCKET_ERROR)
+        {
+            int err = WSAGetLastError();
+            PR_LOG(_pr_io_lm, PR_LOG_DEBUG, ("WSAIoctl() failed with %d", err));
+
+            /* SIO_SET_COMPATIBILITY_MODE may not be supported.
+            ** If the call to WSAIoctl() fails with WSAEOPNOTSUPP,
+            ** don't close the socket.
+            */ 
+        }
+    }
+
+    return (PROsfd)sock;
+}
+
+/*
+** _MD_CloseSocket() -- Close a socket
+**
+*/
+PRInt32
+_MD_CloseSocket(PROsfd osfd)
+{
+    PRInt32 rv;
+
+    rv = closesocket((SOCKET) osfd );
+    if (rv < 0)
+        _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
+
+    return rv;
+}
+
+PRInt32
+_MD_SocketAvailable(PRFileDesc *fd)
+{
+    PRInt32 result;
+
+    if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError());
+        return -1;
+    }
+    return result;
+}
+
+PROsfd _MD_Accept(
+    PRFileDesc *fd, 
+    PRNetAddr *raddr, 
+    PRUint32 *rlen,
+    PRIntervalTime timeout )
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    SOCKET sock;
+    PRInt32 rv, err;
+
+    while ((sock = accept(osfd, (struct sockaddr *) raddr, rlen)) == -1) 
+    {
+        err = WSAGetLastError();
+        if ((err == WSAEWOULDBLOCK) && (!fd->secret->nonblocking))
+        {
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+            {
+                break;
+            }
+        }
+        else
+        {
+            _PR_MD_MAP_ACCEPT_ERROR(err);
+            break;
+        }
+    }
+    return(sock);
+} /* end _MD_accept() */
+
+PRInt32
+_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, 
+               PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv;
+    int     err;
+
+    if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) 
+    {
+        err = WSAGetLastError();
+        if ((!fd->secret->nonblocking) && (err == WSAEWOULDBLOCK))
+        {
+            rv = socket_io_wait(osfd, CONNECT_FD, timeout);
+            if ( rv < 0 )
+            {
+                return(-1);
+            }
+            else
+            {
+                PR_ASSERT(rv > 0);
+                /* it's connected */
+                return(0);
+            } 
+        }
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv;
+
+    rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen);
+
+    if (rv == SOCKET_ERROR)  {
+        _PR_MD_MAP_BIND_ERROR(WSAGetLastError());
+        return -1;
+    }
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv;
+
+    rv = listen(fd->secret->md.osfd, backlog);
+
+    if (rv == SOCKET_ERROR)  {
+        _PR_MD_MAP_DEFAULT_ERROR(WSAGetLastError());
+        return -1;
+    }
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
+            PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    int osflags;
+
+    if (0 == flags) {
+        osflags = 0;
+    } else {
+        PR_ASSERT(PR_MSG_PEEK == flags);
+        osflags = MSG_PEEK;
+    }
+    while ((rv = recv( osfd, buf, amount, osflags)) == -1) 
+    {
+        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
+            && (!fd->secret->nonblocking))
+        {
+            rv = socket_io_wait(osfd, READ_FD, timeout);
+            if ( rv < 0 )
+            {
+                return -1;
+            } 
+        } 
+        else 
+        {
+            _PR_MD_MAP_RECV_ERROR(err);
+            break;
+        }
+    } /* end while() */
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRInt32 bytesSent = 0;
+
+    while(bytesSent < amount ) 
+    {
+        while ((rv = send( osfd, buf, amount, 0 )) == -1) 
+        {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
+                && (!fd->secret->nonblocking))
+            {
+                rv = socket_io_wait(osfd, WRITE_FD, timeout);
+                if ( rv < 0 )
+                {
+                    return -1;
+                }
+            } 
+            else 
+            {
+                _PR_MD_MAP_SEND_ERROR(err);
+                return -1;
+            }
+        }
+        bytesSent += rv;
+        if (fd->secret->nonblocking)
+        {
+            break;
+        }
+        if (bytesSent < amount) 
+        {
+            rv = socket_io_wait(osfd, WRITE_FD, timeout);
+            if ( rv < 0 )
+            {
+                return -1;
+            }
+        }
+    }
+    return bytesSent;
+}
+
+PRInt32
+_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+              const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRInt32 bytesSent = 0;
+
+    while(bytesSent < amount) 
+    {
+        while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr,
+                addrlen)) == -1) 
+        {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
+                && (!fd->secret->nonblocking))
+            {
+                rv = socket_io_wait(osfd, WRITE_FD, timeout);
+                if ( rv < 0 )
+                {
+                    return -1;
+                }
+            } 
+            else 
+            {
+                _PR_MD_MAP_SENDTO_ERROR(err);
+                return -1;
+            }
+        }
+        bytesSent += rv;
+        if (fd->secret->nonblocking)
+        {
+            break;
+        }
+        if (bytesSent < amount) 
+        {
+            rv = socket_io_wait(osfd, WRITE_FD, timeout);
+            if (rv < 0) 
+            {
+                return -1;
+            }
+        }
+    }
+    return bytesSent;
+}
+
+PRInt32
+_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+                PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+
+    while ((rv = recvfrom( osfd, buf, amount, 0, (struct sockaddr *) addr,
+            addrlen)) == -1) 
+    {
+        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
+            && (!fd->secret->nonblocking))
+        {
+            rv = socket_io_wait(osfd, READ_FD, timeout);
+            if ( rv < 0)
+            {
+                return -1;
+            } 
+        } 
+        else 
+        {
+            _PR_MD_MAP_RECVFROM_ERROR(err);
+            break;
+        }
+    }
+    return(rv);
+}
+
+PRInt32
+_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
+{
+    int index;
+    int sent = 0;
+    int rv;
+
+    for (index=0; index < iov_size; index++) 
+    {
+        rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0, timeout);
+        if (rv > 0) 
+            sent += rv;
+        if ( rv != iov[index].iov_len ) 
+        {
+            if (rv < 0)
+            {
+                if (fd->secret->nonblocking
+                    && (PR_GetError() == PR_WOULD_BLOCK_ERROR)
+                    && (sent > 0))
+                {
+                    return sent;
+                }
+                else
+                {
+                    return -1;
+                }
+            }
+            /* Only a nonblocking socket can have partial sends */
+            PR_ASSERT(fd->secret->nonblocking);
+            return sent;
+        }
+    }
+    return sent;
+}
+
+PRInt32
+_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how)
+{
+PRInt32 rv;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0)
+        _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError());
+    return rv;
+}
+
+PRStatus
+_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len);
+    if (rv==0) {
+        return PR_SUCCESS;
+    } else {
+        _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    rv = getpeername((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len);
+    if (rv==0) {
+        return PR_SUCCESS;
+    } else {
+        _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv;
+
+    rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0) {
+        return PR_SUCCESS;
+    } else {
+        _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv;
+
+    rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0) {
+        return PR_SUCCESS;
+    } else {
+        _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+void
+_MD_MakeNonblock(PRFileDesc *f)
+{
+    return; /* do nothing */
+}
+
+
+
+/*
+ * socket_io_wait --
+ *
+ * Wait for socket i/o, periodically checking for interrupt.
+ *
+ * This function returns 1 on success.  On failure, it returns
+ * -1 and sets the error codes.  It never returns 0.
+ */
+#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
+
+static PRInt32 socket_io_wait(
+    PROsfd osfd, 
+    PRInt32 fd_type,
+    PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    struct timeval tv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime elapsed, remaining;
+    PRBool wait_for_remaining;
+    fd_set rd_wr, ex;
+    int err, len;
+
+    switch (timeout) {
+        case PR_INTERVAL_NO_WAIT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            /*
+             * This is a special case of the 'default' case below.
+             * Please see the comments there.
+             */
+            tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+            tv.tv_usec = 0;
+            FD_ZERO(&rd_wr);
+            FD_ZERO(&ex);
+            do {
+                FD_SET(osfd, &rd_wr);
+                FD_SET(osfd, &ex);
+                switch( fd_type )
+                {
+                    case READ_FD:
+                        rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv);
+                        break;
+                    case WRITE_FD:
+                        rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv);
+                        break;
+                    case CONNECT_FD:
+                        rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv);
+                        break;
+                    default:
+                        PR_ASSERT(0);
+                        break;
+                } /* end switch() */
+                if (rv == -1 )
+                {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    break;
+                }
+                if ( rv > 0 && fd_type == CONNECT_FD )
+                {
+                    /*
+                     * Call Sleep(0) to work around a Winsock timing bug.
+                     */
+                    Sleep(0);
+                    if (FD_ISSET((SOCKET)osfd, &ex))
+                    {
+                        len = sizeof(err);
+                        if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
+                                (char *) &err, &len) == SOCKET_ERROR)
+                        {  
+                            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+                            return -1;
+                        }
+                        if (err != 0)
+                            _PR_MD_MAP_CONNECT_ERROR(err);
+                        else
+                            PR_SetError(PR_UNKNOWN_ERROR, 0);
+                        return -1;
+                    }
+                    if (FD_ISSET((SOCKET)osfd, &rd_wr))
+                    {
+                        /* it's connected */
+                        return 1;
+                    }
+                    PR_ASSERT(0);
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+            } while (rv == 0);
+            break;
+        default:
+            remaining = timeout;
+            FD_ZERO(&rd_wr);
+            FD_ZERO(&ex);
+            do {
+                /*
+                 * We block in _MD_SELECT for at most
+                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+                 * so that there is an upper limit on the delay
+                 * before the interrupt bit is checked.
+                 */
+                wait_for_remaining = PR_TRUE;
+                tv.tv_sec = PR_IntervalToSeconds(remaining);
+                if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
+                    wait_for_remaining = PR_FALSE;
+                    tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+                    tv.tv_usec = 0;
+                } else {
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        remaining -
+                        PR_SecondsToInterval(tv.tv_sec));
+                }
+                FD_SET(osfd, &rd_wr);
+                FD_SET(osfd, &ex);
+                switch( fd_type )
+                {
+                    case READ_FD:
+                        rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv);
+                        break;
+                    case WRITE_FD:
+                        rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv);
+                        break;
+                    case CONNECT_FD:
+                        rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv);
+                        break;
+                    default:
+                        PR_ASSERT(0);
+                        break;
+                } /* end switch() */
+                if (rv == -1)
+                {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    break;
+                }
+                if ( rv > 0 && fd_type == CONNECT_FD )
+                {
+                    /*
+                     * Call Sleep(0) to work around a Winsock timing bug.
+                     */
+                    Sleep(0);
+                    if (FD_ISSET((SOCKET)osfd, &ex))
+                    {
+                        len = sizeof(err);
+                        if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
+                                (char *) &err, &len) == SOCKET_ERROR)
+                        {  
+                            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+                            return -1;
+                        }
+                        if (err != 0)
+                            _PR_MD_MAP_CONNECT_ERROR(err);
+                        else
+                            PR_SetError(PR_UNKNOWN_ERROR, 0);
+                        return -1;
+                    }
+                    if (FD_ISSET((SOCKET)osfd, &rd_wr))
+                    {
+                        /* it's connected */
+                        return 1;
+                    }
+                    PR_ASSERT(0);
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+                /*
+                 * We loop again if _MD_SELECT timed out and the
+                 * timeout deadline has not passed yet.
+                 */
+                if (rv == 0 )
+                {
+                    if (wait_for_remaining) {
+                        elapsed = remaining;
+                    } else {
+                        elapsed = PR_SecondsToInterval(tv.tv_sec) 
+                                    + PR_MicrosecondsToInterval(tv.tv_usec);
+                    }
+                    if (elapsed >= remaining) {
+                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                        rv = -1;
+                        break;
+                    } else {
+                        remaining = remaining - elapsed;
+                    }
+                }
+            } while (rv == 0 );
+            break;
+    }
+    return(rv);
+} /* end socket_io_wait() */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95thred.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95thred.c
new file mode 100644
index 0000000..f896626
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/w95thred.c
@@ -0,0 +1,316 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <process.h>  /* for _beginthreadex() */
+
+#if defined(_MSC_VER) && _MSC_VER <= 1200
+/*
+ * VC++ 6.0 doesn't have DWORD_PTR.
+ */
+
+typedef DWORD DWORD_PTR;
+#endif /* _MSC_VER <= 1200 */
+
+/* --- globals ------------------------------------------------ */
+#ifdef _PR_USE_STATIC_TLS
+__declspec(thread) struct PRThread  *_pr_thread_last_run;
+__declspec(thread) struct PRThread  *_pr_currentThread;
+__declspec(thread) struct _PRCPU    *_pr_currentCPU;
+#else
+DWORD _pr_currentThreadIndex;
+DWORD _pr_lastThreadIndex;
+DWORD _pr_currentCPUIndex;
+#endif
+int                           _pr_intsOff = 0; 
+_PRInterruptTable             _pr_interruptTable[] = { { 0 } };
+
+void
+_PR_MD_EARLY_INIT()
+{
+#ifndef _PR_USE_STATIC_TLS
+    _pr_currentThreadIndex = TlsAlloc();
+    _pr_lastThreadIndex = TlsAlloc();
+    _pr_currentCPUIndex = TlsAlloc();
+#endif
+}
+
+void _PR_MD_CLEANUP_BEFORE_EXIT(void)
+{
+    _PR_NT_FreeSids();
+
+    _PR_MD_CleanupSockets();
+
+    WSACleanup();
+
+#ifndef _PR_USE_STATIC_TLS
+    TlsFree(_pr_currentThreadIndex);
+    TlsFree(_pr_lastThreadIndex);
+    TlsFree(_pr_currentCPUIndex);
+#endif
+}
+
+PRStatus
+_PR_MD_INIT_THREAD(PRThread *thread)
+{
+    if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+        /*
+        ** Warning:
+        ** --------
+        ** NSPR requires a real handle to every thread.
+        ** GetCurrentThread() returns a pseudo-handle which
+        ** is not suitable for some thread operations (e.g.,
+        ** suspending).  Therefore, get a real handle from
+        ** the pseudo handle via DuplicateHandle(...)
+        */
+        DuplicateHandle(
+                GetCurrentProcess(),     /* Process of source handle */
+                GetCurrentThread(),      /* Pseudo Handle to dup */
+                GetCurrentProcess(),     /* Process of handle */
+                &(thread->md.handle),    /* resulting handle */
+                0L,                      /* access flags */
+                FALSE,                   /* Inheritable */
+                DUPLICATE_SAME_ACCESS);  /* Options */
+    }
+
+    /* Create the blocking IO semaphore */
+    thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL);
+    if (thread->md.blocked_sema == NULL)
+        return PR_FAILURE;
+	else
+		return PR_SUCCESS;
+}
+
+static unsigned __stdcall
+pr_root(void *arg)
+{
+    PRThread *thread = (PRThread *)arg;
+    thread->md.start(thread);
+    return 0;
+}
+
+PRStatus 
+_PR_MD_CREATE_THREAD(PRThread *thread, 
+                  void (*start)(void *), 
+                  PRThreadPriority priority, 
+                  PRThreadScope scope, 
+                  PRThreadState state, 
+                  PRUint32 stackSize)
+{
+
+    thread->md.start = start;
+    thread->md.handle = (HANDLE) _beginthreadex(
+                    NULL,
+                    thread->stack->stackSize,
+                    pr_root,
+                    (void *)thread,
+                    CREATE_SUSPENDED,
+                    &(thread->id));
+    if(!thread->md.handle) {
+        return PR_FAILURE;
+    }
+
+    thread->md.id = thread->id;
+    /*
+     * On windows, a thread is created with a thread priority of
+     * THREAD_PRIORITY_NORMAL.
+     */
+    if (priority != PR_PRIORITY_NORMAL) {
+        _PR_MD_SET_PRIORITY(&(thread->md), priority);
+    }
+
+    /* Activate the thread */
+    if ( ResumeThread( thread->md.handle ) != -1)
+        return PR_SUCCESS;
+
+    return PR_FAILURE;
+}
+
+void    
+_PR_MD_YIELD(void)
+{
+    /* Can NT really yield at all? */
+    Sleep(0);
+}
+
+void     
+_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
+{
+    int nativePri;
+    BOOL rv;
+
+    if (newPri < PR_PRIORITY_FIRST) {
+        newPri = PR_PRIORITY_FIRST;
+    } else if (newPri > PR_PRIORITY_LAST) {
+        newPri = PR_PRIORITY_LAST;
+    }
+    switch (newPri) {
+        case PR_PRIORITY_LOW:
+            nativePri = THREAD_PRIORITY_BELOW_NORMAL;
+            break;
+        case PR_PRIORITY_NORMAL:
+            nativePri = THREAD_PRIORITY_NORMAL;
+            break;
+        case PR_PRIORITY_HIGH:
+            nativePri = THREAD_PRIORITY_ABOVE_NORMAL;
+            break;
+        case PR_PRIORITY_URGENT:
+            nativePri = THREAD_PRIORITY_HIGHEST;
+    }
+    rv = SetThreadPriority(thread->handle, nativePri);
+    PR_ASSERT(rv);
+    if (!rv) {
+	PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+                ("PR_SetThreadPriority: can't set thread priority\n"));
+    }
+    return;
+}
+
+void
+_PR_MD_CLEAN_THREAD(PRThread *thread)
+{
+    BOOL rv;
+
+    if (thread->md.blocked_sema) {
+        rv = CloseHandle(thread->md.blocked_sema);
+        PR_ASSERT(rv);
+        thread->md.blocked_sema = 0;
+    }
+
+    if (thread->md.handle) {
+        rv = CloseHandle(thread->md.handle);
+        PR_ASSERT(rv);
+        thread->md.handle = 0;
+    }
+}
+
+void
+_PR_MD_EXIT_THREAD(PRThread *thread)
+{
+    _PR_MD_CLEAN_THREAD(thread);
+    _PR_MD_SET_CURRENT_THREAD(NULL);
+}
+
+
+void
+_PR_MD_EXIT(PRIntn status)
+{
+    _exit(status);
+}
+
+PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
+{
+#ifdef WINCE
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return -1;
+#else
+    DWORD_PTR rv;
+
+    rv = SetThreadAffinityMask(thread->md.handle, mask);
+
+    return rv?0:-1;
+#endif
+}
+
+PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
+{
+#ifdef WINCE
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return -1;
+#else
+    BOOL rv;
+    DWORD_PTR process_mask;
+    DWORD_PTR system_mask;
+
+    rv = GetProcessAffinityMask(GetCurrentProcess(),
+            &process_mask, &system_mask);
+    if (rv)
+        *mask = (PRUint32)process_mask;
+
+    return rv?0:-1;
+#endif
+}
+
+void 
+_PR_MD_SUSPEND_CPU(_PRCPU *cpu) 
+{
+    _PR_MD_SUSPEND_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_RESUME_CPU(_PRCPU *cpu)
+{
+    _PR_MD_RESUME_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_SUSPEND_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        DWORD previousSuspendCount;
+        /* XXXMB - SuspendThread() is not a blocking call; how do we
+         * know when the thread is *REALLY* suspended?
+         */
+        previousSuspendCount = SuspendThread(thread->md.handle);
+        PR_ASSERT(previousSuspendCount == 0);
+    }
+}
+
+void
+_PR_MD_RESUME_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        DWORD previousSuspendCount;
+        previousSuspendCount = ResumeThread(thread->md.handle);
+        PR_ASSERT(previousSuspendCount == 1);
+    }
+}
+
+PRThread*
+_MD_CURRENT_THREAD(void)
+{
+PRThread *thread;
+
+	thread = _MD_GET_ATTACHED_THREAD();
+
+   	if (NULL == thread) {
+		thread = _PRI_AttachThread(
+            PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+	}
+	PR_ASSERT(thread != NULL);
+	return thread;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/win32_errors.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/win32_errors.c
new file mode 100644
index 0000000..ced1b7a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/md/windows/win32_errors.c
@@ -0,0 +1,565 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prerror.h"
+#include "prlog.h"
+#include <errno.h>
+#include <windows.h>
+
+/*
+ * On Win32, we map three kinds of error codes:
+ * - GetLastError(): for Win32 functions
+ * - WSAGetLastError(): for Winsock functions
+ * - errno: for standard C library functions
+ * 
+ * GetLastError() and WSAGetLastError() return error codes in
+ * non-overlapping ranges, so their error codes (ERROR_* and
+ * WSAE*) can be mapped by the same function.  On the other hand,
+ * errno and GetLastError() have overlapping ranges, so we need
+ * to use a separate function to map errno.
+ *
+ * We do not check for WSAEINPROGRESS and WSAEINTR because we do not
+ * use blocking Winsock 1.1 calls.
+ *
+ * Except for the 'socket' call, we do not check for WSAEINITIALISED.
+ * It is assumed that if Winsock is not initialized, that fact will
+ * be detected at the time we create new sockets.
+ */
+
+static void _MD_win32_map_default_errno(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EACCES:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case ENOENT:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        default:
+            prError = PR_UNKNOWN_ERROR;
+            break;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_default_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ERROR_ACCESS_DENIED:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case ERROR_ALREADY_EXISTS:
+            prError = PR_FILE_EXISTS_ERROR;
+            break;
+        case ERROR_CALL_NOT_IMPLEMENTED:
+            prError = PR_NOT_IMPLEMENTED_ERROR;
+            break;
+        case ERROR_DISK_CORRUPT:
+            prError = PR_IO_ERROR; 
+            break;
+        case ERROR_DISK_FULL:
+            prError = PR_NO_DEVICE_SPACE_ERROR;
+            break;
+        case ERROR_DISK_OPERATION_FAILED:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_DRIVE_LOCKED:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+        case ERROR_FILENAME_EXCED_RANGE:
+            prError = PR_NAME_TOO_LONG_ERROR;
+            break;
+        case ERROR_FILE_CORRUPT:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_FILE_EXISTS:
+            prError = PR_FILE_EXISTS_ERROR;
+            break;
+        case ERROR_FILE_INVALID:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case ERROR_FILE_NOT_FOUND:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ERROR_HANDLE_DISK_FULL:
+            prError = PR_NO_DEVICE_SPACE_ERROR;
+            break;
+        case ERROR_INVALID_ADDRESS:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case ERROR_INVALID_HANDLE:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case ERROR_INVALID_NAME:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case ERROR_INVALID_PARAMETER:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case ERROR_INVALID_USER_BUFFER:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case ERROR_LOCKED:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+        case ERROR_NETNAME_DELETED:
+            prError = PR_CONNECT_RESET_ERROR;
+            break;
+        case ERROR_NOACCESS:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case ERROR_NOT_ENOUGH_MEMORY:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case ERROR_NOT_ENOUGH_QUOTA:
+            prError = PR_OUT_OF_MEMORY_ERROR;
+            break;
+        case ERROR_NOT_READY:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_NO_MORE_FILES:
+            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;
+            break;
+        case ERROR_SEEK_ON_DEVICE:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_SHARING_VIOLATION:
+            prError = PR_FILE_IS_BUSY_ERROR;
+            break;
+        case ERROR_STACK_OVERFLOW:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case ERROR_TOO_MANY_OPEN_FILES:
+            prError = PR_SYS_DESC_TABLE_FULL_ERROR;
+            break;
+        case ERROR_WRITE_PROTECT:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case WSAEACCES:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case WSAEADDRINUSE:
+            prError = PR_ADDRESS_IN_USE_ERROR;
+            break;
+        case WSAEADDRNOTAVAIL:
+            prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
+            break;
+        case WSAEAFNOSUPPORT:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case WSAEALREADY:
+            prError = PR_ALREADY_INITIATED_ERROR;
+            break;
+        case WSAEBADF:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case WSAECONNABORTED:
+            prError = PR_CONNECT_ABORTED_ERROR;
+            break;
+        case WSAECONNREFUSED:
+            prError = PR_CONNECT_REFUSED_ERROR;
+            break;
+        case WSAECONNRESET:
+            prError = PR_CONNECT_RESET_ERROR;
+            break;
+        case WSAEDESTADDRREQ:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAEFAULT:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case WSAEHOSTUNREACH:
+            prError = PR_HOST_UNREACHABLE_ERROR;
+            break;
+        case WSAEINVAL:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAEISCONN:
+            prError = PR_IS_CONNECTED_ERROR;
+            break;
+        case WSAEMFILE:
+            prError = PR_PROC_DESC_TABLE_FULL_ERROR;
+            break;
+        case WSAEMSGSIZE:
+            prError = PR_BUFFER_OVERFLOW_ERROR;
+            break;
+        case WSAENETDOWN:
+            prError = PR_NETWORK_DOWN_ERROR;
+            break;
+        case WSAENETRESET:
+            prError = PR_CONNECT_ABORTED_ERROR;
+            break;
+        case WSAENETUNREACH:
+            prError = PR_NETWORK_UNREACHABLE_ERROR;
+            break;
+        case WSAENOBUFS:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case WSAENOPROTOOPT:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAENOTCONN:
+            prError = PR_NOT_CONNECTED_ERROR;
+            break;
+        case WSAENOTSOCK:
+            prError = PR_NOT_SOCKET_ERROR;
+            break;
+        case WSAEOPNOTSUPP:
+            prError = PR_OPERATION_NOT_SUPPORTED_ERROR;
+            break;
+        case WSAEPROTONOSUPPORT:
+            prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR;
+            break;
+        case WSAEPROTOTYPE:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAESHUTDOWN:
+            prError = PR_SOCKET_SHUTDOWN_ERROR;
+            break;
+        case WSAESOCKTNOSUPPORT:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAETIMEDOUT:
+            prError = PR_CONNECT_ABORTED_ERROR;
+            break;
+        case WSAEWOULDBLOCK:
+            prError = PR_WOULD_BLOCK_ERROR;
+            break;
+        default:
+            prError = PR_UNKNOWN_ERROR;
+            break;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_opendir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_closedir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_unix_readdir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_delete_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+/* The error code for stat() is in errno. */
+void _MD_win32_map_stat_error(PRInt32 err)
+{
+    _MD_win32_map_default_errno(err);
+}
+
+void _MD_win32_map_fstat_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_rename_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+/* The error code for access() is in errno. */
+void _MD_win32_map_access_error(PRInt32 err)
+{
+    _MD_win32_map_default_errno(err);
+}
+
+void _MD_win32_map_mkdir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_rmdir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_read_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_transmitfile_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_write_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_lseek_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_fsync_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+/*
+ * For both CloseHandle() and closesocket().
+ */
+void _MD_win32_map_close_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_socket_error(PRInt32 err)
+{
+    PR_ASSERT(err != WSANOTINITIALISED);
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_recv_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_recvfrom_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_send_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEMSGSIZE:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_sendto_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEMSGSIZE:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_accept_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEOPNOTSUPP:
+            prError = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+        case WSAEINVAL:
+            prError = PR_INVALID_STATE_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_acceptex_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_connect_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEWOULDBLOCK:
+            prError = PR_IN_PROGRESS_ERROR;
+            break;
+        case WSAEINVAL:
+            prError = PR_ALREADY_INITIATED_ERROR;
+            break;
+        case WSAETIMEDOUT:
+            prError = PR_IO_TIMEOUT_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_bind_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEINVAL:
+            prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_listen_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEOPNOTSUPP:
+            prError = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+        case WSAEINVAL:
+            prError = PR_INVALID_STATE_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_shutdown_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_getsockname_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEINVAL:
+            prError = PR_INVALID_STATE_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_getpeername_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_getsockopt_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_setsockopt_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_open_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_gethostname_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+/* Win32 select() only works on sockets.  So in this
+** context, WSAENOTSOCK is equivalent to EBADF on Unix.  
+*/
+void _MD_win32_map_select_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAENOTSOCK:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_lockf_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/Makefile.in
new file mode 100644
index 0000000..6ba0ba7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/Makefile.in
@@ -0,0 +1,69 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+CSRCS = prseg.c prshm.c prshma.c
+
+ifdef GC_LEAK_DETECTOR
+CSRCS += prgcleak.c
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+ifdef GC_LEAK_DETECTOR
+INCLUDES += -I$(dist_includedir)/.. -I$(dist_includedir)/../boehm
+endif
+
+DEFINES += -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prgcleak.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prgcleak.c
new file mode 100644
index 0000000..414b385
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prgcleak.c
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Patrick Beard <beard@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * prgcleak.c
+ */
+
+#ifdef GC_LEAK_DETECTOR
+
+/* for FILE */
+#include <stdio.h>
+
+/* NSPR stuff */
+#include "generic_threads.h"
+#include "primpl.h"
+
+extern FILE *GC_stdout, *GC_stderr;
+
+extern void GC_gcollect(void);
+extern void GC_clear_roots(void);
+
+static PRStatus PR_CALLBACK scanner(PRThread* t, void** baseAddr,
+                                    PRUword count, void* closure)
+{
+    if (count) {
+        char* begin = (char*)baseAddr;
+        char* end = (char*)(baseAddr + count);
+        GC_mark_range_proc marker = (GC_mark_range_proc) closure;
+        marker(begin, end);
+    }
+    return PR_SUCCESS;
+}
+
+static void mark_all_stacks(GC_mark_range_proc marker)
+{
+    PR_ScanStackPointers(&scanner, (void *)marker);
+}
+
+#if defined(_PR_PTHREADS)
+#define _PR_MD_CURRENT_CPU() 1
+#endif
+
+static void locker(void* mutex)
+{
+    if (_PR_MD_CURRENT_CPU())
+        PR_EnterMonitor(mutex);
+}
+
+static void unlocker(void* mutex)
+{
+    if (_PR_MD_CURRENT_CPU())
+        PR_ExitMonitor(mutex);
+}
+
+static void stopper(void* unused)
+{
+    if (_PR_MD_CURRENT_CPU())
+        PR_SuspendAll();
+}
+
+static void starter(void* unused)
+{
+    if (_PR_MD_CURRENT_CPU())
+        PR_ResumeAll();
+}
+
+void _PR_InitGarbageCollector()
+{
+    void* mutex;
+
+    /* redirect GC's stderr to catch startup leaks. */
+    GC_stderr = fopen("StartupLeaks", "w");
+
+    mutex = PR_NewMonitor();
+    PR_ASSERT(mutex != NULL);
+
+    GC_generic_init_threads(&mark_all_stacks, mutex,
+            &locker, &unlocker,
+            &stopper, &starter);
+}
+
+void _PR_ShutdownGarbageCollector()
+{
+    /* do anything you need to shut down the collector. */
+}
+
+#endif /* GC_LEAK_DETECTOR */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prseg.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prseg.c
new file mode 100644
index 0000000..14de666
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prseg.c
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#if defined(_PR_PTHREADS)
+
+/*
+** The pthreads version doesn't use these functions.
+*/
+void _PR_InitSegs(void)
+{
+}
+
+#else /* _PR_PTHREADS */
+
+void _PR_InitSegs(void)
+{
+	_PR_MD_INIT_SEGS();
+}
+
+/*
+** Allocate a memory segment. The size value is rounded up to the native
+** system page size and a page aligned portion of memory is returned.
+** This memory is not part of the malloc heap. If "vaddr" is not NULL
+** then PR tries to allocate the segment at the desired virtual address.
+*/
+PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr)
+{
+    PRSegment *seg;
+
+	/* calloc the data structure for the segment */
+    seg = PR_NEWZAP(PRSegment);
+
+    if (seg) {
+	    size = ((size + _pr_pageSize - 1) >> _pr_pageShift) << _pr_pageShift;
+		/*
+		**	Now, allocate the actual segment memory (or map under some OS)
+		**	The OS specific code decides from where or how to allocate memory.
+		*/
+	    if (_PR_MD_ALLOC_SEGMENT(seg, size, vaddr) != PR_SUCCESS) {
+			PR_DELETE(seg);
+			return NULL;
+    	}
+	}
+
+    return seg;
+}
+
+/*
+** Free a memory segment.
+*/
+void _PR_DestroySegment(PRSegment *seg)
+{
+	_PR_MD_FREE_SEGMENT(seg);
+    PR_DELETE(seg);
+}
+
+#endif /* _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prshm.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prshm.c
new file mode 100644
index 0000000..ac63395
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prshm.c
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** prshm.c -- NSPR Named Shared Memory
+**
+** lth. Jul-1999.
+*/
+#include <string.h>
+#include "primpl.h"
+
+extern PRLogModuleInfo *_pr_shm_lm;
+
+
+#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+/* SysV implementation is in pr/src/md/unix/uxshm.c */
+#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+/* Posix implementation is in pr/src/md/unix/uxshm.c */
+#elif defined PR_HAVE_WIN32_NAMED_SHARED_MEMORY
+/* Win32 implementation is in pr/src/md/windows/w32shm.c */
+#else 
+/* 
+**  there is no named_shared_memory 
+*/
+extern PRSharedMemory*  _MD_OpenSharedMemory( const char *name, PRSize size, PRIntn flags, PRIntn mode )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}    
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}    
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}    
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}    
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}    
+#endif /* HAVE_SYSV_NAMED_SHARED_MEMORY */
+
+/*
+** FUNCTION: PR_OpenSharedMemory()
+**
+*/
+PR_IMPLEMENT( PRSharedMemory * )
+    PR_OpenSharedMemory(
+        const char *name,
+        PRSize      size,
+        PRIntn      flags,
+        PRIntn      mode
+)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return( _PR_MD_OPEN_SHARED_MEMORY( name, size, flags, mode ));
+} /* end PR_OpenSharedMemory() */
+
+/*
+** FUNCTION: PR_AttachSharedMemory()
+**
+*/
+PR_IMPLEMENT( void * )
+    PR_AttachSharedMemory(
+        PRSharedMemory *shm,
+        PRIntn          flags
+)
+{
+    return( _PR_MD_ATTACH_SHARED_MEMORY( shm, flags ));
+} /* end PR_AttachSharedMemory() */
+
+/*
+** FUNCTION: PR_DetachSharedMemory()
+**
+*/
+PR_IMPLEMENT( PRStatus )
+    PR_DetachSharedMemory(
+        PRSharedMemory *shm,
+        void *addr
+)
+{
+    return( _PR_MD_DETACH_SHARED_MEMORY( shm, addr ));
+} /* end PR_DetachSharedMemory() */
+
+/*
+** FUNCTION: PR_CloseSharedMemory()
+**
+*/
+PR_IMPLEMENT( PRStatus )
+    PR_CloseSharedMemory(
+        PRSharedMemory *shm
+)
+{
+    return( _PR_MD_CLOSE_SHARED_MEMORY( shm ));
+} /* end PR_CloseSharedMemory() */
+
+/*
+** FUNCTION: PR_DeleteSharedMemory()
+**
+*/
+PR_EXTERN( PRStatus )
+    PR_DeleteSharedMemory(
+        const char *name
+)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return(_PR_MD_DELETE_SHARED_MEMORY( name ));
+} /* end PR_DestroySharedMemory() */
+/* end prshm.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prshma.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prshma.c
new file mode 100644
index 0000000..fbc2257
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/memory/prshma.c
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** prshma.h -- NSPR Anonymous Shared Memory
+**
+** 
+*/
+
+#include "primpl.h"
+
+extern PRLogModuleInfo *_pr_shma_lm;
+
+#if defined(XP_UNIX)
+/* defined in pr/src/md/unix/uxshm.c */
+#elif defined(WIN32)
+/* defined in pr/src/md/windows/w32shm.c */
+#else
+extern PRFileMap * _PR_MD_OPEN_ANON_FILE_MAP( const char *dirName, PRSize size, PRFileMapProtect prot )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+extern PRStatus _PR_MD_EXPORT_FILE_MAP_AS_STRING(PRFileMap *fm, PRSize bufSize, char *buf)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+extern PRFileMap * _PR_MD_IMPORT_FILE_MAP_FROM_STRING(const char *fmstring)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+#endif
+
+/*
+** PR_OpenAnonFileMap() -- Creates an anonymous file-mapped shared memory
+**
+*/
+PR_IMPLEMENT(PRFileMap*)
+PR_OpenAnonFileMap(
+    const char *dirName,
+    PRSize      size, 
+    PRFileMapProtect prot
+)
+{
+    return(_PR_MD_OPEN_ANON_FILE_MAP( dirName, size, prot ));
+} /* end PR_OpenAnonFileMap() */
+
+/*
+** PR_ProcessAttrSetInheritableFileMap() -- Prepare FileMap for export  
+**   to my children processes via PR_CreateProcess()
+**
+**
+*/
+PR_IMPLEMENT( PRStatus) 
+PR_ProcessAttrSetInheritableFileMap( 
+    PRProcessAttr   *attr,
+    PRFileMap       *fm, 
+    const char      *shmname
+)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return( PR_FAILURE);
+} /* end PR_ProcessAttrSetInheritableFileMap() */ 
+
+/*
+** PR_GetInheritedFileMap() -- Import a PRFileMap previously exported
+**   by my parent process via PR_CreateProcess()
+**
+*/
+PR_IMPLEMENT( PRFileMap *)
+PR_GetInheritedFileMap( 
+    const char *shmname 
+)
+{
+    PRFileMap   *fm = NULL;
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return( fm );
+} /* end PR_GetInhteritedFileMap() */
+
+/*
+** PR_ExportFileMapAsString() -- Creates a string identifying a PRFileMap
+**
+*/
+PR_IMPLEMENT( PRStatus )
+PR_ExportFileMapAsString( 
+    PRFileMap *fm,
+    PRSize    bufSize,
+    char      *buf
+)
+{
+    return( _PR_MD_EXPORT_FILE_MAP_AS_STRING( fm, bufSize, buf ));
+} /* end PR_ExportFileMapAsString() */
+
+/*
+** PR_ImportFileMapFromString() -- Creates a PRFileMap from the identifying string
+**
+**
+*/
+PR_IMPLEMENT( PRFileMap * )
+PR_ImportFileMapFromString( 
+    const char *fmstring
+)
+{
+    return( _PR_MD_IMPORT_FILE_MAP_FROM_STRING(fmstring));
+} /* end PR_ImportFileMapFromString() */
+/* end prshma.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/Makefile.in
new file mode 100644
index 0000000..8e7c981
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/Makefile.in
@@ -0,0 +1,112 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+CSRCS = \
+	pralarm.c  \
+	pratom.c   \
+	prcountr.c \
+	prdtoa.c   \
+	prenv.c    \
+	prerr.c  \
+	prerror.c  \
+	prerrortable.c  \
+	prinit.c   \
+	prinrval.c \
+	pripc.c \
+	prlog2.c   \
+	prlong.c   \
+	prnetdb.c  \
+	praton.c  \
+	prolock.c  \
+	prrng.c    \
+	prsystem.c \
+	prtime.c   \
+	prthinfo.c \
+	prtpool.c \
+	prtrace.c  \
+	$(NULL)
+
+ifndef USE_PTHREADS
+CSRCS += \
+	pripcsem.c \
+	$(NULL)
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+RELEASE_BINS = $(srcdir)/compile-et.pl $(srcdir)/prerr.properties
+
+include $(topsrcdir)/config/rules.mk
+
+# Prevent floating point errors caused by MSVC 6.0 Processor Pack
+# optimizations (bug 207421).  This disables optimizations that
+# could change the precision of floating-point calculations for
+# this single compilation unit.
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+$(OBJDIR)/prdtoa.$(OBJ_SUFFIX): prdtoa.c
+	@$(MAKE_OBJDIR)
+ifeq (,$(filter-out 1100 1200 1300 1310,$(MSC_VER)))
+	$(CC) -Fo$@ -c $(CFLAGS) -Op $(call pr_abspath,$<)
+else
+	$(CC) -Fo$@ -c $(CFLAGS) -fp:precise $(call pr_abspath,$<)
+endif
+endif
+
+#
+# Generate prerr.h, prerr.c, and prerr.properties from prerr.et.
+#
+build_prerr:
+	cd $(srcdir); $(PERL) compile-et.pl prerr.et
+
+export:: $(TARGETS)
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/compile-et.pl b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/compile-et.pl
new file mode 100644
index 0000000..9f0d90b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/compile-et.pl
@@ -0,0 +1,140 @@
+#!/usr/bin/perl
+
+# usage: compile-et input.et
+
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+sub header
+{
+    local($filename, $comment) = @_;
+
+<<EOF
+$comment
+$comment $filename
+$comment This file is automatically generated; please do not edit it.
+EOF
+}
+
+sub table_base
+{
+    local($name) = @_;
+    local($base) = 0;
+
+    for ($i = 0; $i < length($name); $i++) {
+	$base *= 64;
+	$base += index("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_", substr($name, $i, 1)) + 1;
+    }
+    $base -= 0x1000000 if ($base > 0x7fffff);
+    $base*256;
+}
+
+sub code {
+    local($macro, $text) = @_;
+    $code = $table_base + $table_item_count;
+
+    print H "\n";
+    print H "/* ", $text, " */\n";
+    printf H "#define %-40s (%dL)\n", $macro, $code;
+
+    print C "\t{\"", $macro, "\",    \"", $text, "\"},\n";
+
+    print PROPERTIES $macro, "=", $text, "\n";
+
+    $table_item_count++;
+}
+
+
+$filename = $ARGV[0];
+open(INPUT, "< $filename") || die "Can't read $filename: $!\n";
+
+$base = "$filename";
+$base =~ s/\.et$//;
+$base =~ s#.*/##;
+
+open(H, "> ${base}.h") || die "Can't write ${base}.h\n";
+open(C, "> ${base}.c") || die "Can't write ${base}.c\n";
+open(PROPERTIES, "> ${base}.properties") || die "Can't write ${base}.properties\n";
+
+print H "/*\n", &header("${base}.h", " *"), " */\n";
+print C "/*\n", &header("${base}.c", " *"), " */\n";
+print PROPERTIES &header("${base}.properties", "#");
+
+$skipone = 0;
+
+while ($_ = <INPUT>) {
+    next if /^#/;
+
+    if (/^[ \t]*(error_table|et)[ \t]+([a-zA-Z][a-zA-Z0-9_]+) *(-?[0-9]*)/) {
+	$table_name = $2;
+	if ($3) {
+	    $table_base = $3;
+	}
+	else {
+	    $table_base = &table_base($table_name);
+	}
+	$table_item_count = 0;
+
+	print C "#include \"prerror.h\"\n";
+	print C "static const struct PRErrorMessage text[] = {\n";
+    }
+    elsif (/^[ \t]*(error_code|ec)[ \t]+([A-Z_0-9]+),[ \t]*$/) {
+	$skipone = 1;
+	$macro = $2;
+    }
+    elsif (/^[ \t]*(error_code|ec)[ \t]+([A-Z_0-9]+),[ \t]*"(.*)"[ \t]*$/) {
+	&code($2, $3);
+    }
+    elsif ($skipone && /^[ \t]*"(.*)"[ \t]*$/) {
+	&code($macro, $1);
+    }
+}
+
+print H "\n";
+print H "extern void ", $table_name, "_InitializePRErrorTable","(void);\n";
+printf H "#define ERROR_TABLE_BASE_%s (%dL)\n", $table_name, $table_base;
+
+print C "\t{0, 0}\n";
+print C "};\n\n";
+printf C "static const struct PRErrorTable et = { text, \"%s\", %dL, %d };\n",
+    $base, $table_base, $table_item_count;
+print C "\n";
+print C "void ", $table_name, "_InitializePRErrorTable", "(void) {\n";
+print C "    PR_ErrorInstallTable(&et);\n";
+print C "}\n";
+
+0;
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/dtoa.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/dtoa.c
new file mode 100644
index 0000000..009a3d0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/dtoa.c
@@ -0,0 +1,4315 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to ".").	*/
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa.  If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ *	_control87(PC_53, MCW_PC);
+ * does this with many compilers.  Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE).  With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule.  Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ *	1. We only require IEEE, IBM, or VAX double-precision
+ *		arithmetic (not IEEE double-extended).
+ *	2. We get by with floating-point arithmetic in a case that
+ *		Clinger missed -- when we're computing d * 10^n
+ *		for a small integer d and the integer n is not too
+ *		much larger than 22 (the maximum integer k for which
+ *		we can represent 10^k exactly), we may be able to
+ *		compute (d*10^k) * 10^(e-k) with just one roundoff.
+ *	3. Rather than a bit-at-a-time adjustment of the binary
+ *		result in the hard case, we use floating-point
+ *		arithmetic to determine the adjustment to within
+ *		one bit; only in really hard cases do we need to
+ *		compute a second residual.
+ *	4. Because of 3., we don't need a large table of powers of 10
+ *		for ten-to-e (just some small tables, e.g. of 10^k
+ *		for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ *	significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ *	significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic (D_floating).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ *	computation of dtoa.
+ * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ *	and strtod and dtoa should round accordingly.  Unless Trust_FLT_ROUNDS
+ *	is also #defined, fegetround() will be queried for the rounding mode.
+ *	Note that both FLT_ROUNDS and fegetround() are specified by the C99
+ *	standard (and are specified to be consistent, with fesetround()
+ *	affecting the value of FLT_ROUNDS), but that some (Linux) systems
+ *	do not work correctly in this regard, so using fegetround() is more
+ *	portable than using FLT_FOUNDS directly.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ *	and Honor_FLT_ROUNDS is not #defined.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ *	that use extended-precision instructions to compute rounded
+ *	products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ *	products but inaccurate quotients, e.g., for Intel i860.
+ * #define NO_LONG_LONG on machines that do not have a "long long"
+ *	integer type (of >= 64 bits).  On such machines, you can
+ *	#define Just_16 to store 16 bits per 32-bit Long when doing
+ *	high-precision integer arithmetic.  Whether this speeds things
+ *	up or slows things down depends on the machine and the number
+ *	being converted.  If long long is available and the name is
+ *	something other than "long long", #define Llong to be the name,
+ *	and if "unsigned Llong" does not work as an unsigned version of
+ *	Llong, #define #ULLong to be the corresponding unsigned type.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ *	define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ *	FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ *	if memory is available and otherwise does something you deem
+ *	appropriate.  If MALLOC is undefined, malloc will be invoked
+ *	directly -- and assumed always to succeed.  Similarly, if you
+ *	want something other than the system's free() to be called to
+ *	recycle memory acquired from MALLOC, #define FREE to be the
+ *	name of the alternate routine.  (FREE or free is only called in
+ *	pathological cases, e.g., in a dtoa call after a dtoa return in
+ *	mode 3 with thousands of digits requested.)
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
+ *	memory allocations from a private pool of memory when possible.
+ *	When used, the private pool is PRIVATE_MEM bytes long:  2304 bytes,
+ *	unless #defined to be a different length.  This default length
+ *	suffices to get rid of MALLOC calls except for unusual cases,
+ *	such as decimal-to-binary conversion of a very long string of
+ *	digits.  The longest string dtoa can return is about 751 bytes
+ *	long.  For conversions by strtod of strings of 800 digits and
+ *	all dtoa conversions in single-threaded executions with 8-byte
+ *	pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte
+ *	pointers, PRIVATE_MEM >= 7112 appears adequate.
+ * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK
+ *	#defined automatically on IEEE systems.  On such systems,
+ *	when INFNAN_CHECK is #defined, strtod checks
+ *	for Infinity and NaN (case insensitively).  On some systems
+ *	(e.g., some HP systems), it may be necessary to #define NAN_WORD0
+ *	appropriately -- to the most significant word of a quiet NaN.
+ *	(On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ *	When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
+ *	strtod also accepts (case insensitively) strings of the form
+ *	NaN(x), where x is a string of hexadecimal digits and spaces;
+ *	if there is only one string of hexadecimal digits, it is taken
+ *	for the 52 fraction bits of the resulting NaN; if there are two
+ *	or more strings of hex digits, the first is for the high 20 bits,
+ *	the second and subsequent for the low 32 bits, with intervening
+ *	white space ignored; but if this results in none of the 52
+ *	fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0
+ *	and NAN_WORD1 are used instead.
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
+ *	multiple threads.  In this case, you must provide (or suitably
+ *	#define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed
+ *	by FREE_DTOA_LOCK(n) for n = 0 or 1.  (The second lock, accessed
+ *	in pow5mult, ensures lazy evaluation of only one copy of high
+ *	powers of 5; omitting this lock would introduce a small
+ *	probability of wasting memory, but would otherwise be harmless.)
+ *	You must also invoke freedtoa(s) to free the value s returned by
+ *	dtoa.  You may do so whether or not MULTIPLE_THREADS is #defined.
+ * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
+ *	avoids underflows on inputs whose result does not underflow.
+ *	If you #define NO_IEEE_Scale on a machine that uses IEEE-format
+ *	floating-point numbers and flushes underflows to zero rather
+ *	than implementing gradual underflow, then you must also #define
+ *	Sudden_Underflow.
+ * #define USE_LOCALE to use the current locale's decimal_point value.
+ * #define SET_INEXACT if IEEE arithmetic is being used and extra
+ *	computation should be done to set the inexact flag when the
+ *	result is inexact and avoid setting inexact when the result
+ *	is exact.  In this case, dtoa.c must be compiled in
+ *	an environment, perhaps provided by #include "dtoa.c" in a
+ *	suitable wrapper, that defines two functions,
+ *		int get_inexact(void);
+ *		void clear_inexact(void);
+ *	such that get_inexact() returns a nonzero value if the
+ *	inexact bit is already set, and clear_inexact() sets the
+ *	inexact bit to 0.  When SET_INEXACT is #defined, strtod
+ *	also does extra computations to set the underflow and overflow
+ *	flags when appropriate (i.e., when the result is tiny and
+ *	inexact or when it is a numeric value rounded to +-infinity).
+ * #define NO_ERRNO if strtod should not assign errno = ERANGE when
+ *	the result overflows to +-Infinity or underflows to 0.
+ * #define NO_HEX_FP to omit recognition of hexadecimal floating-point
+ *	values by strtod.
+ * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now)
+ *	to disable logic for "fast" testing of very long input strings
+ *	to strtod.  This testing proceeds by initially truncating the
+ *	input string, then if necessary comparing the whole string with
+ *	a decimal expansion to decide close cases. This logic is only
+ *	used for input more than STRTOD_DIGLIM digits long (default 40).
+ */
+
+#ifndef Long
+#define Long long
+#endif
+#ifndef ULong
+typedef unsigned Long ULong;
+#endif
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#include "stdlib.h"
+#include "string.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+#ifdef Honor_FLT_ROUNDS
+#ifndef Trust_FLT_ROUNDS
+#include <fenv.h>
+#endif
+#endif
+
+#ifdef MALLOC
+#ifdef KR_headers
+extern char *MALLOC();
+#else
+extern void *MALLOC(size_t);
+#endif
+#else
+#define MALLOC malloc
+#endif
+
+#ifndef Omit_Private_Memory
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2304
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#endif
+
+#undef IEEE_Arith
+#undef Avoid_Underflow
+#ifdef IEEE_MC68k
+#define IEEE_Arith
+#endif
+#ifdef IEEE_8087
+#define IEEE_Arith
+#endif
+
+#ifdef IEEE_Arith
+#ifndef NO_INFNAN_CHECK
+#undef INFNAN_CHECK
+#define INFNAN_CHECK
+#endif
+#else
+#undef INFNAN_CHECK
+#define NO_STRTOD_BIGCOMP
+#endif
+
+#include "errno.h"
+
+#ifdef Bad_float_h
+
+#ifdef IEEE_Arith
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#endif /*IEEE_Arith*/
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define DBL_MAX 1.7014118346046923e+38
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+
+#else /* ifndef Bad_float_h */
+#include "float.h"
+#endif /* Bad_float_h */
+
+#ifndef __MATH_H__
+#include "math.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CONST
+#ifdef KR_headers
+#define CONST /* blank */
+#else
+#define CONST const
+#endif
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
+#endif
+
+typedef union { double d; ULong L[2]; } U;
+
+#ifdef IEEE_8087
+#define word0(x) (x)->L[1]
+#define word1(x) (x)->L[0]
+#else
+#define word0(x) (x)->L[0]
+#define word1(x) (x)->L[1]
+#endif
+#define dval(x) (x)->d
+
+#ifndef STRTOD_DIGLIM
+#define STRTOD_DIGLIM 40
+#endif
+
+#ifdef DIGLIM_DEBUG
+extern int strtod_diglim;
+#else
+#define strtod_diglim STRTOD_DIGLIM
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#ifdef IEEE_Arith
+#define Exp_shift  20
+#define Exp_shift1 20
+#define Exp_msk1    0x100000
+#define Exp_msk11   0x100000
+#define Exp_mask  0x7ff00000
+#define P 53
+#define Nbits 53
+#define Bias 1023
+#define Emax 1023
+#define Emin (-1022)
+#define Exp_1  0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask  0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask  0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#ifndef NO_IEEE_Scale
+#define Avoid_Underflow
+#ifdef Flush_Denorm	/* debugging option */
+#undef Sudden_Underflow
+#endif
+#endif
+
+#ifndef Flt_Rounds
+#ifdef FLT_ROUNDS
+#define Flt_Rounds FLT_ROUNDS
+#else
+#define Flt_Rounds 1
+#endif
+#endif /*Flt_Rounds*/
+
+#ifdef Honor_FLT_ROUNDS
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+#else /* ifndef IEEE_Arith */
+#undef Check_FLT_ROUNDS
+#undef Honor_FLT_ROUNDS
+#undef SET_INEXACT
+#undef  Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#undef Flt_Rounds
+#define Flt_Rounds 0
+#define Exp_shift  24
+#define Exp_shift1 24
+#define Exp_msk1   0x1000000
+#define Exp_msk11  0x1000000
+#define Exp_mask  0x7f000000
+#define P 14
+#define Nbits 56
+#define Bias 65
+#define Emax 248
+#define Emin (-260)
+#define Exp_1  0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8	/* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask  0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask  0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#undef Flt_Rounds
+#define Flt_Rounds 1
+#define Exp_shift  23
+#define Exp_shift1 7
+#define Exp_msk1    0x80
+#define Exp_msk11   0x800000
+#define Exp_mask  0x7f80
+#define P 56
+#define Nbits 56
+#define Bias 129
+#define Emax 126
+#define Emin (-129)
+#define Exp_1  0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask  0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask  0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif /* IBM, VAX */
+#endif /* IEEE_Arith */
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Pack_32
+#define Pack_32
+#endif
+
+typedef struct BCinfo BCinfo;
+ struct
+BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; };
+
+#ifdef KR_headers
+#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff)
+#else
+#define FFFFFFFF 0xffffffffUL
+#endif
+
+#ifdef NO_LONG_LONG
+#undef ULLong
+#ifdef Just_16
+#undef Pack_32
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower.  Hence the default is now to store 32 bits per Long.
+ */
+#endif
+#else	/* long long available */
+#ifndef Llong
+#define Llong long long
+#endif
+#ifndef ULLong
+#define ULLong unsigned Llong
+#endif
+#endif /* NO_LONG_LONG */
+
+#ifndef MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n)	/*nothing*/
+#define FREE_DTOA_LOCK(n)	/*nothing*/
+#endif
+
+#define Kmax 7
+
+#ifdef __cplusplus
+extern "C" double strtod(const char *s00, char **se);
+extern "C" char *dtoa(double d, int mode, int ndigits,
+			int *decpt, int *sign, char **rve);
+#endif
+
+ struct
+Bigint {
+	struct Bigint *next;
+	int k, maxwds, sign, wds;
+	ULong x[1];
+	};
+
+ typedef struct Bigint Bigint;
+
+ static Bigint *freelist[Kmax+1];
+
+ static Bigint *
+Balloc
+#ifdef KR_headers
+	(k) int k;
+#else
+	(int k)
+#endif
+{
+	int x;
+	Bigint *rv;
+#ifndef Omit_Private_Memory
+	unsigned int len;
+#endif
+
+	ACQUIRE_DTOA_LOCK(0);
+	/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
+	/* but this case seems very unlikely. */
+	if (k <= Kmax && (rv = freelist[k]))
+		freelist[k] = rv->next;
+	else {
+		x = 1 << k;
+#ifdef Omit_Private_Memory
+		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
+#else
+		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+			/sizeof(double);
+		if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
+			rv = (Bigint*)pmem_next;
+			pmem_next += len;
+			}
+		else
+			rv = (Bigint*)MALLOC(len*sizeof(double));
+#endif
+		rv->k = k;
+		rv->maxwds = x;
+		}
+	FREE_DTOA_LOCK(0);
+	rv->sign = rv->wds = 0;
+	return rv;
+	}
+
+ static void
+Bfree
+#ifdef KR_headers
+	(v) Bigint *v;
+#else
+	(Bigint *v)
+#endif
+{
+	if (v) {
+		if (v->k > Kmax)
+#ifdef FREE
+			FREE((void*)v);
+#else
+			free((void*)v);
+#endif
+		else {
+			ACQUIRE_DTOA_LOCK(0);
+			v->next = freelist[v->k];
+			freelist[v->k] = v;
+			FREE_DTOA_LOCK(0);
+			}
+		}
+	}
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+y->wds*sizeof(Long) + 2*sizeof(int))
+
+ static Bigint *
+multadd
+#ifdef KR_headers
+	(b, m, a) Bigint *b; int m, a;
+#else
+	(Bigint *b, int m, int a)	/* multiply by m and add a */
+#endif
+{
+	int i, wds;
+#ifdef ULLong
+	ULong *x;
+	ULLong carry, y;
+#else
+	ULong carry, *x, y;
+#ifdef Pack_32
+	ULong xi, z;
+#endif
+#endif
+	Bigint *b1;
+
+	wds = b->wds;
+	x = b->x;
+	i = 0;
+	carry = a;
+	do {
+#ifdef ULLong
+		y = *x * (ULLong)m + carry;
+		carry = y >> 32;
+		*x++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+		xi = *x;
+		y = (xi & 0xffff) * m + carry;
+		z = (xi >> 16) * m + (y >> 16);
+		carry = z >> 16;
+		*x++ = (z << 16) + (y & 0xffff);
+#else
+		y = *x * m + carry;
+		carry = y >> 16;
+		*x++ = y & 0xffff;
+#endif
+#endif
+		}
+		while(++i < wds);
+	if (carry) {
+		if (wds >= b->maxwds) {
+			b1 = Balloc(b->k+1);
+			Bcopy(b1, b);
+			Bfree(b);
+			b = b1;
+			}
+		b->x[wds++] = carry;
+		b->wds = wds;
+		}
+	return b;
+	}
+
+ static Bigint *
+s2b
+#ifdef KR_headers
+	(s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9;
+#else
+	(CONST char *s, int nd0, int nd, ULong y9, int dplen)
+#endif
+{
+	Bigint *b;
+	int i, k;
+	Long x, y;
+
+	x = (nd + 8) / 9;
+	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+	b = Balloc(k);
+	b->x[0] = y9;
+	b->wds = 1;
+#else
+	b = Balloc(k+1);
+	b->x[0] = y9 & 0xffff;
+	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+	i = 9;
+	if (9 < nd0) {
+		s += 9;
+		do b = multadd(b, 10, *s++ - '0');
+			while(++i < nd0);
+		s += dplen;
+		}
+	else
+		s += dplen + 9;
+	for(; i < nd; i++)
+		b = multadd(b, 10, *s++ - '0');
+	return b;
+	}
+
+ static int
+hi0bits
+#ifdef KR_headers
+	(x) ULong x;
+#else
+	(ULong x)
+#endif
+{
+	int k = 0;
+
+	if (!(x & 0xffff0000)) {
+		k = 16;
+		x <<= 16;
+		}
+	if (!(x & 0xff000000)) {
+		k += 8;
+		x <<= 8;
+		}
+	if (!(x & 0xf0000000)) {
+		k += 4;
+		x <<= 4;
+		}
+	if (!(x & 0xc0000000)) {
+		k += 2;
+		x <<= 2;
+		}
+	if (!(x & 0x80000000)) {
+		k++;
+		if (!(x & 0x40000000))
+			return 32;
+		}
+	return k;
+	}
+
+ static int
+lo0bits
+#ifdef KR_headers
+	(y) ULong *y;
+#else
+	(ULong *y)
+#endif
+{
+	int k;
+	ULong x = *y;
+
+	if (x & 7) {
+		if (x & 1)
+			return 0;
+		if (x & 2) {
+			*y = x >> 1;
+			return 1;
+			}
+		*y = x >> 2;
+		return 2;
+		}
+	k = 0;
+	if (!(x & 0xffff)) {
+		k = 16;
+		x >>= 16;
+		}
+	if (!(x & 0xff)) {
+		k += 8;
+		x >>= 8;
+		}
+	if (!(x & 0xf)) {
+		k += 4;
+		x >>= 4;
+		}
+	if (!(x & 0x3)) {
+		k += 2;
+		x >>= 2;
+		}
+	if (!(x & 1)) {
+		k++;
+		x >>= 1;
+		if (!x)
+			return 32;
+		}
+	*y = x;
+	return k;
+	}
+
+ static Bigint *
+i2b
+#ifdef KR_headers
+	(i) int i;
+#else
+	(int i)
+#endif
+{
+	Bigint *b;
+
+	b = Balloc(1);
+	b->x[0] = i;
+	b->wds = 1;
+	return b;
+	}
+
+ static Bigint *
+mult
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	Bigint *c;
+	int k, wa, wb, wc;
+	ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+	ULong y;
+#ifdef ULLong
+	ULLong carry, z;
+#else
+	ULong carry, z;
+#ifdef Pack_32
+	ULong z2;
+#endif
+#endif
+
+	if (a->wds < b->wds) {
+		c = a;
+		a = b;
+		b = c;
+		}
+	k = a->k;
+	wa = a->wds;
+	wb = b->wds;
+	wc = wa + wb;
+	if (wc > a->maxwds)
+		k++;
+	c = Balloc(k);
+	for(x = c->x, xa = x + wc; x < xa; x++)
+		*x = 0;
+	xa = a->x;
+	xae = xa + wa;
+	xb = b->x;
+	xbe = xb + wb;
+	xc0 = c->x;
+#ifdef ULLong
+	for(; xb < xbe; xc0++) {
+		if ((y = *xb++)) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = *x++ * (ULLong)y + *xc + carry;
+				carry = z >> 32;
+				*xc++ = z & FFFFFFFF;
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		}
+#else
+#ifdef Pack_32
+	for(; xb < xbe; xb++, xc0++) {
+		if (y = *xb & 0xffff) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+				carry = z >> 16;
+				z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+				carry = z2 >> 16;
+				Storeinc(xc, z2, z);
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		if (y = *xb >> 16) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			z2 = *xc;
+			do {
+				z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+				carry = z >> 16;
+				Storeinc(xc, z, z2);
+				z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+				carry = z2 >> 16;
+				}
+				while(x < xae);
+			*xc = z2;
+			}
+		}
+#else
+	for(; xb < xbe; xc0++) {
+		if (y = *xb++) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = *x++ * y + *xc + carry;
+				carry = z >> 16;
+				*xc++ = z & 0xffff;
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		}
+#endif
+#endif
+	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+	c->wds = wc;
+	return c;
+	}
+
+ static Bigint *p5s;
+
+ static Bigint *
+pow5mult
+#ifdef KR_headers
+	(b, k) Bigint *b; int k;
+#else
+	(Bigint *b, int k)
+#endif
+{
+	Bigint *b1, *p5, *p51;
+	int i;
+	static int p05[3] = { 5, 25, 125 };
+
+	if ((i = k & 3))
+		b = multadd(b, p05[i-1], 0);
+
+	if (!(k >>= 2))
+		return b;
+	if (!(p5 = p5s)) {
+		/* first time */
+#ifdef MULTIPLE_THREADS
+		ACQUIRE_DTOA_LOCK(1);
+		if (!(p5 = p5s)) {
+			p5 = p5s = i2b(625);
+			p5->next = 0;
+			}
+		FREE_DTOA_LOCK(1);
+#else
+		p5 = p5s = i2b(625);
+		p5->next = 0;
+#endif
+		}
+	for(;;) {
+		if (k & 1) {
+			b1 = mult(b, p5);
+			Bfree(b);
+			b = b1;
+			}
+		if (!(k >>= 1))
+			break;
+		if (!(p51 = p5->next)) {
+#ifdef MULTIPLE_THREADS
+			ACQUIRE_DTOA_LOCK(1);
+			if (!(p51 = p5->next)) {
+				p51 = p5->next = mult(p5,p5);
+				p51->next = 0;
+				}
+			FREE_DTOA_LOCK(1);
+#else
+			p51 = p5->next = mult(p5,p5);
+			p51->next = 0;
+#endif
+			}
+		p5 = p51;
+		}
+	return b;
+	}
+
+ static Bigint *
+lshift
+#ifdef KR_headers
+	(b, k) Bigint *b; int k;
+#else
+	(Bigint *b, int k)
+#endif
+{
+	int i, k1, n, n1;
+	Bigint *b1;
+	ULong *x, *x1, *xe, z;
+
+#ifdef Pack_32
+	n = k >> 5;
+#else
+	n = k >> 4;
+#endif
+	k1 = b->k;
+	n1 = n + b->wds + 1;
+	for(i = b->maxwds; n1 > i; i <<= 1)
+		k1++;
+	b1 = Balloc(k1);
+	x1 = b1->x;
+	for(i = 0; i < n; i++)
+		*x1++ = 0;
+	x = b->x;
+	xe = x + b->wds;
+#ifdef Pack_32
+	if (k &= 0x1f) {
+		k1 = 32 - k;
+		z = 0;
+		do {
+			*x1++ = *x << k | z;
+			z = *x++ >> k1;
+			}
+			while(x < xe);
+		if ((*x1 = z))
+			++n1;
+		}
+#else
+	if (k &= 0xf) {
+		k1 = 16 - k;
+		z = 0;
+		do {
+			*x1++ = *x << k  & 0xffff | z;
+			z = *x++ >> k1;
+			}
+			while(x < xe);
+		if (*x1 = z)
+			++n1;
+		}
+#endif
+	else do
+		*x1++ = *x++;
+		while(x < xe);
+	b1->wds = n1 - 1;
+	Bfree(b);
+	return b1;
+	}
+
+ static int
+cmp
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	ULong *xa, *xa0, *xb, *xb0;
+	int i, j;
+
+	i = a->wds;
+	j = b->wds;
+#ifdef DEBUG
+	if (i > 1 && !a->x[i-1])
+		Bug("cmp called with a->x[a->wds-1] == 0");
+	if (j > 1 && !b->x[j-1])
+		Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+	if (i -= j)
+		return i;
+	xa0 = a->x;
+	xa = xa0 + j;
+	xb0 = b->x;
+	xb = xb0 + j;
+	for(;;) {
+		if (*--xa != *--xb)
+			return *xa < *xb ? -1 : 1;
+		if (xa <= xa0)
+			break;
+		}
+	return 0;
+	}
+
+ static Bigint *
+diff
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	Bigint *c;
+	int i, wa, wb;
+	ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef ULLong
+	ULLong borrow, y;
+#else
+	ULong borrow, y;
+#ifdef Pack_32
+	ULong z;
+#endif
+#endif
+
+	i = cmp(a,b);
+	if (!i) {
+		c = Balloc(0);
+		c->wds = 1;
+		c->x[0] = 0;
+		return c;
+		}
+	if (i < 0) {
+		c = a;
+		a = b;
+		b = c;
+		i = 1;
+		}
+	else
+		i = 0;
+	c = Balloc(a->k);
+	c->sign = i;
+	wa = a->wds;
+	xa = a->x;
+	xae = xa + wa;
+	wb = b->wds;
+	xb = b->x;
+	xbe = xb + wb;
+	xc = c->x;
+	borrow = 0;
+#ifdef ULLong
+	do {
+		y = (ULLong)*xa++ - *xb++ - borrow;
+		borrow = y >> 32 & (ULong)1;
+		*xc++ = y & FFFFFFFF;
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = *xa++ - borrow;
+		borrow = y >> 32 & (ULong)1;
+		*xc++ = y & FFFFFFFF;
+		}
+#else
+#ifdef Pack_32
+	do {
+		y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
+		borrow = (y & 0x10000) >> 16;
+		z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
+		borrow = (z & 0x10000) >> 16;
+		Storeinc(xc, z, y);
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = (*xa & 0xffff) - borrow;
+		borrow = (y & 0x10000) >> 16;
+		z = (*xa++ >> 16) - borrow;
+		borrow = (z & 0x10000) >> 16;
+		Storeinc(xc, z, y);
+		}
+#else
+	do {
+		y = *xa++ - *xb++ - borrow;
+		borrow = (y & 0x10000) >> 16;
+		*xc++ = y & 0xffff;
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = *xa++ - borrow;
+		borrow = (y & 0x10000) >> 16;
+		*xc++ = y & 0xffff;
+		}
+#endif
+#endif
+	while(!*--xc)
+		wa--;
+	c->wds = wa;
+	return c;
+	}
+
+ static double
+ulp
+#ifdef KR_headers
+	(x) U *x;
+#else
+	(U *x)
+#endif
+{
+	Long L;
+	U u;
+
+	L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+	if (L > 0) {
+#endif
+#endif
+#ifdef IBM
+		L |= Exp_msk1 >> 4;
+#endif
+		word0(&u) = L;
+		word1(&u) = 0;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+		}
+	else {
+		L = -L >> Exp_shift;
+		if (L < Exp_shift) {
+			word0(&u) = 0x80000 >> L;
+			word1(&u) = 0;
+			}
+		else {
+			word0(&u) = 0;
+			L -= Exp_shift;
+			word1(&u) = L >= 31 ? 1 : 1 << 31 - L;
+			}
+		}
+#endif
+#endif
+	return dval(&u);
+	}
+
+ static double
+b2d
+#ifdef KR_headers
+	(a, e) Bigint *a; int *e;
+#else
+	(Bigint *a, int *e)
+#endif
+{
+	ULong *xa, *xa0, w, y, z;
+	int k;
+	U d;
+#ifdef VAX
+	ULong d0, d1;
+#else
+#define d0 word0(&d)
+#define d1 word1(&d)
+#endif
+
+	xa0 = a->x;
+	xa = xa0 + a->wds;
+	y = *--xa;
+#ifdef DEBUG
+	if (!y) Bug("zero y in b2d");
+#endif
+	k = hi0bits(y);
+	*e = 32 - k;
+#ifdef Pack_32
+	if (k < Ebits) {
+		d0 = Exp_1 | y >> (Ebits - k);
+		w = xa > xa0 ? *--xa : 0;
+		d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
+		goto ret_d;
+		}
+	z = xa > xa0 ? *--xa : 0;
+	if (k -= Ebits) {
+		d0 = Exp_1 | y << k | z >> (32 - k);
+		y = xa > xa0 ? *--xa : 0;
+		d1 = z << k | y >> (32 - k);
+		}
+	else {
+		d0 = Exp_1 | y;
+		d1 = z;
+		}
+#else
+	if (k < Ebits + 16) {
+		z = xa > xa0 ? *--xa : 0;
+		d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+		w = xa > xa0 ? *--xa : 0;
+		y = xa > xa0 ? *--xa : 0;
+		d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+		goto ret_d;
+		}
+	z = xa > xa0 ? *--xa : 0;
+	w = xa > xa0 ? *--xa : 0;
+	k -= Ebits + 16;
+	d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+	y = xa > xa0 ? *--xa : 0;
+	d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+	word0(&d) = d0 >> 16 | d0 << 16;
+	word1(&d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+	return dval(&d);
+	}
+
+ static Bigint *
+d2b
+#ifdef KR_headers
+	(d, e, bits) U *d; int *e, *bits;
+#else
+	(U *d, int *e, int *bits)
+#endif
+{
+	Bigint *b;
+	int de, k;
+	ULong *x, y, z;
+#ifndef Sudden_Underflow
+	int i;
+#endif
+#ifdef VAX
+	ULong d0, d1;
+	d0 = word0(d) >> 16 | word0(d) << 16;
+	d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+	b = Balloc(1);
+#else
+	b = Balloc(2);
+#endif
+	x = b->x;
+
+	z = d0 & Frac_mask;
+	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+	de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+	z |= Exp_msk11;
+#endif
+#else
+	if ((de = (int)(d0 >> Exp_shift)))
+		z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+	if ((y = d1)) {
+		if ((k = lo0bits(&y))) {
+			x[0] = y | z << (32 - k);
+			z >>= k;
+			}
+		else
+			x[0] = y;
+#ifndef Sudden_Underflow
+		i =
+#endif
+		    b->wds = (x[1] = z) ? 2 : 1;
+		}
+	else {
+		k = lo0bits(&z);
+		x[0] = z;
+#ifndef Sudden_Underflow
+		i =
+#endif
+		    b->wds = 1;
+		k += 32;
+		}
+#else
+	if (y = d1) {
+		if (k = lo0bits(&y))
+			if (k >= 16) {
+				x[0] = y | z << 32 - k & 0xffff;
+				x[1] = z >> k - 16 & 0xffff;
+				x[2] = z >> k;
+				i = 2;
+				}
+			else {
+				x[0] = y & 0xffff;
+				x[1] = y >> 16 | z << 16 - k & 0xffff;
+				x[2] = z >> k & 0xffff;
+				x[3] = z >> k+16;
+				i = 3;
+				}
+		else {
+			x[0] = y & 0xffff;
+			x[1] = y >> 16;
+			x[2] = z & 0xffff;
+			x[3] = z >> 16;
+			i = 3;
+			}
+		}
+	else {
+#ifdef DEBUG
+		if (!z)
+			Bug("Zero passed to d2b");
+#endif
+		k = lo0bits(&z);
+		if (k >= 16) {
+			x[0] = z;
+			i = 0;
+			}
+		else {
+			x[0] = z & 0xffff;
+			x[1] = z >> 16;
+			i = 1;
+			}
+		k += 32;
+		}
+	while(!x[i])
+		--i;
+	b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+	if (de) {
+#endif
+#ifdef IBM
+		*e = (de - Bias - (P-1) << 2) + k;
+		*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+		*e = de - Bias - (P-1) + k;
+		*bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+		}
+	else {
+		*e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+		*bits = 32*i - hi0bits(x[i-1]);
+#else
+		*bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+		}
+#endif
+	return b;
+	}
+#undef d0
+#undef d1
+
+ static double
+ratio
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	U da, db;
+	int k, ka, kb;
+
+	dval(&da) = b2d(a, &ka);
+	dval(&db) = b2d(b, &kb);
+#ifdef Pack_32
+	k = ka - kb + 32*(a->wds - b->wds);
+#else
+	k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+	if (k > 0) {
+		word0(&da) += (k >> 2)*Exp_msk1;
+		if (k &= 3)
+			dval(&da) *= 1 << k;
+		}
+	else {
+		k = -k;
+		word0(&db) += (k >> 2)*Exp_msk1;
+		if (k &= 3)
+			dval(&db) *= 1 << k;
+		}
+#else
+	if (k > 0)
+		word0(&da) += k*Exp_msk1;
+	else {
+		k = -k;
+		word0(&db) += k*Exp_msk1;
+		}
+#endif
+	return dval(&da) / dval(&db);
+	}
+
+ static CONST double
+tens[] = {
+		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+		1e20, 1e21, 1e22
+#ifdef VAX
+		, 1e23, 1e24
+#endif
+		};
+
+ static CONST double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+#ifdef Avoid_Underflow
+		9007199254740992.*9007199254740992.e-256
+		/* = 2^106 * 1e-256 */
+#else
+		1e-256
+#endif
+		};
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily.  It leads to a song and dance at the end of strtod. */
+#define Scale_Bit 0x10
+#define n_bigtens 5
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+bigtens[] = { 1e16, 1e32 };
+static CONST double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+#undef Need_Hexdig
+#ifdef INFNAN_CHECK
+#ifndef No_Hex_NaN
+#define Need_Hexdig
+#endif
+#endif
+
+#ifndef Need_Hexdig
+#ifndef NO_HEX_FP
+#define Need_Hexdig
+#endif
+#endif
+
+#ifdef Need_Hexdig /*{*/
+static unsigned char hexdig[256];
+
+ static void
+#ifdef KR_headers
+htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc;
+#else
+htinit(unsigned char *h, unsigned char *s, int inc)
+#endif
+{
+	int i, j;
+	for(i = 0; (j = s[i]) !=0; i++)
+		h[j] = i + inc;
+	}
+
+ static void
+#ifdef KR_headers
+hexdig_init()
+#else
+hexdig_init(void)
+#endif
+{
+#define USC (unsigned char *)
+	htinit(hexdig, USC "0123456789", 0x10);
+	htinit(hexdig, USC "abcdef", 0x10 + 10);
+	htinit(hexdig, USC "ABCDEF", 0x10 + 10);
+	}
+#endif /* } Need_Hexdig */
+
+#ifdef INFNAN_CHECK
+
+#ifndef NAN_WORD0
+#define NAN_WORD0 0x7ff80000
+#endif
+
+#ifndef NAN_WORD1
+#define NAN_WORD1 0
+#endif
+
+ static int
+match
+#ifdef KR_headers
+	(sp, t) char **sp, *t;
+#else
+	(CONST char **sp, char *t)
+#endif
+{
+	int c, d;
+	CONST char *s = *sp;
+
+	while((d = *t++)) {
+		if ((c = *++s) >= 'A' && c <= 'Z')
+			c += 'a' - 'A';
+		if (c != d)
+			return 0;
+		}
+	*sp = s + 1;
+	return 1;
+	}
+
+#ifndef No_Hex_NaN
+ static void
+hexnan
+#ifdef KR_headers
+	(rvp, sp) U *rvp; CONST char **sp;
+#else
+	(U *rvp, CONST char **sp)
+#endif
+{
+	ULong c, x[2];
+	CONST char *s;
+	int c1, havedig, udx0, xshift;
+
+	if (!hexdig['0'])
+		hexdig_init();
+	x[0] = x[1] = 0;
+	havedig = xshift = 0;
+	udx0 = 1;
+	s = *sp;
+	/* allow optional initial 0x or 0X */
+	while((c = *(CONST unsigned char*)(s+1)) && c <= ' ')
+		++s;
+	if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X'))
+		s += 2;
+	while((c = *(CONST unsigned char*)++s)) {
+		if ((c1 = hexdig[c]))
+			c  = c1 & 0xf;
+		else if (c <= ' ') {
+			if (udx0 && havedig) {
+				udx0 = 0;
+				xshift = 1;
+				}
+			continue;
+			}
+#ifdef GDTOA_NON_PEDANTIC_NANCHECK
+		else if (/*(*/ c == ')' && havedig) {
+			*sp = s + 1;
+			break;
+			}
+		else
+			return;	/* invalid form: don't change *sp */
+#else
+		else {
+			do {
+				if (/*(*/ c == ')') {
+					*sp = s + 1;
+					break;
+					}
+				} while((c = *++s));
+			break;
+			}
+#endif
+		havedig = 1;
+		if (xshift) {
+			xshift = 0;
+			x[0] = x[1];
+			x[1] = 0;
+			}
+		if (udx0)
+			x[0] = (x[0] << 4) | (x[1] >> 28);
+		x[1] = (x[1] << 4) | c;
+		}
+	if ((x[0] &= 0xfffff) || x[1]) {
+		word0(rvp) = Exp_mask | x[0];
+		word1(rvp) = x[1];
+		}
+	}
+#endif /*No_Hex_NaN*/
+#endif /* INFNAN_CHECK */
+
+#ifdef Pack_32
+#define ULbits 32
+#define kshift 5
+#define kmask 31
+#else
+#define ULbits 16
+#define kshift 4
+#define kmask 15
+#endif
+#ifndef NO_HEX_FP /*{*/
+
+ static void
+#ifdef KR_headers
+rshift(b, k) Bigint *b; int k;
+#else
+rshift(Bigint *b, int k)
+#endif
+{
+	ULong *x, *x1, *xe, y;
+	int n;
+
+	x = x1 = b->x;
+	n = k >> kshift;
+	if (n < b->wds) {
+		xe = x + b->wds;
+		x += n;
+		if (k &= kmask) {
+			n = 32 - k;
+			y = *x++ >> k;
+			while(x < xe) {
+				*x1++ = (y | (*x << n)) & 0xffffffff;
+				y = *x++ >> k;
+				}
+			if ((*x1 = y) !=0)
+				x1++;
+			}
+		else
+			while(x < xe)
+				*x1++ = *x++;
+		}
+	if ((b->wds = x1 - b->x) == 0)
+		b->x[0] = 0;
+	}
+
+ static ULong
+#ifdef KR_headers
+any_on(b, k) Bigint *b; int k;
+#else
+any_on(Bigint *b, int k)
+#endif
+{
+	int n, nwds;
+	ULong *x, *x0, x1, x2;
+
+	x = b->x;
+	nwds = b->wds;
+	n = k >> kshift;
+	if (n > nwds)
+		n = nwds;
+	else if (n < nwds && (k &= kmask)) {
+		x1 = x2 = x[n];
+		x1 >>= k;
+		x1 <<= k;
+		if (x1 != x2)
+			return 1;
+		}
+	x0 = x;
+	x += n;
+	while(x > x0)
+		if (*--x)
+			return 1;
+	return 0;
+	}
+
+enum {	/* rounding values: same as FLT_ROUNDS */
+	Round_zero = 0,
+	Round_near = 1,
+	Round_up = 2,
+	Round_down = 3
+	};
+
+ static Bigint *
+#ifdef KR_headers
+increment(b) Bigint *b;
+#else
+increment(Bigint *b)
+#endif
+{
+	ULong *x, *xe;
+	Bigint *b1;
+
+	x = b->x;
+	xe = x + b->wds;
+	do {
+		if (*x < (ULong)0xffffffffL) {
+			++*x;
+			return b;
+			}
+		*x++ = 0;
+		} while(x < xe);
+	{
+		if (b->wds >= b->maxwds) {
+			b1 = Balloc(b->k+1);
+			Bcopy(b1,b);
+			Bfree(b);
+			b = b1;
+			}
+		b->x[b->wds++] = 1;
+		}
+	return b;
+	}
+
+ void
+#ifdef KR_headers
+gethex(sp, rvp, rounding, sign)
+	CONST char **sp; U *rvp; int rounding, sign;
+#else
+gethex( CONST char **sp, U *rvp, int rounding, int sign)
+#endif
+{
+	Bigint *b;
+	CONST unsigned char *decpt, *s0, *s, *s1;
+	Long e, e1;
+	ULong L, lostbits, *x;
+	int big, denorm, esign, havedig, k, n, nbits, up, zret;
+#ifdef IBM
+	int j;
+#endif
+	enum {
+#ifdef IEEE_Arith /*{{*/
+		emax = 0x7fe - Bias - P + 1,
+		emin = Emin - P + 1
+#else /*}{*/
+		emin = Emin - P,
+#ifdef VAX
+		emax = 0x7ff - Bias - P + 1
+#endif
+#ifdef IBM
+		emax = 0x7f - Bias - P
+#endif
+#endif /*}}*/
+		};
+#ifdef USE_LOCALE
+	int i;
+#ifdef NO_LOCALE_CACHE
+	const unsigned char *decimalpoint = (unsigned char*)
+		localeconv()->decimal_point;
+#else
+	const unsigned char *decimalpoint;
+	static unsigned char *decimalpoint_cache;
+	if (!(s0 = decimalpoint_cache)) {
+		s0 = (unsigned char*)localeconv()->decimal_point;
+		if ((decimalpoint_cache = (unsigned char*)
+				MALLOC(strlen((CONST char*)s0) + 1))) {
+			strcpy((char*)decimalpoint_cache, (CONST char*)s0);
+			s0 = decimalpoint_cache;
+			}
+		}
+	decimalpoint = s0;
+#endif
+#endif
+
+	if (!hexdig['0'])
+		hexdig_init();
+	havedig = 0;
+	s0 = *(CONST unsigned char **)sp + 2;
+	while(s0[havedig] == '0')
+		havedig++;
+	s0 += havedig;
+	s = s0;
+	decpt = 0;
+	zret = 0;
+	e = 0;
+	if (hexdig[*s])
+		havedig++;
+	else {
+		zret = 1;
+#ifdef USE_LOCALE
+		for(i = 0; decimalpoint[i]; ++i) {
+			if (s[i] != decimalpoint[i])
+				goto pcheck;
+			}
+		decpt = s += i;
+#else
+		if (*s != '.')
+			goto pcheck;
+		decpt = ++s;
+#endif
+		if (!hexdig[*s])
+			goto pcheck;
+		while(*s == '0')
+			s++;
+		if (hexdig[*s])
+			zret = 0;
+		havedig = 1;
+		s0 = s;
+		}
+	while(hexdig[*s])
+		s++;
+#ifdef USE_LOCALE
+	if (*s == *decimalpoint && !decpt) {
+		for(i = 1; decimalpoint[i]; ++i) {
+			if (s[i] != decimalpoint[i])
+				goto pcheck;
+			}
+		decpt = s += i;
+#else
+	if (*s == '.' && !decpt) {
+		decpt = ++s;
+#endif
+		while(hexdig[*s])
+			s++;
+		}/*}*/
+	if (decpt)
+		e = -(((Long)(s-decpt)) << 2);
+ pcheck:
+	s1 = s;
+	big = esign = 0;
+	switch(*s) {
+	  case 'p':
+	  case 'P':
+		switch(*++s) {
+		  case '-':
+			esign = 1;
+			/* no break */
+		  case '+':
+			s++;
+		  }
+		if ((n = hexdig[*s]) == 0 || n > 0x19) {
+			s = s1;
+			break;
+			}
+		e1 = n - 0x10;
+		while((n = hexdig[*++s]) !=0 && n <= 0x19) {
+			if (e1 & 0xf8000000)
+				big = 1;
+			e1 = 10*e1 + n - 0x10;
+			}
+		if (esign)
+			e1 = -e1;
+		e += e1;
+	  }
+	*sp = (char*)s;
+	if (!havedig)
+		*sp = (char*)s0 - 1;
+	if (zret)
+		goto retz1;
+	if (big) {
+		if (esign) {
+#ifdef IEEE_Arith
+			switch(rounding) {
+			  case Round_up:
+				if (sign)
+					break;
+				goto ret_tiny;
+			  case Round_down:
+				if (!sign)
+					break;
+				goto ret_tiny;
+			  }
+#endif
+			goto retz;
+#ifdef IEEE_Arith
+ ret_tiny:
+#ifndef NO_ERRNO
+			errno = ERANGE;
+#endif
+			word0(rvp) = 0;
+			word1(rvp) = 1;
+			return;
+#endif /* IEEE_Arith */
+			}
+		switch(rounding) {
+		  case Round_near:
+			goto ovfl1;
+		  case Round_up:
+			if (!sign)
+				goto ovfl1;
+			goto ret_big;
+		  case Round_down:
+			if (sign)
+				goto ovfl1;
+			goto ret_big;
+		  }
+ ret_big:
+		word0(rvp) = Big0;
+		word1(rvp) = Big1;
+		return;
+		}
+	n = s1 - s0 - 1;
+	for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1)
+		k++;
+	b = Balloc(k);
+	x = b->x;
+	n = 0;
+	L = 0;
+#ifdef USE_LOCALE
+	for(i = 0; decimalpoint[i+1]; ++i);
+#endif
+	while(s1 > s0) {
+#ifdef USE_LOCALE
+		if (*--s1 == decimalpoint[i]) {
+			s1 -= i;
+			continue;
+			}
+#else
+		if (*--s1 == '.')
+			continue;
+#endif
+		if (n == ULbits) {
+			*x++ = L;
+			L = 0;
+			n = 0;
+			}
+		L |= (hexdig[*s1] & 0x0f) << n;
+		n += 4;
+		}
+	*x++ = L;
+	b->wds = n = x - b->x;
+	n = ULbits*n - hi0bits(L);
+	nbits = Nbits;
+	lostbits = 0;
+	x = b->x;
+	if (n > nbits) {
+		n -= nbits;
+		if (any_on(b,n)) {
+			lostbits = 1;
+			k = n - 1;
+			if (x[k>>kshift] & 1 << (k & kmask)) {
+				lostbits = 2;
+				if (k > 0 && any_on(b,k))
+					lostbits = 3;
+				}
+			}
+		rshift(b, n);
+		e += n;
+		}
+	else if (n < nbits) {
+		n = nbits - n;
+		b = lshift(b, n);
+		e -= n;
+		x = b->x;
+		}
+	if (e > Emax) {
+ ovfl:
+		Bfree(b);
+ ovfl1:
+#ifndef NO_ERRNO
+		errno = ERANGE;
+#endif
+		word0(rvp) = Exp_mask;
+		word1(rvp) = 0;
+		return;
+		}
+	denorm = 0;
+	if (e < emin) {
+		denorm = 1;
+		n = emin - e;
+		if (n >= nbits) {
+#ifdef IEEE_Arith /*{*/
+			switch (rounding) {
+			  case Round_near:
+				if (n == nbits && (n < 2 || any_on(b,n-1)))
+					goto ret_tiny;
+				break;
+			  case Round_up:
+				if (!sign)
+					goto ret_tiny;
+				break;
+			  case Round_down:
+				if (sign)
+					goto ret_tiny;
+			  }
+#endif /* } IEEE_Arith */
+			Bfree(b);
+ retz:
+#ifndef NO_ERRNO
+			errno = ERANGE;
+#endif
+ retz1:
+			rvp->d = 0.;
+			return;
+			}
+		k = n - 1;
+		if (lostbits)
+			lostbits = 1;
+		else if (k > 0)
+			lostbits = any_on(b,k);
+		if (x[k>>kshift] & 1 << (k & kmask))
+			lostbits |= 2;
+		nbits -= n;
+		rshift(b,n);
+		e = emin;
+		}
+	if (lostbits) {
+		up = 0;
+		switch(rounding) {
+		  case Round_zero:
+			break;
+		  case Round_near:
+			if (lostbits & 2
+			 && (lostbits & 1) | (x[0] & 1))
+				up = 1;
+			break;
+		  case Round_up:
+			up = 1 - sign;
+			break;
+		  case Round_down:
+			up = sign;
+		  }
+		if (up) {
+			k = b->wds;
+			b = increment(b);
+			x = b->x;
+			if (denorm) {
+#if 0
+				if (nbits == Nbits - 1
+				 && x[nbits >> kshift] & 1 << (nbits & kmask))
+					denorm = 0; /* not currently used */
+#endif
+				}
+			else if (b->wds > k
+			 || ((n = nbits & kmask) !=0
+			     && hi0bits(x[k-1]) < 32-n)) {
+				rshift(b,1);
+				if (++e > Emax)
+					goto ovfl;
+				}
+			}
+		}
+#ifdef IEEE_Arith
+	if (denorm)
+		word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0;
+	else
+		word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20);
+	word1(rvp) = b->x[0];
+#endif
+#ifdef IBM
+	if ((j = e & 3)) {
+		k = b->x[0] & ((1 << j) - 1);
+		rshift(b,j);
+		if (k) {
+			switch(rounding) {
+			  case Round_up:
+				if (!sign)
+					increment(b);
+				break;
+			  case Round_down:
+				if (sign)
+					increment(b);
+				break;
+			  case Round_near:
+				j = 1 << (j-1);
+				if (k & j && ((k & (j-1)) | lostbits))
+					increment(b);
+			  }
+			}
+		}
+	e >>= 2;
+	word0(rvp) = b->x[1] | ((e + 65 + 13) << 24);
+	word1(rvp) = b->x[0];
+#endif
+#ifdef VAX
+	/* The next two lines ignore swap of low- and high-order 2 bytes. */
+	/* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */
+	/* word1(rvp) = b->x[0]; */
+	word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16);
+	word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16);
+#endif
+	Bfree(b);
+	}
+#endif /*!NO_HEX_FP}*/
+
+ static int
+#ifdef KR_headers
+dshift(b, p2) Bigint *b; int p2;
+#else
+dshift(Bigint *b, int p2)
+#endif
+{
+	int rv = hi0bits(b->x[b->wds-1]) - 4;
+	if (p2 > 0)
+		rv -= p2;
+	return rv & kmask;
+	}
+
+ static int
+quorem
+#ifdef KR_headers
+	(b, S) Bigint *b, *S;
+#else
+	(Bigint *b, Bigint *S)
+#endif
+{
+	int n;
+	ULong *bx, *bxe, q, *sx, *sxe;
+#ifdef ULLong
+	ULLong borrow, carry, y, ys;
+#else
+	ULong borrow, carry, y, ys;
+#ifdef Pack_32
+	ULong si, z, zs;
+#endif
+#endif
+
+	n = S->wds;
+#ifdef DEBUG
+	/*debug*/ if (b->wds > n)
+	/*debug*/	Bug("oversize b in quorem");
+#endif
+	if (b->wds < n)
+		return 0;
+	sx = S->x;
+	sxe = sx + --n;
+	bx = b->x;
+	bxe = bx + n;
+	q = *bxe / (*sxe + 1);	/* ensure q <= true quotient */
+#ifdef DEBUG
+#ifdef NO_STRTOD_BIGCOMP
+	/*debug*/ if (q > 9)
+#else
+	/* An oversized q is possible when quorem is called from bigcomp and */
+	/* the input is near, e.g., twice the smallest denormalized number. */
+	/*debug*/ if (q > 15)
+#endif
+	/*debug*/	Bug("oversized quotient in quorem");
+#endif
+	if (q) {
+		borrow = 0;
+		carry = 0;
+		do {
+#ifdef ULLong
+			ys = *sx++ * (ULLong)q + carry;
+			carry = ys >> 32;
+			y = *bx - (ys & FFFFFFFF) - borrow;
+			borrow = y >> 32 & (ULong)1;
+			*bx++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+			si = *sx++;
+			ys = (si & 0xffff) * q + carry;
+			zs = (si >> 16) * q + (ys >> 16);
+			carry = zs >> 16;
+			y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			z = (*bx >> 16) - (zs & 0xffff) - borrow;
+			borrow = (z & 0x10000) >> 16;
+			Storeinc(bx, z, y);
+#else
+			ys = *sx++ * q + carry;
+			carry = ys >> 16;
+			y = *bx - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			*bx++ = y & 0xffff;
+#endif
+#endif
+			}
+			while(sx <= sxe);
+		if (!*bxe) {
+			bx = b->x;
+			while(--bxe > bx && !*bxe)
+				--n;
+			b->wds = n;
+			}
+		}
+	if (cmp(b, S) >= 0) {
+		q++;
+		borrow = 0;
+		carry = 0;
+		bx = b->x;
+		sx = S->x;
+		do {
+#ifdef ULLong
+			ys = *sx++ + carry;
+			carry = ys >> 32;
+			y = *bx - (ys & FFFFFFFF) - borrow;
+			borrow = y >> 32 & (ULong)1;
+			*bx++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+			si = *sx++;
+			ys = (si & 0xffff) + carry;
+			zs = (si >> 16) + (ys >> 16);
+			carry = zs >> 16;
+			y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			z = (*bx >> 16) - (zs & 0xffff) - borrow;
+			borrow = (z & 0x10000) >> 16;
+			Storeinc(bx, z, y);
+#else
+			ys = *sx++ + carry;
+			carry = ys >> 16;
+			y = *bx - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			*bx++ = y & 0xffff;
+#endif
+#endif
+			}
+			while(sx <= sxe);
+		bx = b->x;
+		bxe = bx + n;
+		if (!*bxe) {
+			while(--bxe > bx && !*bxe)
+				--n;
+			b->wds = n;
+			}
+		}
+	return q;
+	}
+
+#if defined(Avoid_Underflow) || !defined(NO_STRTOD_BIGCOMP) /*{*/
+ static double
+sulp
+#ifdef KR_headers
+	(x, bc) U *x; BCinfo *bc;
+#else
+	(U *x, BCinfo *bc)
+#endif
+{
+	U u;
+	double rv;
+	int i;
+
+	rv = ulp(x);
+	if (!bc->scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0)
+		return rv; /* Is there an example where i <= 0 ? */
+	word0(&u) = Exp_1 + (i << Exp_shift);
+	word1(&u) = 0;
+	return rv * u.d;
+	}
+#endif /*}*/
+
+#ifndef NO_STRTOD_BIGCOMP
+ static void
+bigcomp
+#ifdef KR_headers
+	(rv, s0, bc)
+	U *rv; CONST char *s0; BCinfo *bc;
+#else
+	(U *rv, CONST char *s0, BCinfo *bc)
+#endif
+{
+	Bigint *b, *d;
+	int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase;
+
+	dsign = bc->dsign;
+	nd = bc->nd;
+	nd0 = bc->nd0;
+	p5 = nd + bc->e0 - 1;
+	speccase = 0;
+#ifndef Sudden_Underflow
+	if (rv->d == 0.) {	/* special case: value near underflow-to-zero */
+				/* threshold was rounded to zero */
+		b = i2b(1);
+		p2 = Emin - P + 1;
+		bbits = 1;
+#ifdef Avoid_Underflow
+		word0(rv) = (P+2) << Exp_shift;
+#else
+		word1(rv) = 1;
+#endif
+		i = 0;
+#ifdef Honor_FLT_ROUNDS
+		if (bc->rounding == 1)
+#endif
+			{
+			speccase = 1;
+			--p2;
+			dsign = 0;
+			goto have_i;
+			}
+		}
+	else
+#endif
+		b = d2b(rv, &p2, &bbits);
+#ifdef Avoid_Underflow
+	p2 -= bc->scale;
+#endif
+	/* floor(log2(rv)) == bbits - 1 + p2 */
+	/* Check for denormal case. */
+	i = P - bbits;
+	if (i > (j = P - Emin - 1 + p2)) {
+#ifdef Sudden_Underflow
+		Bfree(b);
+		b = i2b(1);
+		p2 = Emin;
+		i = P - 1;
+#ifdef Avoid_Underflow
+		word0(rv) = (1 + bc->scale) << Exp_shift;
+#else
+		word0(rv) = Exp_msk1;
+#endif
+		word1(rv) = 0;
+#else
+		i = j;
+#endif
+		}
+#ifdef Honor_FLT_ROUNDS
+	if (bc->rounding != 1) {
+		if (i > 0)
+			b = lshift(b, i);
+		if (dsign)
+			b = increment(b);
+		}
+	else
+#endif
+		{
+		b = lshift(b, ++i);
+		b->x[0] |= 1;
+		}
+#ifndef Sudden_Underflow
+ have_i:
+#endif
+	p2 -= p5 + i;
+	d = i2b(1);
+	/* Arrange for convenient computation of quotients:
+	 * shift left if necessary so divisor has 4 leading 0 bits.
+	 */
+	if (p5 > 0)
+		d = pow5mult(d, p5);
+	else if (p5 < 0)
+		b = pow5mult(b, -p5);
+	if (p2 > 0) {
+		b2 = p2;
+		d2 = 0;
+		}
+	else {
+		b2 = 0;
+		d2 = -p2;
+		}
+	i = dshift(d, d2);
+	if ((b2 += i) > 0)
+		b = lshift(b, b2);
+	if ((d2 += i) > 0)
+		d = lshift(d, d2);
+
+	/* Now b/d = exactly half-way between the two floating-point values */
+	/* on either side of the input string.  Compute first digit of b/d. */
+
+	if (!(dig = quorem(b,d))) {
+		b = multadd(b, 10, 0);	/* very unlikely */
+		dig = quorem(b,d);
+		}
+
+	/* Compare b/d with s0 */
+
+	for(i = 0; i < nd0; ) {
+		if ((dd = s0[i++] - '0' - dig))
+			goto ret;
+		if (!b->x[0] && b->wds == 1) {
+			if (i < nd)
+				dd = 1;
+			goto ret;
+			}
+		b = multadd(b, 10, 0);
+		dig = quorem(b,d);
+		}
+	for(j = bc->dp1; i++ < nd;) {
+		if ((dd = s0[j++] - '0' - dig))
+			goto ret;
+		if (!b->x[0] && b->wds == 1) {
+			if (i < nd)
+				dd = 1;
+			goto ret;
+			}
+		b = multadd(b, 10, 0);
+		dig = quorem(b,d);
+		}
+	if (b->x[0] || b->wds > 1)
+		dd = -1;
+ ret:
+	Bfree(b);
+	Bfree(d);
+#ifdef Honor_FLT_ROUNDS
+	if (bc->rounding != 1) {
+		if (dd < 0) {
+			if (bc->rounding == 0) {
+				if (!dsign)
+					goto retlow1;
+				}
+			else if (dsign)
+				goto rethi1;
+			}
+		else if (dd > 0) {
+			if (bc->rounding == 0) {
+				if (dsign)
+					goto rethi1;
+				goto ret1;
+				}
+			if (!dsign)
+				goto rethi1;
+			dval(rv) += 2.*sulp(rv,bc);
+			}
+		else {
+			bc->inexact = 0;
+			if (dsign)
+				goto rethi1;
+			}
+		}
+	else
+#endif
+	if (speccase) {
+		if (dd <= 0)
+			rv->d = 0.;
+		}
+	else if (dd < 0) {
+		if (!dsign)	/* does not happen for round-near */
+retlow1:
+			dval(rv) -= sulp(rv,bc);
+		}
+	else if (dd > 0) {
+		if (dsign) {
+ rethi1:
+			dval(rv) += sulp(rv,bc);
+			}
+		}
+	else {
+		/* Exact half-way case:  apply round-even rule. */
+		if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) {
+			i = 1 - j;
+			if (i <= 31) {
+				if (word1(rv) & (0x1 << i))
+					goto odd;
+				}
+			else if (word0(rv) & (0x1 << (i-32)))
+				goto odd;
+			}
+		else if (word1(rv) & 1) {
+ odd:
+			if (dsign)
+				goto rethi1;
+			goto retlow1;
+			}
+		}
+
+#ifdef Honor_FLT_ROUNDS
+ ret1:
+#endif
+	return;
+	}
+#endif /* NO_STRTOD_BIGCOMP */
+
+ double
+strtod
+#ifdef KR_headers
+	(s00, se) CONST char *s00; char **se;
+#else
+	(CONST char *s00, char **se)
+#endif
+{
+	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1;
+	int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign;
+	CONST char *s, *s0, *s1;
+	double aadj, aadj1;
+	Long L;
+	U aadj2, adj, rv, rv0;
+	ULong y, z;
+	BCinfo bc;
+	Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+#ifdef Avoid_Underflow
+	ULong Lsb, Lsb1;
+#endif
+#ifdef SET_INEXACT
+	int oldinexact;
+#endif
+#ifndef NO_STRTOD_BIGCOMP
+	int req_bigcomp = 0;
+#endif
+#ifdef Honor_FLT_ROUNDS /*{*/
+#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
+	bc.rounding = Flt_Rounds;
+#else /*}{*/
+	bc.rounding = 1;
+	switch(fegetround()) {
+	  case FE_TOWARDZERO:	bc.rounding = 0; break;
+	  case FE_UPWARD:	bc.rounding = 2; break;
+	  case FE_DOWNWARD:	bc.rounding = 3;
+	  }
+#endif /*}}*/
+#endif /*}*/
+#ifdef USE_LOCALE
+	CONST char *s2;
+#endif
+
+	sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0;
+	dval(&rv) = 0.;
+	for(s = s00;;s++) switch(*s) {
+		case '-':
+			sign = 1;
+			/* no break */
+		case '+':
+			if (*++s)
+				goto break2;
+			/* no break */
+		case 0:
+			goto ret0;
+		case '\t':
+		case '\n':
+		case '\v':
+		case '\f':
+		case '\r':
+		case ' ':
+			continue;
+		default:
+			goto break2;
+		}
+ break2:
+	if (*s == '0') {
+#ifndef NO_HEX_FP /*{*/
+		switch(s[1]) {
+		  case 'x':
+		  case 'X':
+#ifdef Honor_FLT_ROUNDS
+			gethex(&s, &rv, bc.rounding, sign);
+#else
+			gethex(&s, &rv, 1, sign);
+#endif
+			goto ret;
+		  }
+#endif /*}*/
+		nz0 = 1;
+		while(*++s == '0') ;
+		if (!*s)
+			goto ret;
+		}
+	s0 = s;
+	y = z = 0;
+	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+		if (nd < 9)
+			y = 10*y + c - '0';
+		else if (nd < 16)
+			z = 10*z + c - '0';
+	nd0 = nd;
+	bc.dp0 = bc.dp1 = s - s0;
+	for(s1 = s; s1 > s0 && *--s1 == '0'; )
+		++nz1;
+#ifdef USE_LOCALE
+	s1 = localeconv()->decimal_point;
+	if (c == *s1) {
+		c = '.';
+		if (*++s1) {
+			s2 = s;
+			for(;;) {
+				if (*++s2 != *s1) {
+					c = 0;
+					break;
+					}
+				if (!*++s1) {
+					s = s2;
+					break;
+					}
+				}
+			}
+		}
+#endif
+	if (c == '.') {
+		c = *++s;
+		bc.dp1 = s - s0;
+		bc.dplen = bc.dp1 - bc.dp0;
+		if (!nd) {
+			for(; c == '0'; c = *++s)
+				nz++;
+			if (c > '0' && c <= '9') {
+				s0 = s;
+				nf += nz;
+				nz = 0;
+				goto have_dig;
+				}
+			goto dig_done;
+			}
+		for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+			nz++;
+			if (c -= '0') {
+				nf += nz;
+				for(i = 1; i < nz; i++)
+					if (nd++ < 9)
+						y *= 10;
+					else if (nd <= DBL_DIG + 1)
+						z *= 10;
+				if (nd++ < 9)
+					y = 10*y + c;
+				else if (nd <= DBL_DIG + 1)
+					z = 10*z + c;
+				nz = nz1 = 0;
+				}
+			}
+		}
+ dig_done:
+	e = 0;
+	if (c == 'e' || c == 'E') {
+		if (!nd && !nz && !nz0) {
+			goto ret0;
+			}
+		s00 = s;
+		esign = 0;
+		switch(c = *++s) {
+			case '-':
+				esign = 1;
+			case '+':
+				c = *++s;
+			}
+		if (c >= '0' && c <= '9') {
+			while(c == '0')
+				c = *++s;
+			if (c > '0' && c <= '9') {
+				L = c - '0';
+				s1 = s;
+				while((c = *++s) >= '0' && c <= '9')
+					L = 10*L + c - '0';
+				if (s - s1 > 8 || L > 19999)
+					/* Avoid confusion from exponents
+					 * so large that e might overflow.
+					 */
+					e = 19999; /* safe for 16 bit ints */
+				else
+					e = (int)L;
+				if (esign)
+					e = -e;
+				}
+			else
+				e = 0;
+			}
+		else
+			s = s00;
+		}
+	if (!nd) {
+		if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+			/* Check for Nan and Infinity */
+			if (!bc.dplen)
+			 switch(c) {
+			  case 'i':
+			  case 'I':
+				if (match(&s,"nf")) {
+					--s;
+					if (!match(&s,"inity"))
+						++s;
+					word0(&rv) = 0x7ff00000;
+					word1(&rv) = 0;
+					goto ret;
+					}
+				break;
+			  case 'n':
+			  case 'N':
+				if (match(&s, "an")) {
+					word0(&rv) = NAN_WORD0;
+					word1(&rv) = NAN_WORD1;
+#ifndef No_Hex_NaN
+					if (*s == '(') /*)*/
+						hexnan(&rv, &s);
+#endif
+					goto ret;
+					}
+			  }
+#endif /* INFNAN_CHECK */
+ ret0:
+			s = s00;
+			sign = 0;
+			}
+		goto ret;
+		}
+	bc.e0 = e1 = e -= nf;
+
+	/* Now we have nd0 digits, starting at s0, followed by a
+	 * decimal point, followed by nd-nd0 digits.  The number we're
+	 * after is the integer represented by those digits times
+	 * 10**e */
+
+	if (!nd0)
+		nd0 = nd;
+	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+	dval(&rv) = y;
+	if (k > 9) {
+#ifdef SET_INEXACT
+		if (k > DBL_DIG)
+			oldinexact = get_inexact();
+#endif
+		dval(&rv) = tens[k - 9] * dval(&rv) + z;
+		}
+	bd0 = 0;
+	if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+#ifndef Honor_FLT_ROUNDS
+		&& Flt_Rounds == 1
+#endif
+#endif
+			) {
+		if (!e)
+			goto ret;
+		if (e > 0) {
+			if (e <= Ten_pmax) {
+#ifdef VAX
+				goto vax_ovfl_check;
+#else
+#ifdef Honor_FLT_ROUNDS
+				/* round correctly FLT_ROUNDS = 2 or 3 */
+				if (sign) {
+					rv.d = -rv.d;
+					sign = 0;
+					}
+#endif
+				/* rv = */ rounded_product(dval(&rv), tens[e]);
+				goto ret;
+#endif
+				}
+			i = DBL_DIG - nd;
+			if (e <= Ten_pmax + i) {
+				/* A fancier test would sometimes let us do
+				 * this for larger i values.
+				 */
+#ifdef Honor_FLT_ROUNDS
+				/* round correctly FLT_ROUNDS = 2 or 3 */
+				if (sign) {
+					rv.d = -rv.d;
+					sign = 0;
+					}
+#endif
+				e -= i;
+				dval(&rv) *= tens[i];
+#ifdef VAX
+				/* VAX exponent range is so narrow we must
+				 * worry about overflow here...
+				 */
+ vax_ovfl_check:
+				word0(&rv) -= P*Exp_msk1;
+				/* rv = */ rounded_product(dval(&rv), tens[e]);
+				if ((word0(&rv) & Exp_mask)
+				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+					goto ovfl;
+				word0(&rv) += P*Exp_msk1;
+#else
+				/* rv = */ rounded_product(dval(&rv), tens[e]);
+#endif
+				goto ret;
+				}
+			}
+#ifndef Inaccurate_Divide
+		else if (e >= -Ten_pmax) {
+#ifdef Honor_FLT_ROUNDS
+			/* round correctly FLT_ROUNDS = 2 or 3 */
+			if (sign) {
+				rv.d = -rv.d;
+				sign = 0;
+				}
+#endif
+			/* rv = */ rounded_quotient(dval(&rv), tens[-e]);
+			goto ret;
+			}
+#endif
+		}
+	e1 += nd - k;
+
+#ifdef IEEE_Arith
+#ifdef SET_INEXACT
+	bc.inexact = 1;
+	if (k <= DBL_DIG)
+		oldinexact = get_inexact();
+#endif
+#ifdef Avoid_Underflow
+	bc.scale = 0;
+#endif
+#ifdef Honor_FLT_ROUNDS
+	if (bc.rounding >= 2) {
+		if (sign)
+			bc.rounding = bc.rounding == 2 ? 0 : 2;
+		else
+			if (bc.rounding != 2)
+				bc.rounding = 0;
+		}
+#endif
+#endif /*IEEE_Arith*/
+
+	/* Get starting approximation = rv * 10**e1 */
+
+	if (e1 > 0) {
+		if ((i = e1 & 15))
+			dval(&rv) *= tens[i];
+		if (e1 &= ~15) {
+			if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+				/* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+#ifdef Honor_FLT_ROUNDS
+				switch(bc.rounding) {
+				  case 0: /* toward 0 */
+				  case 3: /* toward -infinity */
+					word0(&rv) = Big0;
+					word1(&rv) = Big1;
+					break;
+				  default:
+					word0(&rv) = Exp_mask;
+					word1(&rv) = 0;
+				  }
+#else /*Honor_FLT_ROUNDS*/
+				word0(&rv) = Exp_mask;
+				word1(&rv) = 0;
+#endif /*Honor_FLT_ROUNDS*/
+#ifdef SET_INEXACT
+				/* set overflow bit */
+				dval(&rv0) = 1e300;
+				dval(&rv0) *= dval(&rv0);
+#endif
+#else /*IEEE_Arith*/
+				word0(&rv) = Big0;
+				word1(&rv) = Big1;
+#endif /*IEEE_Arith*/
+ range_err:
+				if (bd0) {
+					Bfree(bb);
+					Bfree(bd);
+					Bfree(bs);
+					Bfree(bd0);
+					Bfree(delta);
+					}
+#ifndef NO_ERRNO
+				errno = ERANGE;
+#endif
+				goto ret;
+				}
+			e1 >>= 4;
+			for(j = 0; e1 > 1; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(&rv) *= bigtens[j];
+		/* The last multiplication could overflow. */
+			word0(&rv) -= P*Exp_msk1;
+			dval(&rv) *= bigtens[j];
+			if ((z = word0(&rv) & Exp_mask)
+			 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+				goto ovfl;
+			if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+				/* set to largest number */
+				/* (Can't trust DBL_MAX) */
+				word0(&rv) = Big0;
+				word1(&rv) = Big1;
+				}
+			else
+				word0(&rv) += P*Exp_msk1;
+			}
+		}
+	else if (e1 < 0) {
+		e1 = -e1;
+		if ((i = e1 & 15))
+			dval(&rv) /= tens[i];
+		if (e1 >>= 4) {
+			if (e1 >= 1 << n_bigtens)
+				goto undfl;
+#ifdef Avoid_Underflow
+			if (e1 & Scale_Bit)
+				bc.scale = 2*P;
+			for(j = 0; e1 > 0; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(&rv) *= tinytens[j];
+			if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
+						>> Exp_shift)) > 0) {
+				/* scaled rv is denormal; clear j low bits */
+				if (j >= 32) {
+					if (j > 54)
+						goto undfl;
+					word1(&rv) = 0;
+					if (j >= 53)
+					 word0(&rv) = (P+2)*Exp_msk1;
+					else
+					 word0(&rv) &= 0xffffffff << (j-32);
+					}
+				else
+					word1(&rv) &= 0xffffffff << j;
+				}
+#else
+			for(j = 0; e1 > 1; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(&rv) *= tinytens[j];
+			/* The last multiplication could underflow. */
+			dval(&rv0) = dval(&rv);
+			dval(&rv) *= tinytens[j];
+			if (!dval(&rv)) {
+				dval(&rv) = 2.*dval(&rv0);
+				dval(&rv) *= tinytens[j];
+#endif
+				if (!dval(&rv)) {
+ undfl:
+					dval(&rv) = 0.;
+					goto range_err;
+					}
+#ifndef Avoid_Underflow
+				word0(&rv) = Tiny0;
+				word1(&rv) = Tiny1;
+				/* The refinement below will clean
+				 * this approximation up.
+				 */
+				}
+#endif
+			}
+		}
+
+	/* Now the hard part -- adjusting rv to the correct value.*/
+
+	/* Put digits into bd: true value = bd * 10^e */
+
+	bc.nd = nd - nz1;
+#ifndef NO_STRTOD_BIGCOMP
+	bc.nd0 = nd0;	/* Only needed if nd > strtod_diglim, but done here */
+			/* to silence an erroneous warning about bc.nd0 */
+			/* possibly not being initialized. */
+	if (nd > strtod_diglim) {
+		/* ASSERT(strtod_diglim >= 18); 18 == one more than the */
+		/* minimum number of decimal digits to distinguish double values */
+		/* in IEEE arithmetic. */
+		i = j = 18;
+		if (i > nd0)
+			j += bc.dplen;
+		for(;;) {
+			if (--j < bc.dp1 && j >= bc.dp0)
+				j = bc.dp0 - 1;
+			if (s0[j] != '0')
+				break;
+			--i;
+			}
+		e += nd - i;
+		nd = i;
+		if (nd0 > nd)
+			nd0 = nd;
+		if (nd < 9) { /* must recompute y */
+			y = 0;
+			for(i = 0; i < nd0; ++i)
+				y = 10*y + s0[i] - '0';
+			for(j = bc.dp1; i < nd; ++i)
+				y = 10*y + s0[j++] - '0';
+			}
+		}
+#endif
+	bd0 = s2b(s0, nd0, nd, y, bc.dplen);
+
+	for(;;) {
+		bd = Balloc(bd0->k);
+		Bcopy(bd, bd0);
+		bb = d2b(&rv, &bbe, &bbbits);	/* rv = bb * 2^bbe */
+		bs = i2b(1);
+
+		if (e >= 0) {
+			bb2 = bb5 = 0;
+			bd2 = bd5 = e;
+			}
+		else {
+			bb2 = bb5 = -e;
+			bd2 = bd5 = 0;
+			}
+		if (bbe >= 0)
+			bb2 += bbe;
+		else
+			bd2 -= bbe;
+		bs2 = bb2;
+#ifdef Honor_FLT_ROUNDS
+		if (bc.rounding != 1)
+			bs2++;
+#endif
+#ifdef Avoid_Underflow
+		Lsb = LSB;
+		Lsb1 = 0;
+		j = bbe - bc.scale;
+		i = j + bbbits - 1;	/* logb(rv) */
+		j = P + 1 - bbbits;
+		if (i < Emin) {	/* denormal */
+			i = Emin - i;
+			j -= i;
+			if (i < 32)
+				Lsb <<= i;
+			else if (i < 52)
+				Lsb1 = Lsb << (i-32);
+			else
+				Lsb1 = Exp_mask;
+			}
+#else /*Avoid_Underflow*/
+#ifdef Sudden_Underflow
+#ifdef IBM
+		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+		j = P + 1 - bbbits;
+#endif
+#else /*Sudden_Underflow*/
+		j = bbe;
+		i = j + bbbits - 1;	/* logb(rv) */
+		if (i < Emin)	/* denormal */
+			j += P - Emin;
+		else
+			j = P + 1 - bbbits;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+		bb2 += j;
+		bd2 += j;
+#ifdef Avoid_Underflow
+		bd2 += bc.scale;
+#endif
+		i = bb2 < bd2 ? bb2 : bd2;
+		if (i > bs2)
+			i = bs2;
+		if (i > 0) {
+			bb2 -= i;
+			bd2 -= i;
+			bs2 -= i;
+			}
+		if (bb5 > 0) {
+			bs = pow5mult(bs, bb5);
+			bb1 = mult(bs, bb);
+			Bfree(bb);
+			bb = bb1;
+			}
+		if (bb2 > 0)
+			bb = lshift(bb, bb2);
+		if (bd5 > 0)
+			bd = pow5mult(bd, bd5);
+		if (bd2 > 0)
+			bd = lshift(bd, bd2);
+		if (bs2 > 0)
+			bs = lshift(bs, bs2);
+		delta = diff(bb, bd);
+		bc.dsign = delta->sign;
+		delta->sign = 0;
+		i = cmp(delta, bs);
+#ifndef NO_STRTOD_BIGCOMP /*{*/
+		if (bc.nd > nd && i <= 0) {
+			if (bc.dsign) {
+				/* Must use bigcomp(). */
+				req_bigcomp = 1;
+				break;
+				}
+#ifdef Honor_FLT_ROUNDS
+			if (bc.rounding != 1) {
+				if (i < 0) {
+					req_bigcomp = 1;
+					break;
+					}
+				}
+			else
+#endif
+				i = -1;	/* Discarded digits make delta smaller. */
+			}
+#endif /*}*/
+#ifdef Honor_FLT_ROUNDS /*{*/
+		if (bc.rounding != 1) {
+			if (i < 0) {
+				/* Error is less than an ulp */
+				if (!delta->x[0] && delta->wds <= 1) {
+					/* exact */
+#ifdef SET_INEXACT
+					bc.inexact = 0;
+#endif
+					break;
+					}
+				if (bc.rounding) {
+					if (bc.dsign) {
+						adj.d = 1.;
+						goto apply_adj;
+						}
+					}
+				else if (!bc.dsign) {
+					adj.d = -1.;
+					if (!word1(&rv)
+					 && !(word0(&rv) & Frac_mask)) {
+						y = word0(&rv) & Exp_mask;
+#ifdef Avoid_Underflow
+						if (!bc.scale || y > 2*P*Exp_msk1)
+#else
+						if (y)
+#endif
+						  {
+						  delta = lshift(delta,Log2P);
+						  if (cmp(delta, bs) <= 0)
+							adj.d = -0.5;
+						  }
+						}
+ apply_adj:
+#ifdef Avoid_Underflow /*{*/
+					if (bc.scale && (y = word0(&rv) & Exp_mask)
+						<= 2*P*Exp_msk1)
+					  word0(&adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+					if ((word0(&rv) & Exp_mask) <=
+							P*Exp_msk1) {
+						word0(&rv) += P*Exp_msk1;
+						dval(&rv) += adj.d*ulp(dval(&rv));
+						word0(&rv) -= P*Exp_msk1;
+						}
+					else
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow}*/
+					dval(&rv) += adj.d*ulp(&rv);
+					}
+				break;
+				}
+			adj.d = ratio(delta, bs);
+			if (adj.d < 1.)
+				adj.d = 1.;
+			if (adj.d <= 0x7ffffffe) {
+				/* adj = rounding ? ceil(adj) : floor(adj); */
+				y = adj.d;
+				if (y != adj.d) {
+					if (!((bc.rounding>>1) ^ bc.dsign))
+						y++;
+					adj.d = y;
+					}
+				}
+#ifdef Avoid_Underflow /*{*/
+			if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
+				word0(&adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+			if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
+				word0(&rv) += P*Exp_msk1;
+				adj.d *= ulp(dval(&rv));
+				if (bc.dsign)
+					dval(&rv) += adj.d;
+				else
+					dval(&rv) -= adj.d;
+				word0(&rv) -= P*Exp_msk1;
+				goto cont;
+				}
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow}*/
+			adj.d *= ulp(&rv);
+			if (bc.dsign) {
+				if (word0(&rv) == Big0 && word1(&rv) == Big1)
+					goto ovfl;
+				dval(&rv) += adj.d;
+				}
+			else
+				dval(&rv) -= adj.d;
+			goto cont;
+			}
+#endif /*}Honor_FLT_ROUNDS*/
+
+		if (i < 0) {
+			/* Error is less than half an ulp -- check for
+			 * special case of mantissa a power of two.
+			 */
+			if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask
+#ifdef IEEE_Arith /*{*/
+#ifdef Avoid_Underflow
+			 || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+#else
+			 || (word0(&rv) & Exp_mask) <= Exp_msk1
+#endif
+#endif /*}*/
+				) {
+#ifdef SET_INEXACT
+				if (!delta->x[0] && delta->wds <= 1)
+					bc.inexact = 0;
+#endif
+				break;
+				}
+			if (!delta->x[0] && delta->wds <= 1) {
+				/* exact result */
+#ifdef SET_INEXACT
+				bc.inexact = 0;
+#endif
+				break;
+				}
+			delta = lshift(delta,Log2P);
+			if (cmp(delta, bs) > 0)
+				goto drop_down;
+			break;
+			}
+		if (i == 0) {
+			/* exactly half-way between */
+			if (bc.dsign) {
+				if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
+				 &&  word1(&rv) == (
+#ifdef Avoid_Underflow
+			(bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
+		? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
+#endif
+						   0xffffffff)) {
+					/*boundary case -- increment exponent*/
+					if (word0(&rv) == Big0 && word1(&rv) == Big1)
+						goto ovfl;
+					word0(&rv) = (word0(&rv) & Exp_mask)
+						+ Exp_msk1
+#ifdef IBM
+						| Exp_msk1 >> 4
+#endif
+						;
+					word1(&rv) = 0;
+#ifdef Avoid_Underflow
+					bc.dsign = 0;
+#endif
+					break;
+					}
+				}
+			else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
+ drop_down:
+				/* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow /*{{*/
+				L = word0(&rv) & Exp_mask;
+#ifdef IBM
+				if (L <  Exp_msk1)
+#else
+#ifdef Avoid_Underflow
+				if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
+#else
+				if (L <= Exp_msk1)
+#endif /*Avoid_Underflow*/
+#endif /*IBM*/
+					{
+					if (bc.nd >nd) {
+						bc.uflchk = 1;
+						break;
+						}
+					goto undfl;
+					}
+				L -= Exp_msk1;
+#else /*Sudden_Underflow}{*/
+#ifdef Avoid_Underflow
+				if (bc.scale) {
+					L = word0(&rv) & Exp_mask;
+					if (L <= (2*P+1)*Exp_msk1) {
+						if (L > (P+2)*Exp_msk1)
+							/* round even ==> */
+							/* accept rv */
+							break;
+						/* rv = smallest denormal */
+						if (bc.nd >nd) {
+							bc.uflchk = 1;
+							break;
+							}
+						goto undfl;
+						}
+					}
+#endif /*Avoid_Underflow*/
+				L = (word0(&rv) & Exp_mask) - Exp_msk1;
+#endif /*Sudden_Underflow}}*/
+				word0(&rv) = L | Bndry_mask1;
+				word1(&rv) = 0xffffffff;
+#ifdef IBM
+				goto cont;
+#else
+#ifndef NO_STRTOD_BIGCOMP
+				if (bc.nd > nd)
+					goto cont;
+#endif
+				break;
+#endif
+				}
+#ifndef ROUND_BIASED
+#ifdef Avoid_Underflow
+			if (Lsb1) {
+				if (!(word0(&rv) & Lsb1))
+					break;
+				}
+			else if (!(word1(&rv) & Lsb))
+				break;
+#else
+			if (!(word1(&rv) & LSB))
+				break;
+#endif
+#endif
+			if (bc.dsign)
+#ifdef Avoid_Underflow
+				dval(&rv) += sulp(&rv, &bc);
+#else
+				dval(&rv) += ulp(&rv);
+#endif
+#ifndef ROUND_BIASED
+			else {
+#ifdef Avoid_Underflow
+				dval(&rv) -= sulp(&rv, &bc);
+#else
+				dval(&rv) -= ulp(&rv);
+#endif
+#ifndef Sudden_Underflow
+				if (!dval(&rv)) {
+					if (bc.nd >nd) {
+						bc.uflchk = 1;
+						break;
+						}
+					goto undfl;
+					}
+#endif
+				}
+#ifdef Avoid_Underflow
+			bc.dsign = 1 - bc.dsign;
+#endif
+#endif
+			break;
+			}
+		if ((aadj = ratio(delta, bs)) <= 2.) {
+			if (bc.dsign)
+				aadj = aadj1 = 1.;
+			else if (word1(&rv) || word0(&rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+				if (word1(&rv) == Tiny1 && !word0(&rv)) {
+					if (bc.nd >nd) {
+						bc.uflchk = 1;
+						break;
+						}
+					goto undfl;
+					}
+#endif
+				aadj = 1.;
+				aadj1 = -1.;
+				}
+			else {
+				/* special case -- power of FLT_RADIX to be */
+				/* rounded down... */
+
+				if (aadj < 2./FLT_RADIX)
+					aadj = 1./FLT_RADIX;
+				else
+					aadj *= 0.5;
+				aadj1 = -aadj;
+				}
+			}
+		else {
+			aadj *= 0.5;
+			aadj1 = bc.dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+			switch(bc.rounding) {
+				case 2: /* towards +infinity */
+					aadj1 -= 0.5;
+					break;
+				case 0: /* towards 0 */
+				case 3: /* towards -infinity */
+					aadj1 += 0.5;
+				}
+#else
+			if (Flt_Rounds == 0)
+				aadj1 += 0.5;
+#endif /*Check_FLT_ROUNDS*/
+			}
+		y = word0(&rv) & Exp_mask;
+
+		/* Check for overflow */
+
+		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+			dval(&rv0) = dval(&rv);
+			word0(&rv) -= P*Exp_msk1;
+			adj.d = aadj1 * ulp(&rv);
+			dval(&rv) += adj.d;
+			if ((word0(&rv) & Exp_mask) >=
+					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+				if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
+					goto ovfl;
+				word0(&rv) = Big0;
+				word1(&rv) = Big1;
+				goto cont;
+				}
+			else
+				word0(&rv) += P*Exp_msk1;
+			}
+		else {
+#ifdef Avoid_Underflow
+			if (bc.scale && y <= 2*P*Exp_msk1) {
+				if (aadj <= 0x7fffffff) {
+					if ((z = aadj) <= 0)
+						z = 1;
+					aadj = z;
+					aadj1 = bc.dsign ? aadj : -aadj;
+					}
+				dval(&aadj2) = aadj1;
+				word0(&aadj2) += (2*P+1)*Exp_msk1 - y;
+				aadj1 = dval(&aadj2);
+				adj.d = aadj1 * ulp(&rv);
+				dval(&rv) += adj.d;
+				if (rv.d == 0.)
+#ifdef NO_STRTOD_BIGCOMP
+					goto undfl;
+#else
+					{
+					if (bc.nd > nd)
+						bc.dsign = 1;
+					break;
+					}
+#endif
+				}
+			else {
+				adj.d = aadj1 * ulp(&rv);
+				dval(&rv) += adj.d;
+				}
+#else
+#ifdef Sudden_Underflow
+			if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
+				dval(&rv0) = dval(&rv);
+				word0(&rv) += P*Exp_msk1;
+				adj.d = aadj1 * ulp(&rv);
+				dval(&rv) += adj.d;
+#ifdef IBM
+				if ((word0(&rv) & Exp_mask) <  P*Exp_msk1)
+#else
+				if ((word0(&rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+					{
+					if (word0(&rv0) == Tiny0
+					 && word1(&rv0) == Tiny1) {
+						if (bc.nd >nd) {
+							bc.uflchk = 1;
+							break;
+							}
+						goto undfl;
+						}
+					word0(&rv) = Tiny0;
+					word1(&rv) = Tiny1;
+					goto cont;
+					}
+				else
+					word0(&rv) -= P*Exp_msk1;
+				}
+			else {
+				adj.d = aadj1 * ulp(&rv);
+				dval(&rv) += adj.d;
+				}
+#else /*Sudden_Underflow*/
+			/* Compute adj so that the IEEE rounding rules will
+			 * correctly round rv + adj in some half-way cases.
+			 * If rv * ulp(rv) is denormalized (i.e.,
+			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+			 * trouble from bits lost to denormalization;
+			 * example: 1.2e-307 .
+			 */
+			if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
+				aadj1 = (double)(int)(aadj + 0.5);
+				if (!bc.dsign)
+					aadj1 = -aadj1;
+				}
+			adj.d = aadj1 * ulp(&rv);
+			dval(&rv) += adj.d;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+			}
+		z = word0(&rv) & Exp_mask;
+#ifndef SET_INEXACT
+		if (bc.nd == nd) {
+#ifdef Avoid_Underflow
+		if (!bc.scale)
+#endif
+		if (y == z) {
+			/* Can we stop now? */
+			L = (Long)aadj;
+			aadj -= L;
+			/* The tolerances below are conservative. */
+			if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
+				if (aadj < .4999999 || aadj > .5000001)
+					break;
+				}
+			else if (aadj < .4999999/FLT_RADIX)
+				break;
+			}
+		}
+#endif
+ cont:
+		Bfree(bb);
+		Bfree(bd);
+		Bfree(bs);
+		Bfree(delta);
+		}
+	Bfree(bb);
+	Bfree(bd);
+	Bfree(bs);
+	Bfree(bd0);
+	Bfree(delta);
+#ifndef NO_STRTOD_BIGCOMP
+	if (req_bigcomp) {
+		bd0 = 0;
+		bc.e0 += nz1;
+		bigcomp(&rv, s0, &bc);
+		y = word0(&rv) & Exp_mask;
+		if (y == Exp_mask)
+			goto ovfl;
+		if (y == 0 && rv.d == 0.)
+			goto undfl;
+		}
+#endif
+#ifdef SET_INEXACT
+	if (bc.inexact) {
+		if (!oldinexact) {
+			word0(&rv0) = Exp_1 + (70 << Exp_shift);
+			word1(&rv0) = 0;
+			dval(&rv0) += 1.;
+			}
+		}
+	else if (!oldinexact)
+		clear_inexact();
+#endif
+#ifdef Avoid_Underflow
+	if (bc.scale) {
+		word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
+		word1(&rv0) = 0;
+		dval(&rv) *= dval(&rv0);
+#ifndef NO_ERRNO
+		/* try to avoid the bug of testing an 8087 register value */
+#ifdef IEEE_Arith
+		if (!(word0(&rv) & Exp_mask))
+#else
+		if (word0(&rv) == 0 && word1(&rv) == 0)
+#endif
+			errno = ERANGE;
+#endif
+		}
+#endif /* Avoid_Underflow */
+#ifdef SET_INEXACT
+	if (bc.inexact && !(word0(&rv) & Exp_mask)) {
+		/* set underflow bit */
+		dval(&rv0) = 1e-300;
+		dval(&rv0) *= dval(&rv0);
+		}
+#endif
+ ret:
+	if (se)
+		*se = (char *)s;
+	return sign ? -dval(&rv) : dval(&rv);
+	}
+
+#ifndef MULTIPLE_THREADS
+ static char *dtoa_result;
+#endif
+
+ static char *
+#ifdef KR_headers
+rv_alloc(i) int i;
+#else
+rv_alloc(int i)
+#endif
+{
+	int j, k, *r;
+
+	j = sizeof(ULong);
+	for(k = 0;
+		sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
+		j <<= 1)
+			k++;
+	r = (int*)Balloc(k);
+	*r = k;
+	return
+#ifndef MULTIPLE_THREADS
+	dtoa_result =
+#endif
+		(char *)(r+1);
+	}
+
+ static char *
+#ifdef KR_headers
+nrv_alloc(s, rve, n) char *s, **rve; int n;
+#else
+nrv_alloc(char *s, char **rve, int n)
+#endif
+{
+	char *rv, *t;
+
+	t = rv = rv_alloc(n);
+	while((*t = *s++)) t++;
+	if (rve)
+		*rve = t;
+	return rv;
+	}
+
+/* freedtoa(s) must be used to free values s returned by dtoa
+ * when MULTIPLE_THREADS is #defined.  It should be used in all cases,
+ * but for consistency with earlier versions of dtoa, it is optional
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+ void
+#ifdef KR_headers
+freedtoa(s) char *s;
+#else
+freedtoa(char *s)
+#endif
+{
+	Bigint *b = (Bigint *)((int *)s - 1);
+	b->maxwds = 1 << (b->k = *(int*)b);
+	Bfree(b);
+#ifndef MULTIPLE_THREADS
+	if (s == dtoa_result)
+		dtoa_result = 0;
+#endif
+	}
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ *	1. Rather than iterating, we use a simple numeric overestimate
+ *	   to determine k = floor(log10(d)).  We scale relevant
+ *	   quantities using O(log2(k)) rather than O(k) multiplications.
+ *	2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ *	   try to generate digits strictly left to right.  Instead, we
+ *	   compute with fewer bits and propagate the carry if necessary
+ *	   when rounding the final digit up.  This is often faster.
+ *	3. Under the assumption that input will be rounded nearest,
+ *	   mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ *	   That is, we allow equality in stopping tests when the
+ *	   round-nearest rule will give the same floating-point value
+ *	   as would satisfaction of the stopping test with strict
+ *	   inequality.
+ *	4. We remove common factors of powers of 2 from relevant
+ *	   quantities.
+ *	5. When converting floating-point integers less than 1e16,
+ *	   we use floating-point arithmetic rather than resorting
+ *	   to multiple-precision integers.
+ *	6. When asked to produce fewer than 15 digits, we first try
+ *	   to get by with floating-point arithmetic; we resort to
+ *	   multiple-precision integer arithmetic only if we cannot
+ *	   guarantee that the floating-point calculation has given
+ *	   the correctly rounded result.  For k requested digits and
+ *	   "uniformly" distributed input, the probability is
+ *	   something like 10^(k-15) that we must resort to the Long
+ *	   calculation.
+ */
+
+ char *
+dtoa
+#ifdef KR_headers
+	(dd, mode, ndigits, decpt, sign, rve)
+	double dd; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+	(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /*	Arguments ndigits, decpt, sign are similar to those
+	of ecvt and fcvt; trailing zeros are suppressed from
+	the returned string.  If not null, *rve is set to point
+	to the end of the return value.  If d is +-Infinity or NaN,
+	then *decpt is set to 9999.
+
+	mode:
+		0 ==> shortest string that yields d when read in
+			and rounded to nearest.
+		1 ==> like 0, but with Steele & White stopping rule;
+			e.g. with IEEE P754 arithmetic , mode 0 gives
+			1e23 whereas mode 1 gives 9.999999999999999e22.
+		2 ==> max(1,ndigits) significant digits.  This gives a
+			return value similar to that of ecvt, except
+			that trailing zeros are suppressed.
+		3 ==> through ndigits past the decimal point.  This
+			gives a return value similar to that from fcvt,
+			except that trailing zeros are suppressed, and
+			ndigits can be negative.
+		4,5 ==> similar to 2 and 3, respectively, but (in
+			round-nearest mode) with the tests of mode 0 to
+			possibly return a shorter string that rounds to d.
+			With IEEE arithmetic and compilation with
+			-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+			as modes 2 and 3 when FLT_ROUNDS != 1.
+		6-9 ==> Debugging modes similar to mode - 4:  don't try
+			fast floating-point estimate (if applicable).
+
+		Values of mode other than 0-9 are treated as mode 0.
+
+		Sufficient space is allocated to the return value
+		to hold the suppressed trailing zeros.
+	*/
+
+	int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+		j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+		spec_case, try_quick;
+	Long L;
+#ifndef Sudden_Underflow
+	int denorm;
+	ULong x;
+#endif
+	Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+	U d2, eps, u;
+	double ds;
+	char *s, *s0;
+#ifdef SET_INEXACT
+	int inexact, oldinexact;
+#endif
+#ifdef Honor_FLT_ROUNDS /*{*/
+	int Rounding;
+#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
+	Rounding = Flt_Rounds;
+#else /*}{*/
+	Rounding = 1;
+	switch(fegetround()) {
+	  case FE_TOWARDZERO:	Rounding = 0; break;
+	  case FE_UPWARD:	Rounding = 2; break;
+	  case FE_DOWNWARD:	Rounding = 3;
+	  }
+#endif /*}}*/
+#endif /*}*/
+
+#ifndef MULTIPLE_THREADS
+	if (dtoa_result) {
+		freedtoa(dtoa_result);
+		dtoa_result = 0;
+		}
+#endif
+
+	u.d = dd;
+	if (word0(&u) & Sign_bit) {
+		/* set sign for everything, including 0's and NaNs */
+		*sign = 1;
+		word0(&u) &= ~Sign_bit;	/* clear sign bit */
+		}
+	else
+		*sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+	if ((word0(&u) & Exp_mask) == Exp_mask)
+#else
+	if (word0(&u)  == 0x8000)
+#endif
+		{
+		/* Infinity or NaN */
+		*decpt = 9999;
+#ifdef IEEE_Arith
+		if (!word1(&u) && !(word0(&u) & 0xfffff))
+			return nrv_alloc("Infinity", rve, 8);
+#endif
+		return nrv_alloc("NaN", rve, 3);
+		}
+#endif
+#ifdef IBM
+	dval(&u) += 0; /* normalize */
+#endif
+	if (!dval(&u)) {
+		*decpt = 1;
+		return nrv_alloc("0", rve, 1);
+		}
+
+#ifdef SET_INEXACT
+	try_quick = oldinexact = get_inexact();
+	inexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+	if (Rounding >= 2) {
+		if (*sign)
+			Rounding = Rounding == 2 ? 0 : 2;
+		else
+			if (Rounding != 2)
+				Rounding = 0;
+		}
+#endif
+
+	b = d2b(&u, &be, &bbits);
+#ifdef Sudden_Underflow
+	i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+	if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
+#endif
+		dval(&d2) = dval(&u);
+		word0(&d2) &= Frac_mask1;
+		word0(&d2) |= Exp_11;
+#ifdef IBM
+		if (j = 11 - hi0bits(word0(&d2) & Frac_mask))
+			dval(&d2) /= 1 << j;
+#endif
+
+		/* log(x)	~=~ log(1.5) + (x-1.5)/1.5
+		 * log10(x)	 =  log(x) / log(10)
+		 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+		 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+		 *
+		 * This suggests computing an approximation k to log10(d) by
+		 *
+		 * k = (i - Bias)*0.301029995663981
+		 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+		 *
+		 * We want k to be too large rather than too small.
+		 * The error in the first-order Taylor series approximation
+		 * is in our favor, so we just round up the constant enough
+		 * to compensate for any error in the multiplication of
+		 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+		 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+		 * adding 1e-13 to the constant term more than suffices.
+		 * Hence we adjust the constant term to 0.1760912590558.
+		 * (We could get a more accurate k by invoking log10,
+		 *  but this is probably not worthwhile.)
+		 */
+
+		i -= Bias;
+#ifdef IBM
+		i <<= 2;
+		i += j;
+#endif
+#ifndef Sudden_Underflow
+		denorm = 0;
+		}
+	else {
+		/* d is denormalized */
+
+		i = bbits + be + (Bias + (P-1) - 1);
+		x = i > 32  ? word0(&u) << (64 - i) | word1(&u) >> (i - 32)
+			    : word1(&u) << (32 - i);
+		dval(&d2) = x;
+		word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
+		i -= (Bias + (P-1) - 1) + 1;
+		denorm = 1;
+		}
+#endif
+	ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+	k = (int)ds;
+	if (ds < 0. && ds != k)
+		k--;	/* want k = floor(ds) */
+	k_check = 1;
+	if (k >= 0 && k <= Ten_pmax) {
+		if (dval(&u) < tens[k])
+			k--;
+		k_check = 0;
+		}
+	j = bbits - i - 1;
+	if (j >= 0) {
+		b2 = 0;
+		s2 = j;
+		}
+	else {
+		b2 = -j;
+		s2 = 0;
+		}
+	if (k >= 0) {
+		b5 = 0;
+		s5 = k;
+		s2 += k;
+		}
+	else {
+		b2 -= k;
+		b5 = -k;
+		s5 = 0;
+		}
+	if (mode < 0 || mode > 9)
+		mode = 0;
+
+#ifndef SET_INEXACT
+#ifdef Check_FLT_ROUNDS
+	try_quick = Rounding == 1;
+#else
+	try_quick = 1;
+#endif
+#endif /*SET_INEXACT*/
+
+	if (mode > 5) {
+		mode -= 4;
+		try_quick = 0;
+		}
+	leftright = 1;
+	ilim = ilim1 = -1;	/* Values for cases 0 and 1; done here to */
+				/* silence erroneous "gcc -Wall" warning. */
+	switch(mode) {
+		case 0:
+		case 1:
+			i = 18;
+			ndigits = 0;
+			break;
+		case 2:
+			leftright = 0;
+			/* no break */
+		case 4:
+			if (ndigits <= 0)
+				ndigits = 1;
+			ilim = ilim1 = i = ndigits;
+			break;
+		case 3:
+			leftright = 0;
+			/* no break */
+		case 5:
+			i = ndigits + k + 1;
+			ilim = i;
+			ilim1 = i - 1;
+			if (i <= 0)
+				i = 1;
+		}
+	s = s0 = rv_alloc(i);
+
+#ifdef Honor_FLT_ROUNDS
+	if (mode > 1 && Rounding != 1)
+		leftright = 0;
+#endif
+
+	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+		/* Try to get by with floating-point arithmetic. */
+
+		i = 0;
+		dval(&d2) = dval(&u);
+		k0 = k;
+		ilim0 = ilim;
+		ieps = 2; /* conservative */
+		if (k > 0) {
+			ds = tens[k&0xf];
+			j = k >> 4;
+			if (j & Bletch) {
+				/* prevent overflows */
+				j &= Bletch - 1;
+				dval(&u) /= bigtens[n_bigtens-1];
+				ieps++;
+				}
+			for(; j; j >>= 1, i++)
+				if (j & 1) {
+					ieps++;
+					ds *= bigtens[i];
+					}
+			dval(&u) /= ds;
+			}
+		else if ((j1 = -k)) {
+			dval(&u) *= tens[j1 & 0xf];
+			for(j = j1 >> 4; j; j >>= 1, i++)
+				if (j & 1) {
+					ieps++;
+					dval(&u) *= bigtens[i];
+					}
+			}
+		if (k_check && dval(&u) < 1. && ilim > 0) {
+			if (ilim1 <= 0)
+				goto fast_failed;
+			ilim = ilim1;
+			k--;
+			dval(&u) *= 10.;
+			ieps++;
+			}
+		dval(&eps) = ieps*dval(&u) + 7.;
+		word0(&eps) -= (P-1)*Exp_msk1;
+		if (ilim == 0) {
+			S = mhi = 0;
+			dval(&u) -= 5.;
+			if (dval(&u) > dval(&eps))
+				goto one_digit;
+			if (dval(&u) < -dval(&eps))
+				goto no_digits;
+			goto fast_failed;
+			}
+#ifndef No_leftright
+		if (leftright) {
+			/* Use Steele & White method of only
+			 * generating digits needed.
+			 */
+			dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
+			for(i = 0;;) {
+				L = dval(&u);
+				dval(&u) -= L;
+				*s++ = '0' + (int)L;
+				if (dval(&u) < dval(&eps))
+					goto ret1;
+				if (1. - dval(&u) < dval(&eps))
+					goto bump_up;
+				if (++i >= ilim)
+					break;
+				dval(&eps) *= 10.;
+				dval(&u) *= 10.;
+				}
+			}
+		else {
+#endif
+			/* Generate ilim digits, then fix them up. */
+			dval(&eps) *= tens[ilim-1];
+			for(i = 1;; i++, dval(&u) *= 10.) {
+				L = (Long)(dval(&u));
+				if (!(dval(&u) -= L))
+					ilim = i;
+				*s++ = '0' + (int)L;
+				if (i == ilim) {
+					if (dval(&u) > 0.5 + dval(&eps))
+						goto bump_up;
+					else if (dval(&u) < 0.5 - dval(&eps)) {
+						while(*--s == '0');
+						s++;
+						goto ret1;
+						}
+					break;
+					}
+				}
+#ifndef No_leftright
+			}
+#endif
+ fast_failed:
+		s = s0;
+		dval(&u) = dval(&d2);
+		k = k0;
+		ilim = ilim0;
+		}
+
+	/* Do we have a "small" integer? */
+
+	if (be >= 0 && k <= Int_max) {
+		/* Yes. */
+		ds = tens[k];
+		if (ndigits < 0 && ilim <= 0) {
+			S = mhi = 0;
+			if (ilim < 0 || dval(&u) <= 5*ds)
+				goto no_digits;
+			goto one_digit;
+			}
+		for(i = 1;; i++, dval(&u) *= 10.) {
+			L = (Long)(dval(&u) / ds);
+			dval(&u) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+			/* If FLT_ROUNDS == 2, L will usually be high by 1 */
+			if (dval(&u) < 0) {
+				L--;
+				dval(&u) += ds;
+				}
+#endif
+			*s++ = '0' + (int)L;
+			if (!dval(&u)) {
+#ifdef SET_INEXACT
+				inexact = 0;
+#endif
+				break;
+				}
+			if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+				if (mode > 1)
+				switch(Rounding) {
+				  case 0: goto ret1;
+				  case 2: goto bump_up;
+				  }
+#endif
+				dval(&u) += dval(&u);
+				if (dval(&u) > ds || (dval(&u) == ds && L & 1)) {
+ bump_up:
+					while(*--s == '9')
+						if (s == s0) {
+							k++;
+							*s = '0';
+							break;
+							}
+					++*s++;
+					}
+				break;
+				}
+			}
+		goto ret1;
+		}
+
+	m2 = b2;
+	m5 = b5;
+	mhi = mlo = 0;
+	if (leftright) {
+		i =
+#ifndef Sudden_Underflow
+			denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+			1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+			1 + P - bbits;
+#endif
+		b2 += i;
+		s2 += i;
+		mhi = i2b(1);
+		}
+	if (m2 > 0 && s2 > 0) {
+		i = m2 < s2 ? m2 : s2;
+		b2 -= i;
+		m2 -= i;
+		s2 -= i;
+		}
+	if (b5 > 0) {
+		if (leftright) {
+			if (m5 > 0) {
+				mhi = pow5mult(mhi, m5);
+				b1 = mult(mhi, b);
+				Bfree(b);
+				b = b1;
+				}
+			if ((j = b5 - m5))
+				b = pow5mult(b, j);
+			}
+		else
+			b = pow5mult(b, b5);
+		}
+	S = i2b(1);
+	if (s5 > 0)
+		S = pow5mult(S, s5);
+
+	/* Check for special case that d is a normalized power of 2. */
+
+	spec_case = 0;
+	if ((mode < 2 || leftright)
+#ifdef Honor_FLT_ROUNDS
+			&& Rounding == 1
+#endif
+				) {
+		if (!word1(&u) && !(word0(&u) & Bndry_mask)
+#ifndef Sudden_Underflow
+		 && word0(&u) & (Exp_mask & ~Exp_msk1)
+#endif
+				) {
+			/* The special case */
+			b2 += Log2P;
+			s2 += Log2P;
+			spec_case = 1;
+			}
+		}
+
+	/* Arrange for convenient computation of quotients:
+	 * shift left if necessary so divisor has 4 leading 0 bits.
+	 *
+	 * Perhaps we should just compute leading 28 bits of S once
+	 * and for all and pass them and a shift to quorem, so it
+	 * can do shifts and ors to compute the numerator for q.
+	 */
+#ifdef Pack_32
+	if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f))
+		i = 32 - i;
+#define iInc 28
+#else
+	if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
+		i = 16 - i;
+#define iInc 12
+#endif
+	i = dshift(S, s2);
+	b2 += i;
+	m2 += i;
+	s2 += i;
+	if (b2 > 0)
+		b = lshift(b, b2);
+	if (s2 > 0)
+		S = lshift(S, s2);
+	if (k_check) {
+		if (cmp(b,S) < 0) {
+			k--;
+			b = multadd(b, 10, 0);	/* we botched the k estimate */
+			if (leftright)
+				mhi = multadd(mhi, 10, 0);
+			ilim = ilim1;
+			}
+		}
+	if (ilim <= 0 && (mode == 3 || mode == 5)) {
+		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+			/* no digits, fcvt style */
+ no_digits:
+			k = -1 - ndigits;
+			goto ret;
+			}
+ one_digit:
+		*s++ = '1';
+		k++;
+		goto ret;
+		}
+	if (leftright) {
+		if (m2 > 0)
+			mhi = lshift(mhi, m2);
+
+		/* Compute mlo -- check for special case
+		 * that d is a normalized power of 2.
+		 */
+
+		mlo = mhi;
+		if (spec_case) {
+			mhi = Balloc(mhi->k);
+			Bcopy(mhi, mlo);
+			mhi = lshift(mhi, Log2P);
+			}
+
+		for(i = 1;;i++) {
+			dig = quorem(b,S) + '0';
+			/* Do we yet have the shortest decimal string
+			 * that will round to d?
+			 */
+			j = cmp(b, mlo);
+			delta = diff(S, mhi);
+			j1 = delta->sign ? 1 : cmp(b, delta);
+			Bfree(delta);
+#ifndef ROUND_BIASED
+			if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
+#ifdef Honor_FLT_ROUNDS
+				&& Rounding >= 1
+#endif
+								   ) {
+				if (dig == '9')
+					goto round_9_up;
+				if (j > 0)
+					dig++;
+#ifdef SET_INEXACT
+				else if (!b->x[0] && b->wds <= 1)
+					inexact = 0;
+#endif
+				*s++ = dig;
+				goto ret;
+				}
+#endif
+			if (j < 0 || (j == 0 && mode != 1
+#ifndef ROUND_BIASED
+							&& !(word1(&u) & 1)
+#endif
+					)) {
+				if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+					inexact = 0;
+#endif
+					goto accept_dig;
+					}
+#ifdef Honor_FLT_ROUNDS
+				if (mode > 1)
+				 switch(Rounding) {
+				  case 0: goto accept_dig;
+				  case 2: goto keep_dig;
+				  }
+#endif /*Honor_FLT_ROUNDS*/
+				if (j1 > 0) {
+					b = lshift(b, 1);
+					j1 = cmp(b, S);
+					if ((j1 > 0 || (j1 == 0 && dig & 1))
+					&& dig++ == '9')
+						goto round_9_up;
+					}
+ accept_dig:
+				*s++ = dig;
+				goto ret;
+				}
+			if (j1 > 0) {
+#ifdef Honor_FLT_ROUNDS
+				if (!Rounding)
+					goto accept_dig;
+#endif
+				if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+					*s++ = '9';
+					goto roundoff;
+					}
+				*s++ = dig + 1;
+				goto ret;
+				}
+#ifdef Honor_FLT_ROUNDS
+ keep_dig:
+#endif
+			*s++ = dig;
+			if (i == ilim)
+				break;
+			b = multadd(b, 10, 0);
+			if (mlo == mhi)
+				mlo = mhi = multadd(mhi, 10, 0);
+			else {
+				mlo = multadd(mlo, 10, 0);
+				mhi = multadd(mhi, 10, 0);
+				}
+			}
+		}
+	else
+		for(i = 1;; i++) {
+			*s++ = dig = quorem(b,S) + '0';
+			if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+				inexact = 0;
+#endif
+				goto ret;
+				}
+			if (i >= ilim)
+				break;
+			b = multadd(b, 10, 0);
+			}
+
+	/* Round off last digit */
+
+#ifdef Honor_FLT_ROUNDS
+	switch(Rounding) {
+	  case 0: goto trimzeros;
+	  case 2: goto roundoff;
+	  }
+#endif
+	b = lshift(b, 1);
+	j = cmp(b, S);
+	if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+		while(*--s == '9')
+			if (s == s0) {
+				k++;
+				*s++ = '1';
+				goto ret;
+				}
+		++*s++;
+		}
+	else {
+#ifdef Honor_FLT_ROUNDS
+ trimzeros:
+#endif
+		while(*--s == '0');
+		s++;
+		}
+ ret:
+	Bfree(S);
+	if (mhi) {
+		if (mlo && mlo != mhi)
+			Bfree(mlo);
+		Bfree(mhi);
+		}
+ ret1:
+#ifdef SET_INEXACT
+	if (inexact) {
+		if (!oldinexact) {
+			word0(&u) = Exp_1 + (70 << Exp_shift);
+			word1(&u) = 0;
+			dval(&u) += 1.;
+			}
+		}
+	else if (!oldinexact)
+		clear_inexact();
+#endif
+	Bfree(b);
+	*s = 0;
+	*decpt = k + 1;
+	if (rve)
+		*rve = s;
+	return s0;
+	}
+#ifdef __cplusplus
+}
+#endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pralarm.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pralarm.c
new file mode 100644
index 0000000..932d077
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pralarm.c
@@ -0,0 +1,278 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+/**********************************************************************/
+/******************************* PRALARM ******************************/
+/**********************************************************************/
+
+#include "obsolete/pralarm.h"
+
+struct PRAlarmID {                       /* typedef'd in pralarm.h       */
+    PRCList list;                        /* circular list linkage        */
+    PRAlarm *alarm;                      /* back pointer to owning alarm */
+    PRPeriodicAlarmFn function;          /* function to call for notify  */
+    void *clientData;                    /* opaque client context        */
+    PRIntervalTime period;               /* the client defined period    */
+    PRUint32 rate;                       /* rate of notification         */
+
+    PRUint32 accumulator;                /* keeps track of # notifies    */
+    PRIntervalTime epoch;                /* when timer was started       */
+    PRIntervalTime nextNotify;           /* when we'll next do our thing */
+    PRIntervalTime lastNotify;           /* when we last did our thing   */
+};
+
+typedef enum {alarm_active, alarm_inactive} _AlarmState;
+
+struct PRAlarm {                         /* typedef'd in pralarm.h       */
+    PRCList timers;                      /* base of alarm ids list       */
+    PRLock *lock;                        /* lock used to protect data    */
+    PRCondVar *cond;                     /* condition that used to wait  */
+    PRThread *notifier;                  /* thread to deliver notifies   */
+    PRAlarmID *current;                  /* current alarm being served   */
+    _AlarmState state;                   /* used to delete the alarm     */
+};
+
+static PRAlarmID *pr_getNextAlarm(PRAlarm *alarm, PRAlarmID *id)
+{
+/*
+ * Puts 'id' back into the sorted list iff it's not NULL.
+ * Removes the first element from the list and returns it (or NULL).
+ * List is "assumed" to be short.
+ *
+ * NB: Caller is providing locking
+ */
+    PRCList *timer;
+    PRAlarmID *result = id;
+    PRIntervalTime now = PR_IntervalNow();
+
+    if (!PR_CLIST_IS_EMPTY(&alarm->timers))
+    {    
+        if (id != NULL)  /* have to put this id back in */
+        {        
+            PRIntervalTime idDelta = now - id->nextNotify;
+            timer = alarm->timers.next;
+            do
+            {
+                result = (PRAlarmID*)timer;
+                if ((PRIntervalTime)(now - result->nextNotify) > idDelta)
+                {
+                    PR_INSERT_BEFORE(&id->list, &alarm->timers);
+                    break;
+                }
+                timer = timer->next;
+            } while (timer != &alarm->timers);
+        }
+        result = (PRAlarmID*)(timer = PR_LIST_HEAD(&alarm->timers));
+        PR_REMOVE_LINK(timer);  /* remove it from the list */
+    }
+
+    return result;
+}  /* pr_getNextAlarm */
+
+static PRIntervalTime pr_PredictNextNotifyTime(PRAlarmID *id)
+{
+    PRIntervalTime delta;
+    PRFloat64 baseRate = (PRFloat64)id->period / (PRFloat64)id->rate;
+    PRFloat64 offsetFromEpoch = (PRFloat64)id->accumulator * baseRate;
+
+    id->accumulator += 1;  /* every call advances to next period */
+    id->lastNotify = id->nextNotify;  /* just keeping track of things */
+    id->nextNotify = (PRIntervalTime)(offsetFromEpoch + 0.5);
+
+    delta = id->nextNotify - id->lastNotify;
+    return delta;
+}  /* pr_PredictNextNotifyTime */
+
+static void PR_CALLBACK pr_alarmNotifier(void *arg)
+{
+    /*
+     * This is the root of the notifier thread. There is one such thread
+     * for each PRAlarm. It may service an arbitrary (though assumed to be
+     * small) number of alarms using the same thread and structure. It
+     * continues to run until the alarm is destroyed.
+     */
+    PRAlarmID *id = NULL;
+    PRAlarm *alarm = (PRAlarm*)arg;
+    enum {notify, abort, scan} why = scan;
+
+    while (why != abort)
+    {
+        PRIntervalTime pause;
+
+        PR_Lock(alarm->lock);
+        while (why == scan)
+        {
+            alarm->current = NULL;  /* reset current id */
+            if (alarm->state == alarm_inactive) why = abort;  /* we're toast */
+            else if (why == scan)  /* the dominant case */
+            {
+                id = pr_getNextAlarm(alarm, id);  /* even if it's the same */
+                if (id == NULL)  /* there are no alarms set */
+                    (void)PR_WaitCondVar(alarm->cond, PR_INTERVAL_NO_TIMEOUT);
+                else
+                {
+                    pause = id->nextNotify - (PR_IntervalNow() - id->epoch);
+                    if ((PRInt32)pause <= 0)  /* is this one's time up? */
+                    {
+                        why = notify;  /* set up to do our thing */
+                        alarm->current = id;  /* id we're about to schedule */
+                    }
+                    else
+                        (void)PR_WaitCondVar(alarm->cond, pause);  /* dally */
+                }
+            }
+        }
+        PR_Unlock(alarm->lock);
+
+        if (why == notify)
+        {
+            (void)pr_PredictNextNotifyTime(id);
+            if (!id->function(id, id->clientData, ~pause))
+            {
+                /*
+                 * Notified function decided not to continue. Free
+                 * the alarm id to make sure it doesn't get back on
+                 * the list.
+                 */
+                PR_DELETE(id);  /* free notifier object */
+                id = NULL;  /* so it doesn't get back into the list */
+            }
+            why = scan;  /* so we can cycle through the loop again */
+        }
+    }
+
+}  /* pr_alarm_notifier */
+
+PR_IMPLEMENT(PRAlarm*) PR_CreateAlarm(void)
+{
+    PRAlarm *alarm = PR_NEWZAP(PRAlarm);
+    if (alarm != NULL)
+    {
+        if ((alarm->lock = PR_NewLock()) == NULL) goto done;
+        if ((alarm->cond = PR_NewCondVar(alarm->lock)) == NULL) goto done;
+        alarm->state = alarm_active;
+        PR_INIT_CLIST(&alarm->timers);
+        alarm->notifier = PR_CreateThread(
+            PR_USER_THREAD, pr_alarmNotifier, alarm,
+            PR_GetThreadPriority(PR_GetCurrentThread()),
+            PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (alarm->notifier == NULL) goto done;
+    }
+    return alarm;
+
+done:
+    if (alarm->cond != NULL) PR_DestroyCondVar(alarm->cond);
+    if (alarm->lock != NULL) PR_DestroyLock(alarm->lock);
+    PR_DELETE(alarm);
+    return NULL;
+}  /* CreateAlarm */
+
+PR_IMPLEMENT(PRStatus) PR_DestroyAlarm(PRAlarm *alarm)
+{
+    PRStatus rv;
+
+    PR_Lock(alarm->lock);
+    alarm->state = alarm_inactive;
+    rv = PR_NotifyCondVar(alarm->cond);
+    PR_Unlock(alarm->lock);
+
+    if (rv == PR_SUCCESS)
+        rv = PR_JoinThread(alarm->notifier);
+    if (rv == PR_SUCCESS)
+    {
+        PR_DestroyCondVar(alarm->cond);
+        PR_DestroyLock(alarm->lock);
+        PR_DELETE(alarm);
+    }
+    return rv;
+}  /* PR_DestroyAlarm */
+
+PR_IMPLEMENT(PRAlarmID*) PR_SetAlarm(
+    PRAlarm *alarm, PRIntervalTime period, PRUint32 rate,
+    PRPeriodicAlarmFn function, void *clientData)
+{
+    /*
+     * Create a new periodic alarm an existing current structure.
+     * Set up the context and compute the first notify time (immediate).
+     * Link the new ID into the head of the list (since it's notifying
+     * immediately).
+     */
+
+    PRAlarmID *id = PR_NEWZAP(PRAlarmID);
+
+    if (!id)
+        return NULL;
+
+    id->alarm = alarm;
+    PR_INIT_CLIST(&id->list);
+    id->function = function;
+    id->clientData = clientData;
+    id->period = period;
+    id->rate = rate;
+    id->epoch = id->nextNotify = PR_IntervalNow();
+    (void)pr_PredictNextNotifyTime(id);
+
+    PR_Lock(alarm->lock);
+    PR_INSERT_BEFORE(&id->list, &alarm->timers);
+    PR_NotifyCondVar(alarm->cond);
+    PR_Unlock(alarm->lock);
+
+    return id;
+}  /* PR_SetAlarm */
+
+PR_IMPLEMENT(PRStatus) PR_ResetAlarm(
+    PRAlarmID *id, PRIntervalTime period, PRUint32 rate)
+{
+    /*
+     * Can only be called from within the notify routine. Doesn't
+     * need locking because it can only be called from within the
+     * notify routine.
+     */
+    if (id != id->alarm->current)
+        return PR_FAILURE;
+    id->period = period;
+    id->rate = rate;
+    id->accumulator = 1;
+    id->epoch = PR_IntervalNow();
+    (void)pr_PredictNextNotifyTime(id);
+    return PR_SUCCESS;
+}  /* PR_ResetAlarm */
+
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pratom.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pratom.c
new file mode 100644
index 0000000..35b86c0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pratom.c
@@ -0,0 +1,411 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+**     PR Atomic operations
+*/
+
+
+#include "pratom.h"
+#include "primpl.h"
+
+#include <string.h>
+
+/*
+ * The following is a fallback implementation that emulates
+ * atomic operations for platforms without atomic operations.
+ * If a platform has atomic operations, it should define the
+ * macro _PR_HAVE_ATOMIC_OPS, and the following will not be
+ * compiled in.
+ */
+
+#if !defined(_PR_HAVE_ATOMIC_OPS)
+
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+/*
+ * PR_AtomicDecrement() is used in NSPR's thread-specific data
+ * destructor.  Because thread-specific data destructors may be
+ * invoked after a PR_Cleanup() call, we need an implementation
+ * of the atomic routines that doesn't need NSPR to be initialized.
+ */
+
+/*
+ * We use a set of locks for all the emulated atomic operations.
+ * By hashing on the address of the integer to be locked the
+ * contention between multiple threads should be lessened.
+ *
+ * The number of atomic locks can be set by the environment variable
+ * NSPR_ATOMIC_HASH_LOCKS
+ */
+
+/*
+ * lock counts should be a power of 2
+ */
+#define DEFAULT_ATOMIC_LOCKS	16	/* should be in sync with the number of initializers
+										below */
+#define MAX_ATOMIC_LOCKS		(4 * 1024)
+
+static pthread_mutex_t static_atomic_locks[DEFAULT_ATOMIC_LOCKS] = {
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER };
+
+#ifdef DEBUG
+static PRInt32 static_hash_lock_counts[DEFAULT_ATOMIC_LOCKS];
+static PRInt32 *hash_lock_counts = static_hash_lock_counts;
+#endif
+
+static PRUint32	num_atomic_locks = DEFAULT_ATOMIC_LOCKS;
+static pthread_mutex_t *atomic_locks = static_atomic_locks;
+static PRUint32 atomic_hash_mask = DEFAULT_ATOMIC_LOCKS - 1;
+
+#define _PR_HASH_FOR_LOCK(ptr) 							\
+			((PRUint32) (((PRUptrdiff) (ptr) >> 2)	^	\
+						((PRUptrdiff) (ptr) >> 8)) &	\
+						atomic_hash_mask)
+
+void _PR_MD_INIT_ATOMIC()
+{
+char *eval;
+int index;
+
+
+	PR_ASSERT(PR_FloorLog2(MAX_ATOMIC_LOCKS) ==
+						PR_CeilingLog2(MAX_ATOMIC_LOCKS));
+
+	PR_ASSERT(PR_FloorLog2(DEFAULT_ATOMIC_LOCKS) ==
+							PR_CeilingLog2(DEFAULT_ATOMIC_LOCKS));
+
+	if (((eval = getenv("NSPR_ATOMIC_HASH_LOCKS")) != NULL)  &&
+		((num_atomic_locks = atoi(eval)) != DEFAULT_ATOMIC_LOCKS)) {
+
+		if (num_atomic_locks > MAX_ATOMIC_LOCKS)
+			num_atomic_locks = MAX_ATOMIC_LOCKS;
+		else if (num_atomic_locks < 1) 
+			num_atomic_locks = 1;
+		else {
+			num_atomic_locks = PR_FloorLog2(num_atomic_locks);
+			num_atomic_locks = 1L << num_atomic_locks;
+		}
+		atomic_locks = (pthread_mutex_t *) PR_Malloc(sizeof(pthread_mutex_t) *
+						num_atomic_locks);
+		if (atomic_locks) {
+			for (index = 0; index < num_atomic_locks; index++) {
+				if (pthread_mutex_init(&atomic_locks[index], NULL)) {
+						PR_DELETE(atomic_locks);
+						atomic_locks = NULL;
+						break; 
+				}
+			}
+		}
+#ifdef DEBUG
+		if (atomic_locks) {
+			hash_lock_counts = PR_CALLOC(num_atomic_locks * sizeof(PRInt32));
+			if (hash_lock_counts == NULL) {
+				PR_DELETE(atomic_locks);
+				atomic_locks = NULL;
+			}
+		}
+#endif
+		if (atomic_locks == NULL) {
+			/*
+			 *	Use statically allocated locks
+			 */
+			atomic_locks = static_atomic_locks;
+			num_atomic_locks = DEFAULT_ATOMIC_LOCKS;
+	#ifdef DEBUG
+			hash_lock_counts = static_hash_lock_counts;
+	#endif
+		}
+		atomic_hash_mask = num_atomic_locks - 1;
+	}
+	PR_ASSERT(PR_FloorLog2(num_atomic_locks) ==
+								PR_CeilingLog2(num_atomic_locks));
+}
+
+PRInt32
+_PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    PRInt32 rv;
+    PRInt32 idx = _PR_HASH_FOR_LOCK(val);
+
+    pthread_mutex_lock(&atomic_locks[idx]);
+    rv = ++(*val);
+#ifdef DEBUG
+    hash_lock_counts[idx]++;
+#endif
+    pthread_mutex_unlock(&atomic_locks[idx]);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    PRInt32 rv;
+    PRInt32 idx = _PR_HASH_FOR_LOCK(ptr);
+
+    pthread_mutex_lock(&atomic_locks[idx]);
+    rv = ((*ptr) += val);
+#ifdef DEBUG
+    hash_lock_counts[idx]++;
+#endif
+    pthread_mutex_unlock(&atomic_locks[idx]);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    PRInt32 rv;
+    PRInt32 idx = _PR_HASH_FOR_LOCK(val);
+
+    pthread_mutex_lock(&atomic_locks[idx]);
+    rv = --(*val);
+#ifdef DEBUG
+    hash_lock_counts[idx]++;
+#endif
+    pthread_mutex_unlock(&atomic_locks[idx]);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    PRInt32 rv;
+    PRInt32 idx = _PR_HASH_FOR_LOCK(val);
+
+    pthread_mutex_lock(&atomic_locks[idx]);
+    rv = *val;
+    *val = newval;
+#ifdef DEBUG
+    hash_lock_counts[idx]++;
+#endif
+    pthread_mutex_unlock(&atomic_locks[idx]);
+    return rv;
+}
+#else  /* _PR_PTHREADS && !_PR_DCETHREADS */
+/*
+ * We use a single lock for all the emulated atomic operations.
+ * The lock contention should be acceptable.
+ */
+static PRLock *atomic_lock = NULL;
+void _PR_MD_INIT_ATOMIC(void)
+{
+    if (atomic_lock == NULL) {
+        atomic_lock = PR_NewLock();
+    }
+}
+
+PRInt32
+_PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(atomic_lock);
+    rv = ++(*val);
+    PR_Unlock(atomic_lock);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(atomic_lock);
+    rv = ((*ptr) += val);
+    PR_Unlock(atomic_lock);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(atomic_lock);
+    rv = --(*val);
+    PR_Unlock(atomic_lock);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(atomic_lock);
+    rv = *val;
+    *val = newval;
+    PR_Unlock(atomic_lock);
+    return rv;
+}
+#endif  /* _PR_PTHREADS && !_PR_DCETHREADS */
+
+#endif  /* !_PR_HAVE_ATOMIC_OPS */
+
+void _PR_InitAtomic(void)
+{
+    _PR_MD_INIT_ATOMIC();
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_AtomicIncrement(PRInt32 *val)
+{
+    return _PR_MD_ATOMIC_INCREMENT(val);
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_AtomicDecrement(PRInt32 *val)
+{
+    return _PR_MD_ATOMIC_DECREMENT(val);
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_AtomicSet(PRInt32 *val, PRInt32 newval)
+{
+    return _PR_MD_ATOMIC_SET(val, newval);
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+{
+    return _PR_MD_ATOMIC_ADD(ptr, val);
+}
+/*
+ * For platforms, which don't support the CAS (compare-and-swap) instruction
+ * (or an equivalent), the stack operations are implemented by use of PRLock
+ */
+
+PR_IMPLEMENT(PRStack *)
+PR_CreateStack(const char *stack_name)
+{
+PRStack *stack;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+
+    if ((stack = PR_NEW(PRStack)) == NULL) {
+		return NULL;
+	}
+	if (stack_name) {
+		stack->prstk_name = (char *) PR_Malloc(strlen(stack_name) + 1);
+		if (stack->prstk_name == NULL) {
+			PR_DELETE(stack);
+			return NULL;
+		}
+		strcpy(stack->prstk_name, stack_name);
+	} else
+		stack->prstk_name = NULL;
+
+#ifndef _PR_HAVE_ATOMIC_CAS
+    stack->prstk_lock = PR_NewLock();
+	if (stack->prstk_lock == NULL) {
+		PR_Free(stack->prstk_name);
+		PR_DELETE(stack);
+		return NULL;
+	}
+#endif /* !_PR_HAVE_ATOMIC_CAS */
+
+	stack->prstk_head.prstk_elem_next = NULL;
+	
+    return stack;
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_DestroyStack(PRStack *stack)
+{
+	if (stack->prstk_head.prstk_elem_next != NULL) {
+		PR_SetError(PR_INVALID_STATE_ERROR, 0);
+		return PR_FAILURE;
+	}
+
+	if (stack->prstk_name)
+		PR_Free(stack->prstk_name);
+#ifndef _PR_HAVE_ATOMIC_CAS
+	PR_DestroyLock(stack->prstk_lock);
+#endif /* !_PR_HAVE_ATOMIC_CAS */
+	PR_DELETE(stack);
+
+	return PR_SUCCESS;
+}
+
+#ifndef _PR_HAVE_ATOMIC_CAS
+
+PR_IMPLEMENT(void)
+PR_StackPush(PRStack *stack, PRStackElem *stack_elem)
+{
+    PR_Lock(stack->prstk_lock);
+	stack_elem->prstk_elem_next = stack->prstk_head.prstk_elem_next;
+	stack->prstk_head.prstk_elem_next = stack_elem;
+    PR_Unlock(stack->prstk_lock);
+    return;
+}
+
+PR_IMPLEMENT(PRStackElem *)
+PR_StackPop(PRStack *stack)
+{
+PRStackElem *element;
+
+    PR_Lock(stack->prstk_lock);
+	element = stack->prstk_head.prstk_elem_next;
+	if (element != NULL) {
+		stack->prstk_head.prstk_elem_next = element->prstk_elem_next;
+		element->prstk_elem_next = NULL;	/* debugging aid */
+	}
+    PR_Unlock(stack->prstk_lock);
+    return element;
+}
+#endif /* !_PR_HAVE_ATOMIC_CAS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/praton.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/praton.c
new file mode 100644
index 0000000..bff0cd1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/praton.c
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*******************************************************************************
+ * The following function pr_inet_aton is based on the BSD function inet_aton
+ * with some modifications. The license and copyright notices applying to this
+ * function appear below. Modifications are also according to the license below.
+ ******************************************************************************/
+
+#include "prnetdb.h"
+
+/*
+ * Copyright (c) 1983, 1990, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#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,
+};
+
+static PRBool _isdigit(char c) { return c >= '0' && c <= '9'; }
+static PRBool _isxdigit(char c) { return index_hex[(unsigned char) c] != XX; }
+static PRBool _isspace(char c) { return c == ' ' || (c >= '\t' && c <= '\r'); }
+#undef XX
+
+int
+pr_inet_aton(const char *cp, PRUint32 *addr)
+{
+    PRUint32 val;
+    int base, n;
+    char c;
+    PRUint8 parts[4];
+    PRUint8 *pp = parts;
+    int digit;
+
+    c = *cp;
+    for (;;) {
+        /*
+         * Collect number up to ``.''.
+         * Values are specified as for C:
+         * 0x=hex, 0=octal, isdigit=decimal.
+         */
+        if (!_isdigit(c))
+            return (0);
+        val = 0; base = 10; digit = 0;
+        if (c == '0') {
+            c = *++cp;
+            if (c == 'x' || c == 'X')
+                base = 16, c = *++cp;
+            else {
+                base = 8;
+                digit = 1;
+            }
+        }
+        for (;;) {
+            if (_isdigit(c)) {
+                if (base == 8 && (c == '8' || c == '9'))
+                    return (0);
+                val = (val * base) + (c - '0');
+                c = *++cp;
+                digit = 1;
+            } else if (base == 16 && _isxdigit(c)) {
+                val = (val << 4) + index_hex[(unsigned char) c];
+                c = *++cp;
+                digit = 1;
+            } else
+                break;
+        }
+        if (c == '.') {
+            /*
+             * Internet format:
+             *    a.b.c.d
+             *    a.b.c    (with c treated as 16 bits)
+             *    a.b    (with b treated as 24 bits)
+             */
+            if (pp >= parts + 3 || val > 0xffU)
+                return (0);
+            *pp++ = val;
+            c = *++cp;
+        } else
+            break;
+    }
+    /*
+     * Check for trailing characters.
+     */
+    if (c != '\0' && !_isspace(c))
+        return (0);
+    /*
+     * Did we get a valid digit?
+     */
+    if (!digit)
+        return (0);
+    /*
+     * Concoct the address according to
+     * the number of parts specified.
+     */
+    n = pp - parts + 1;
+    switch (n) {
+    case 1:                /*%< a -- 32 bits */
+        break;
+
+    case 2:                /*%< a.b -- 8.24 bits */
+        if (val > 0xffffffU)
+            return (0);
+        val |= parts[0] << 24;
+        break;
+
+    case 3:                /*%< a.b.c -- 8.8.16 bits */
+        if (val > 0xffffU)
+            return (0);
+        val |= (parts[0] << 24) | (parts[1] << 16);
+        break;
+
+    case 4:                /*%< a.b.c.d -- 8.8.8.8 bits */
+        if (val > 0xffU)
+            return (0);
+        val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+        break;
+    }
+    *addr = PR_htonl(val);
+    return (1);
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prcountr.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prcountr.c
new file mode 100644
index 0000000..a4e4f6c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prcountr.c
@@ -0,0 +1,506 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** prcountr.c -- NSPR Instrumentation Counters
+**
+** Implement the interface defined in prcountr.h
+**
+** Design Notes:
+**
+** The Counter Facility (CF) has a single anchor: qNameList.      
+** The anchor is a PRCList. qNameList is a list of links in QName
+** structures. From qNameList any QName structure and its
+** associated RName structure can be located. 
+** 
+** For each QName, a list of RName structures is anchored at
+** rnLink in the QName structure.
+** 
+** The counter itself is embedded in the RName structure.
+** 
+** For manipulating the counter database, single lock is used to
+** protect the entire list: counterLock.
+**
+** A PRCounterHandle, defined in prcountr.h, is really a pointer
+** to a RName structure. References by PRCounterHandle are
+** dead-reconed to the RName structure. The PRCounterHandle is
+** "overloaded" for traversing the QName structures; only the
+** function PR_FindNextQnameHandle() uses this overloading.
+**
+** 
+** ToDo (lth): decide on how to lock or atomically update
+** individual counters. Candidates are: the global lock; a lock
+** per RName structure; Atomic operations (Note that there are
+** not adaquate atomic operations (yet) to achieve this goal). At
+** this writing (6/19/98) , the update of the counter variable in
+** a QName structure is unprotected.
+**
+*/
+
+#include "prcountr.h"
+#include "prclist.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmem.h"
+#include <string.h>
+
+/*
+**
+*/
+typedef struct QName
+{
+    PRCList link;
+    PRCList rNameList;
+    char    name[PRCOUNTER_NAME_MAX+1];
+} QName;
+
+/*
+**
+*/
+typedef struct RName
+{
+    PRCList link;
+    QName   *qName;
+    PRLock  *lock;
+    volatile PRUint32   counter;    
+    char    name[PRCOUNTER_NAME_MAX+1]; 
+    char    desc[PRCOUNTER_DESC_MAX+1]; 
+} RName;
+
+
+/*
+** Define the Counter Facility database
+*/
+static PRLock  *counterLock;
+static PRCList qNameList;
+static PRLogModuleInfo *lm;
+
+/*
+** _PR_CounterInitialize() -- Initialize the Counter Facility
+**
+*/
+static void _PR_CounterInitialize( void )
+{
+    /*
+    ** This function should be called only once
+    */
+    PR_ASSERT( counterLock == NULL );
+    
+    counterLock = PR_NewLock();
+    PR_INIT_CLIST( &qNameList );
+    lm = PR_NewLogModule("counters");
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Initialization complete"));
+
+    return;
+} /* end _PR_CounterInitialize() */
+
+/*
+** PR_CreateCounter() -- Create a counter
+**
+**  ValidateArguments
+**  Lock
+**  if (qName not already in database)
+**      NewQname
+**  if (rName already in database )
+**      Assert
+**  else NewRname
+**  NewCounter
+**  link 'em up
+**  Unlock
+**
+*/
+PR_IMPLEMENT(PRCounterHandle) 
+	PR_CreateCounter( 
+		const char *qName, 
+    	const char *rName, 
+        const char *description 
+) 
+{
+    QName   *qnp;
+    RName   *rnp;
+    PRBool  matchQname = PR_FALSE;
+
+    /* Self initialize, if necessary */
+    if ( counterLock == NULL )
+        _PR_CounterInitialize();
+
+    /* Validate input arguments */
+    PR_ASSERT( strlen(qName) <= PRCOUNTER_NAME_MAX );
+    PR_ASSERT( strlen(rName) <= PRCOUNTER_NAME_MAX );
+    PR_ASSERT( strlen(description) <= PRCOUNTER_DESC_MAX );
+
+    /* Lock the Facility */
+    PR_Lock( counterLock );
+
+    /* Do we already have a matching QName? */
+    if (!PR_CLIST_IS_EMPTY( &qNameList ))
+    {
+        qnp = (QName *) PR_LIST_HEAD( &qNameList );
+        do {
+            if ( strcmp(qnp->name, qName) == 0)
+            {
+                matchQname = PR_TRUE;
+                break;
+            }
+            qnp = (QName *)PR_NEXT_LINK( &qnp->link );
+        } while( qnp != (QName *)PR_LIST_HEAD( &qNameList ));
+    }
+    /*
+    ** If we did not find a matching QName,
+    **    allocate one and initialize it.
+    **    link it onto the qNameList.
+    **
+    */
+    if ( matchQname != PR_TRUE )
+    {
+        qnp = PR_NEWZAP( QName );
+        PR_ASSERT( qnp != NULL );
+        PR_INIT_CLIST( &qnp->link ); 
+        PR_INIT_CLIST( &qnp->rNameList ); 
+        strcpy( qnp->name, qName );
+        PR_APPEND_LINK( &qnp->link, &qNameList ); 
+    }
+
+    /* Do we already have a matching RName? */
+    if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
+    {
+        rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
+        do {
+            /*
+            ** No duplicate RNames are allowed within a QName
+            **
+            */
+            PR_ASSERT( strcmp(rnp->name, rName));
+            rnp = (RName *)PR_NEXT_LINK( &rnp->link );
+        } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList ));
+    }
+
+    /* Get a new RName structure; initialize its members */
+    rnp = PR_NEWZAP( RName );
+    PR_ASSERT( rnp != NULL );
+    PR_INIT_CLIST( &rnp->link );
+    strcpy( rnp->name, rName );
+    strcpy( rnp->desc, description );
+    rnp->lock = PR_NewLock();
+    if ( rnp->lock == NULL )
+    {
+        PR_ASSERT(0);
+    }
+
+    PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */    
+    rnp->qName = qnp;                       /* point the RName to the QName */
+
+    /* Unlock the Facility */
+    PR_Unlock( counterLock );
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t",
+        qName, qnp, rName, rnp ));
+
+    return((PRCounterHandle)rnp);
+} /*  end PR_CreateCounter() */
+  
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_DestroyCounter( 
+		PRCounterHandle handle 
+)
+{
+    RName   *rnp = (RName *)handle;
+    QName   *qnp = rnp->qName;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s", 
+        qnp->name, rnp->name));
+
+    /* Lock the Facility */
+    PR_Lock( counterLock );
+
+    /*
+    ** Remove RName from the list of RNames in QName
+    ** and free RName
+    */
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p", 
+        rnp->name, rnp));
+    PR_REMOVE_LINK( &rnp->link );
+    PR_Free( rnp->lock );
+    PR_DELETE( rnp );
+
+    /*
+    ** If this is the last RName within QName
+    **   remove QName from the qNameList and free it
+    */
+    if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
+    {
+        PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p", 
+            qnp->name, qnp));
+        PR_REMOVE_LINK( &qnp->link );
+        PR_DELETE( qnp );
+    } 
+
+    /* Unlock the Facility */
+    PR_Unlock( counterLock );
+    return;
+} /*  end PR_DestroyCounter() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRCounterHandle) 
+	PR_GetCounterHandleFromName( 
+    	const char *qName, 
+    	const char *rName 
+)
+{
+    const char    *qn, *rn, *desc;
+    PRCounterHandle     qh, rh = NULL;
+    RName   *rnp = NULL;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounterHandleFromName:\n\t"
+        "QName: %s, RName: %s", qName, rName ));
+
+    qh = PR_FindNextCounterQname( NULL );
+    while (qh != NULL)
+    {
+        rh = PR_FindNextCounterRname( NULL, qh );
+        while ( rh != NULL )
+        {
+            PR_GetCounterNameFromHandle( rh, &qn, &rn, &desc );
+            if ( (strcmp( qName, qn ) == 0)
+                && (strcmp( rName, rn ) == 0 ))
+            {
+                rnp = (RName *)rh;
+                goto foundIt;
+            }
+            rh = PR_FindNextCounterRname( rh, qh );
+        }
+        qh = PR_FindNextCounterQname( NULL );
+    }
+
+foundIt:
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp ));
+    return(rh);
+} /*  end PR_GetCounterHandleFromName() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_GetCounterNameFromHandle( 
+    	PRCounterHandle handle,  
+	    const char **qName, 
+	    const char **rName, 
+		const char **description 
+)
+{
+    RName   *rnp = (RName *)handle;
+    QName   *qnp = rnp->qName;
+
+    *qName = qnp->name;
+    *rName = rnp->name;
+    *description = rnp->desc;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterNameFromHandle: "
+        "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", 
+        qnp, rnp, qnp->name, rnp->name, rnp->desc ));
+
+    return;
+} /*  end PR_GetCounterNameFromHandle() */
+
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_IncrementCounter( 
+		PRCounterHandle handle
+)
+{
+    PR_Lock(((RName *)handle)->lock);
+    ((RName *)handle)->counter++;
+    PR_Unlock(((RName *)handle)->lock);
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end PR_IncrementCounter() */
+
+
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_DecrementCounter( 
+		PRCounterHandle handle
+)
+{
+    PR_Lock(((RName *)handle)->lock);
+    ((RName *)handle)->counter--;
+    PR_Unlock(((RName *)handle)->lock);
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end PR_DecrementCounter()  */
+
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_AddToCounter( 
+    	PRCounterHandle handle, 
+	    PRUint32 value 
+)
+{
+    PR_Lock(((RName *)handle)->lock);
+    ((RName *)handle)->counter += value;
+    PR_Unlock(((RName *)handle)->lock);
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end PR_AddToCounter() */
+
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_SubtractFromCounter( 
+    	PRCounterHandle handle, 
+	    PRUint32 value 
+)
+{
+    PR_Lock(((RName *)handle)->lock);
+    ((RName *)handle)->counter -= value;
+    PR_Unlock(((RName *)handle)->lock);
+    
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end  PR_SubtractFromCounter() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRUint32) 
+	PR_GetCounter( 
+		PRCounterHandle handle 
+)
+{
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return(((RName *)handle)->counter);
+} /*  end  PR_GetCounter() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_SetCounter( 
+		PRCounterHandle handle, 
+		PRUint32 value 
+)
+{
+    ((RName *)handle)->counter = value;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end  PR_SetCounter() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRCounterHandle) 
+	PR_FindNextCounterQname( 
+        PRCounterHandle handle
+)
+{
+    QName *qnp = (QName *)handle;
+
+    if ( PR_CLIST_IS_EMPTY( &qNameList ))
+            qnp = NULL;
+    else if ( qnp == NULL )
+        qnp = (QName *)PR_LIST_HEAD( &qNameList );
+    else if ( PR_NEXT_LINK( &qnp->link ) ==  &qNameList )
+        qnp = NULL;
+    else  
+        qnp = (QName *)PR_NEXT_LINK( &qnp->link );
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", 
+        handle, qnp ));
+
+    return((PRCounterHandle)qnp);
+} /*  end  PR_FindNextCounterQname() */
+
+
+/*
+**
+*/
+PR_IMPLEMENT(PRCounterHandle) 
+	PR_FindNextCounterRname( 
+        PRCounterHandle rhandle, 
+        PRCounterHandle qhandle 
+)
+{
+    RName *rnp = (RName *)rhandle;
+    QName *qnp = (QName *)qhandle;
+
+
+    if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
+        rnp = NULL;
+    else if ( rnp == NULL )
+        rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
+    else if ( PR_NEXT_LINK( &rnp->link ) ==  &qnp->rNameList )
+        rnp = NULL;
+    else
+        rnp = (RName *)PR_NEXT_LINK( &rnp->link );
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", 
+        rhandle, qhandle, rnp ));
+
+    return((PRCounterHandle)rnp);
+} /*  end PR_FindNextCounterRname() */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prdtoa.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prdtoa.c
new file mode 100644
index 0000000..4f26b20
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prdtoa.c
@@ -0,0 +1,3552 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This file is based on the third-party code dtoa.c.  We minimize our
+ * modifications to third-party code to make it easy to merge new versions.
+ * The author of dtoa.c was not willing to add the parentheses suggested by
+ * GCC, so we suppress these warnings.
+ */
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+#pragma GCC diagnostic ignored "-Wparentheses"
+#endif
+
+#include "primpl.h"
+#include "prbit.h"
+
+#define MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n)	PR_Lock(dtoa_lock[n])
+#define FREE_DTOA_LOCK(n)	PR_Unlock(dtoa_lock[n])
+
+static PRLock *dtoa_lock[2];
+
+void _PR_InitDtoa(void)
+{
+    dtoa_lock[0] = PR_NewLock();
+    dtoa_lock[1] = PR_NewLock();
+}
+
+void _PR_CleanupDtoa(void)
+{
+    PR_DestroyLock(dtoa_lock[0]);
+    dtoa_lock[0] = NULL;
+    PR_DestroyLock(dtoa_lock[1]);
+    dtoa_lock[1] = NULL;
+
+    /* FIXME: deal with freelist and p5s. */
+}
+
+#if !defined(__ARM_EABI__) \
+    && (defined(__arm) || defined(__arm__) || defined(__arm26__) \
+    || defined(__arm32__))
+#define IEEE_ARM
+#elif defined(IS_LITTLE_ENDIAN)
+#define IEEE_8087
+#else
+#define IEEE_MC68k
+#endif
+
+#define Long PRInt32
+#define ULong PRUint32
+#define NO_LONG_LONG
+
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to ".").	*/
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa.  If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ *	_control87(PC_53, MCW_PC);
+ * does this with many compilers.  Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE).  With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule.  Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ *	1. We only require IEEE, IBM, or VAX double-precision
+ *		arithmetic (not IEEE double-extended).
+ *	2. We get by with floating-point arithmetic in a case that
+ *		Clinger missed -- when we're computing d * 10^n
+ *		for a small integer d and the integer n is not too
+ *		much larger than 22 (the maximum integer k for which
+ *		we can represent 10^k exactly), we may be able to
+ *		compute (d*10^k) * 10^(e-k) with just one roundoff.
+ *	3. Rather than a bit-at-a-time adjustment of the binary
+ *		result in the hard case, we use floating-point
+ *		arithmetic to determine the adjustment to within
+ *		one bit; only in really hard cases do we need to
+ *		compute a second residual.
+ *	4. Because of 3., we don't need a large table of powers of 10
+ *		for ten-to-e (just some small tables, e.g. of 10^k
+ *		for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ *	significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ *	significant byte has the lowest address.
+ * #define IEEE_ARM for IEEE-arithmetic machines where the two words
+ *	in a double are stored in big endian order but the two shorts
+ *	in a word are still stored in little endian order.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic (D_floating).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ *	computation of dtoa.
+ * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ *	and strtod and dtoa should round accordingly.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ *	and Honor_FLT_ROUNDS is not #defined.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ *	that use extended-precision instructions to compute rounded
+ *	products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ *	products but inaccurate quotients, e.g., for Intel i860.
+ * #define NO_LONG_LONG on machines that do not have a "long long"
+ *	integer type (of >= 64 bits).  On such machines, you can
+ *	#define Just_16 to store 16 bits per 32-bit Long when doing
+ *	high-precision integer arithmetic.  Whether this speeds things
+ *	up or slows things down depends on the machine and the number
+ *	being converted.  If long long is available and the name is
+ *	something other than "long long", #define Llong to be the name,
+ *	and if "unsigned Llong" does not work as an unsigned version of
+ *	Llong, #define #ULLong to be the corresponding unsigned type.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ *	define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ *	FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ *	if memory is available and otherwise does something you deem
+ *	appropriate.  If MALLOC is undefined, malloc will be invoked
+ *	directly -- and assumed always to succeed.  Similarly, if you
+ *	want something other than the system's free() to be called to
+ *	recycle memory acquired from MALLOC, #define FREE to be the
+ *	name of the alternate routine.  (FREE or free is only called in
+ *	pathological cases, e.g., in a dtoa call after a dtoa return in
+ *	mode 3 with thousands of digits requested.)
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
+ *	memory allocations from a private pool of memory when possible.
+ *	When used, the private pool is PRIVATE_MEM bytes long:  2304 bytes,
+ *	unless #defined to be a different length.  This default length
+ *	suffices to get rid of MALLOC calls except for unusual cases,
+ *	such as decimal-to-binary conversion of a very long string of
+ *	digits.  The longest string dtoa can return is about 751 bytes
+ *	long.  For conversions by strtod of strings of 800 digits and
+ *	all dtoa conversions in single-threaded executions with 8-byte
+ *	pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte
+ *	pointers, PRIVATE_MEM >= 7112 appears adequate.
+ * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
+ *	Infinity and NaN (case insensitively).  On some systems (e.g.,
+ *	some HP systems), it may be necessary to #define NAN_WORD0
+ *	appropriately -- to the most significant word of a quiet NaN.
+ *	(On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ *	When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
+ *	strtod also accepts (case insensitively) strings of the form
+ *	NaN(x), where x is a string of hexadecimal digits and spaces;
+ *	if there is only one string of hexadecimal digits, it is taken
+ *	for the 52 fraction bits of the resulting NaN; if there are two
+ *	or more strings of hex digits, the first is for the high 20 bits,
+ *	the second and subsequent for the low 32 bits, with intervening
+ *	white space ignored; but if this results in none of the 52
+ *	fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0
+ *	and NAN_WORD1 are used instead.
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
+ *	multiple threads.  In this case, you must provide (or suitably
+ *	#define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed
+ *	by FREE_DTOA_LOCK(n) for n = 0 or 1.  (The second lock, accessed
+ *	in pow5mult, ensures lazy evaluation of only one copy of high
+ *	powers of 5; omitting this lock would introduce a small
+ *	probability of wasting memory, but would otherwise be harmless.)
+ *	You must also invoke freedtoa(s) to free the value s returned by
+ *	dtoa.  You may do so whether or not MULTIPLE_THREADS is #defined.
+ * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
+ *	avoids underflows on inputs whose result does not underflow.
+ *	If you #define NO_IEEE_Scale on a machine that uses IEEE-format
+ *	floating-point numbers and flushes underflows to zero rather
+ *	than implementing gradual underflow, then you must also #define
+ *	Sudden_Underflow.
+ * #define USE_LOCALE to use the current locale's decimal_point value.
+ * #define SET_INEXACT if IEEE arithmetic is being used and extra
+ *	computation should be done to set the inexact flag when the
+ *	result is inexact and avoid setting inexact when the result
+ *	is exact.  In this case, dtoa.c must be compiled in
+ *	an environment, perhaps provided by #include "dtoa.c" in a
+ *	suitable wrapper, that defines two functions,
+ *		int get_inexact(void);
+ *		void clear_inexact(void);
+ *	such that get_inexact() returns a nonzero value if the
+ *	inexact bit is already set, and clear_inexact() sets the
+ *	inexact bit to 0.  When SET_INEXACT is #defined, strtod
+ *	also does extra computations to set the underflow and overflow
+ *	flags when appropriate (i.e., when the result is tiny and
+ *	inexact or when it is a numeric value rounded to +-infinity).
+ * #define NO_ERRNO if strtod should not assign errno = ERANGE when
+ *	the result overflows to +-Infinity or underflows to 0.
+ */
+
+#ifndef Long
+#define Long long
+#endif
+#ifndef ULong
+typedef unsigned Long ULong;
+#endif
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#include "stdlib.h"
+#include "string.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+#ifdef MALLOC
+#ifdef KR_headers
+extern char *MALLOC();
+#else
+extern void *MALLOC(size_t);
+#endif
+#else
+#define MALLOC malloc
+#endif
+
+#ifndef Omit_Private_Memory
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2304
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#endif
+
+#undef IEEE_Arith
+#undef Avoid_Underflow
+#ifdef IEEE_MC68k
+#define IEEE_Arith
+#endif
+#ifdef IEEE_8087
+#define IEEE_Arith
+#endif
+#ifdef IEEE_ARM
+#define IEEE_Arith
+#endif
+
+#include "errno.h"
+
+#ifdef Bad_float_h
+
+#ifdef IEEE_Arith
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#endif /*IEEE_Arith*/
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define DBL_MAX 1.7014118346046923e+38
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+
+#else /* ifndef Bad_float_h */
+#include "float.h"
+/*
+ * MacOS 10.2 defines the macro FLT_ROUNDS to an internal function
+ * which does not exist on 10.1.  We can safely #define it to 1 here
+ * to allow 10.2 builds to run on 10.1, since we can't use fesetround()
+ * (which does not exist on 10.1 either).
+ */
+#if defined(XP_MACOSX) && (!defined(MAC_OS_X_VERSION_10_2) || \
+    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2)
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+#endif /* DT < 10.2 */
+#endif /* Bad_float_h */
+
+#ifndef __MATH_H__
+#include "math.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CONST
+#ifdef KR_headers
+#define CONST /* blank */
+#else
+#define CONST const
+#endif
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, IEEE_ARM, VAX, or IBM should be defined.
+#endif
+
+typedef union { double d; ULong L[2]; } U;
+
+#define dval(x) (x).d
+#ifdef IEEE_8087
+#define word0(x) (x).L[1]
+#define word1(x) (x).L[0]
+#else
+#define word0(x) (x).L[0]
+#define word1(x) (x).L[1]
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(IEEE_ARM) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#ifdef IEEE_Arith
+#define Exp_shift  20
+#define Exp_shift1 20
+#define Exp_msk1    0x100000
+#define Exp_msk11   0x100000
+#define Exp_mask  0x7ff00000
+#define P 53
+#define Bias 1023
+#define Emin (-1022)
+#define Exp_1  0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask  0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask  0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#ifndef NO_IEEE_Scale
+#define Avoid_Underflow
+#ifdef Flush_Denorm	/* debugging option */
+#undef Sudden_Underflow
+#endif
+#endif
+
+#ifndef Flt_Rounds
+#ifdef FLT_ROUNDS
+#define Flt_Rounds FLT_ROUNDS
+#else
+#define Flt_Rounds 1
+#endif
+#endif /*Flt_Rounds*/
+
+#ifdef Honor_FLT_ROUNDS
+#define Rounding rounding
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+#else /* ifndef IEEE_Arith */
+#undef Check_FLT_ROUNDS
+#undef Honor_FLT_ROUNDS
+#undef SET_INEXACT
+#undef  Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#undef Flt_Rounds
+#define Flt_Rounds 0
+#define Exp_shift  24
+#define Exp_shift1 24
+#define Exp_msk1   0x1000000
+#define Exp_msk11  0x1000000
+#define Exp_mask  0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1  0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8	/* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask  0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask  0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#undef Flt_Rounds
+#define Flt_Rounds 1
+#define Exp_shift  23
+#define Exp_shift1 7
+#define Exp_msk1    0x80
+#define Exp_msk11   0x800000
+#define Exp_mask  0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1  0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask  0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask  0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif /* IBM, VAX */
+#endif /* IEEE_Arith */
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Pack_32
+#define Pack_32
+#endif
+
+#ifdef KR_headers
+#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff)
+#else
+#define FFFFFFFF 0xffffffffUL
+#endif
+
+#ifdef NO_LONG_LONG
+#undef ULLong
+#ifdef Just_16
+#undef Pack_32
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower.  Hence the default is now to store 32 bits per Long.
+ */
+#endif
+#else	/* long long available */
+#ifndef Llong
+#define Llong long long
+#endif
+#ifndef ULLong
+#define ULLong unsigned Llong
+#endif
+#endif /* NO_LONG_LONG */
+
+#ifndef MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n)	/*nothing*/
+#define FREE_DTOA_LOCK(n)	/*nothing*/
+#endif
+
+#define Kmax 7
+
+ struct
+Bigint {
+	struct Bigint *next;
+	int k, maxwds, sign, wds;
+	ULong x[1];
+	};
+
+ typedef struct Bigint Bigint;
+
+ static Bigint *freelist[Kmax+1];
+
+ static Bigint *
+Balloc
+#ifdef KR_headers
+	(k) int k;
+#else
+	(int k)
+#endif
+{
+	int x;
+	Bigint *rv;
+#ifndef Omit_Private_Memory
+	unsigned int len;
+#endif
+
+	ACQUIRE_DTOA_LOCK(0);
+	/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
+	/* but this case seems very unlikely. */
+	if (k <= Kmax && (rv = freelist[k]))
+		freelist[k] = rv->next;
+	else {
+		x = 1 << k;
+#ifdef Omit_Private_Memory
+		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
+#else
+		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+			/sizeof(double);
+		if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
+			rv = (Bigint*)pmem_next;
+			pmem_next += len;
+			}
+		else
+			rv = (Bigint*)MALLOC(len*sizeof(double));
+#endif
+		rv->k = k;
+		rv->maxwds = x;
+		}
+	FREE_DTOA_LOCK(0);
+	rv->sign = rv->wds = 0;
+	return rv;
+	}
+
+ static void
+Bfree
+#ifdef KR_headers
+	(v) Bigint *v;
+#else
+	(Bigint *v)
+#endif
+{
+	if (v) {
+		if (v->k > Kmax)
+#ifdef FREE
+			FREE((void*)v);
+#else
+			free((void*)v);
+#endif
+		else {
+			ACQUIRE_DTOA_LOCK(0);
+			v->next = freelist[v->k];
+			freelist[v->k] = v;
+			FREE_DTOA_LOCK(0);
+			}
+		}
+	}
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+y->wds*sizeof(Long) + 2*sizeof(int))
+
+ static Bigint *
+multadd
+#ifdef KR_headers
+	(b, m, a) Bigint *b; int m, a;
+#else
+	(Bigint *b, int m, int a)	/* multiply by m and add a */
+#endif
+{
+	int i, wds;
+#ifdef ULLong
+	ULong *x;
+	ULLong carry, y;
+#else
+	ULong carry, *x, y;
+#ifdef Pack_32
+	ULong xi, z;
+#endif
+#endif
+	Bigint *b1;
+
+	wds = b->wds;
+	x = b->x;
+	i = 0;
+	carry = a;
+	do {
+#ifdef ULLong
+		y = *x * (ULLong)m + carry;
+		carry = y >> 32;
+		*x++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+		xi = *x;
+		y = (xi & 0xffff) * m + carry;
+		z = (xi >> 16) * m + (y >> 16);
+		carry = z >> 16;
+		*x++ = (z << 16) + (y & 0xffff);
+#else
+		y = *x * m + carry;
+		carry = y >> 16;
+		*x++ = y & 0xffff;
+#endif
+#endif
+		}
+		while(++i < wds);
+	if (carry) {
+		if (wds >= b->maxwds) {
+			b1 = Balloc(b->k+1);
+			Bcopy(b1, b);
+			Bfree(b);
+			b = b1;
+			}
+		b->x[wds++] = carry;
+		b->wds = wds;
+		}
+	return b;
+	}
+
+ static Bigint *
+s2b
+#ifdef KR_headers
+	(s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
+#else
+	(CONST char *s, int nd0, int nd, ULong y9)
+#endif
+{
+	Bigint *b;
+	int i, k;
+	Long x, y;
+
+	x = (nd + 8) / 9;
+	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+	b = Balloc(k);
+	b->x[0] = y9;
+	b->wds = 1;
+#else
+	b = Balloc(k+1);
+	b->x[0] = y9 & 0xffff;
+	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+	i = 9;
+	if (9 < nd0) {
+		s += 9;
+		do b = multadd(b, 10, *s++ - '0');
+			while(++i < nd0);
+		s++;
+		}
+	else
+		s += 10;
+	for(; i < nd; i++)
+		b = multadd(b, 10, *s++ - '0');
+	return b;
+	}
+
+ static int
+hi0bits
+#ifdef KR_headers
+	(x) register ULong x;
+#else
+	(register ULong x)
+#endif
+{
+#ifdef PR_HAVE_BUILTIN_BITSCAN32
+	return( (!x) ? 32 : pr_bitscan_clz32(x) );
+#else
+	register int k = 0;
+
+	if (!(x & 0xffff0000)) {
+		k = 16;
+		x <<= 16;
+		}
+	if (!(x & 0xff000000)) {
+		k += 8;
+		x <<= 8;
+		}
+	if (!(x & 0xf0000000)) {
+		k += 4;
+		x <<= 4;
+		}
+	if (!(x & 0xc0000000)) {
+		k += 2;
+		x <<= 2;
+		}
+	if (!(x & 0x80000000)) {
+		k++;
+		if (!(x & 0x40000000))
+			return 32;
+		}
+	return k;
+#endif /* PR_HAVE_BUILTIN_BITSCAN32 */
+	}
+
+ static int
+lo0bits
+#ifdef KR_headers
+	(y) ULong *y;
+#else
+	(ULong *y)
+#endif
+{
+#ifdef PR_HAVE_BUILTIN_BITSCAN32
+	int k;
+	ULong x = *y;
+
+	if (x>1)
+		*y = ( x >> (k = pr_bitscan_ctz32(x)) );
+	else
+		k = ((x ^ 1) << 5);
+#else
+	register int k;
+	register ULong x = *y;
+
+	if (x & 7) {
+		if (x & 1)
+			return 0;
+		if (x & 2) {
+			*y = x >> 1;
+			return 1;
+			}
+		*y = x >> 2;
+		return 2;
+		}
+	k = 0;
+	if (!(x & 0xffff)) {
+		k = 16;
+		x >>= 16;
+		}
+	if (!(x & 0xff)) {
+		k += 8;
+		x >>= 8;
+		}
+	if (!(x & 0xf)) {
+		k += 4;
+		x >>= 4;
+		}
+	if (!(x & 0x3)) {
+		k += 2;
+		x >>= 2;
+		}
+	if (!(x & 1)) {
+		k++;
+		x >>= 1;
+		if (!x)
+			return 32;
+		}
+	*y = x;
+#endif /* PR_HAVE_BUILTIN_BITSCAN32 */
+	return k;
+	}
+
+ static Bigint *
+i2b
+#ifdef KR_headers
+	(i) int i;
+#else
+	(int i)
+#endif
+{
+	Bigint *b;
+
+	b = Balloc(1);
+	b->x[0] = i;
+	b->wds = 1;
+	return b;
+	}
+
+ static Bigint *
+mult
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	Bigint *c;
+	int k, wa, wb, wc;
+	ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+	ULong y;
+#ifdef ULLong
+	ULLong carry, z;
+#else
+	ULong carry, z;
+#ifdef Pack_32
+	ULong z2;
+#endif
+#endif
+
+	if (a->wds < b->wds) {
+		c = a;
+		a = b;
+		b = c;
+		}
+	k = a->k;
+	wa = a->wds;
+	wb = b->wds;
+	wc = wa + wb;
+	if (wc > a->maxwds)
+		k++;
+	c = Balloc(k);
+	for(x = c->x, xa = x + wc; x < xa; x++)
+		*x = 0;
+	xa = a->x;
+	xae = xa + wa;
+	xb = b->x;
+	xbe = xb + wb;
+	xc0 = c->x;
+#ifdef ULLong
+	for(; xb < xbe; xc0++) {
+		if (y = *xb++) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = *x++ * (ULLong)y + *xc + carry;
+				carry = z >> 32;
+				*xc++ = z & FFFFFFFF;
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		}
+#else
+#ifdef Pack_32
+	for(; xb < xbe; xb++, xc0++) {
+		if (y = *xb & 0xffff) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+				carry = z >> 16;
+				z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+				carry = z2 >> 16;
+				Storeinc(xc, z2, z);
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		if (y = *xb >> 16) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			z2 = *xc;
+			do {
+				z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+				carry = z >> 16;
+				Storeinc(xc, z, z2);
+				z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+				carry = z2 >> 16;
+				}
+				while(x < xae);
+			*xc = z2;
+			}
+		}
+#else
+	for(; xb < xbe; xc0++) {
+		if (y = *xb++) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = *x++ * y + *xc + carry;
+				carry = z >> 16;
+				*xc++ = z & 0xffff;
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		}
+#endif
+#endif
+	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+	c->wds = wc;
+	return c;
+	}
+
+ static Bigint *p5s;
+
+ static Bigint *
+pow5mult
+#ifdef KR_headers
+	(b, k) Bigint *b; int k;
+#else
+	(Bigint *b, int k)
+#endif
+{
+	Bigint *b1, *p5, *p51;
+	int i;
+	static int p05[3] = { 5, 25, 125 };
+
+	if (i = k & 3)
+		b = multadd(b, p05[i-1], 0);
+
+	if (!(k >>= 2))
+		return b;
+	if (!(p5 = p5s)) {
+		/* first time */
+#ifdef MULTIPLE_THREADS
+		ACQUIRE_DTOA_LOCK(1);
+		if (!(p5 = p5s)) {
+			p5 = p5s = i2b(625);
+			p5->next = 0;
+			}
+		FREE_DTOA_LOCK(1);
+#else
+		p5 = p5s = i2b(625);
+		p5->next = 0;
+#endif
+		}
+	for(;;) {
+		if (k & 1) {
+			b1 = mult(b, p5);
+			Bfree(b);
+			b = b1;
+			}
+		if (!(k >>= 1))
+			break;
+		if (!(p51 = p5->next)) {
+#ifdef MULTIPLE_THREADS
+			ACQUIRE_DTOA_LOCK(1);
+			if (!(p51 = p5->next)) {
+				p51 = p5->next = mult(p5,p5);
+				p51->next = 0;
+				}
+			FREE_DTOA_LOCK(1);
+#else
+			p51 = p5->next = mult(p5,p5);
+			p51->next = 0;
+#endif
+			}
+		p5 = p51;
+		}
+	return b;
+	}
+
+ static Bigint *
+lshift
+#ifdef KR_headers
+	(b, k) Bigint *b; int k;
+#else
+	(Bigint *b, int k)
+#endif
+{
+	int i, k1, n, n1;
+	Bigint *b1;
+	ULong *x, *x1, *xe, z;
+
+#ifdef Pack_32
+	n = k >> 5;
+#else
+	n = k >> 4;
+#endif
+	k1 = b->k;
+	n1 = n + b->wds + 1;
+	for(i = b->maxwds; n1 > i; i <<= 1)
+		k1++;
+	b1 = Balloc(k1);
+	x1 = b1->x;
+	for(i = 0; i < n; i++)
+		*x1++ = 0;
+	x = b->x;
+	xe = x + b->wds;
+#ifdef Pack_32
+	if (k &= 0x1f) {
+		k1 = 32 - k;
+		z = 0;
+		do {
+			*x1++ = *x << k | z;
+			z = *x++ >> k1;
+			}
+			while(x < xe);
+		if (*x1 = z)
+			++n1;
+		}
+#else
+	if (k &= 0xf) {
+		k1 = 16 - k;
+		z = 0;
+		do {
+			*x1++ = *x << k  & 0xffff | z;
+			z = *x++ >> k1;
+			}
+			while(x < xe);
+		if (*x1 = z)
+			++n1;
+		}
+#endif
+	else do
+		*x1++ = *x++;
+		while(x < xe);
+	b1->wds = n1 - 1;
+	Bfree(b);
+	return b1;
+	}
+
+ static int
+cmp
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	ULong *xa, *xa0, *xb, *xb0;
+	int i, j;
+
+	i = a->wds;
+	j = b->wds;
+#ifdef DEBUG
+	if (i > 1 && !a->x[i-1])
+		Bug("cmp called with a->x[a->wds-1] == 0");
+	if (j > 1 && !b->x[j-1])
+		Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+	if (i -= j)
+		return i;
+	xa0 = a->x;
+	xa = xa0 + j;
+	xb0 = b->x;
+	xb = xb0 + j;
+	for(;;) {
+		if (*--xa != *--xb)
+			return *xa < *xb ? -1 : 1;
+		if (xa <= xa0)
+			break;
+		}
+	return 0;
+	}
+
+ static Bigint *
+diff
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	Bigint *c;
+	int i, wa, wb;
+	ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef ULLong
+	ULLong borrow, y;
+#else
+	ULong borrow, y;
+#ifdef Pack_32
+	ULong z;
+#endif
+#endif
+
+	i = cmp(a,b);
+	if (!i) {
+		c = Balloc(0);
+		c->wds = 1;
+		c->x[0] = 0;
+		return c;
+		}
+	if (i < 0) {
+		c = a;
+		a = b;
+		b = c;
+		i = 1;
+		}
+	else
+		i = 0;
+	c = Balloc(a->k);
+	c->sign = i;
+	wa = a->wds;
+	xa = a->x;
+	xae = xa + wa;
+	wb = b->wds;
+	xb = b->x;
+	xbe = xb + wb;
+	xc = c->x;
+	borrow = 0;
+#ifdef ULLong
+	do {
+		y = (ULLong)*xa++ - *xb++ - borrow;
+		borrow = y >> 32 & (ULong)1;
+		*xc++ = y & FFFFFFFF;
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = *xa++ - borrow;
+		borrow = y >> 32 & (ULong)1;
+		*xc++ = y & FFFFFFFF;
+		}
+#else
+#ifdef Pack_32
+	do {
+		y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
+		borrow = (y & 0x10000) >> 16;
+		z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
+		borrow = (z & 0x10000) >> 16;
+		Storeinc(xc, z, y);
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = (*xa & 0xffff) - borrow;
+		borrow = (y & 0x10000) >> 16;
+		z = (*xa++ >> 16) - borrow;
+		borrow = (z & 0x10000) >> 16;
+		Storeinc(xc, z, y);
+		}
+#else
+	do {
+		y = *xa++ - *xb++ - borrow;
+		borrow = (y & 0x10000) >> 16;
+		*xc++ = y & 0xffff;
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = *xa++ - borrow;
+		borrow = (y & 0x10000) >> 16;
+		*xc++ = y & 0xffff;
+		}
+#endif
+#endif
+	while(!*--xc)
+		wa--;
+	c->wds = wa;
+	return c;
+	}
+
+ static double
+ulp
+#ifdef KR_headers
+	(dx) double dx;
+#else
+	(double dx)
+#endif
+{
+	register Long L;
+	U x, a;
+
+	dval(x) = dx;
+	L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+	if (L > 0) {
+#endif
+#endif
+#ifdef IBM
+		L |= Exp_msk1 >> 4;
+#endif
+		word0(a) = L;
+		word1(a) = 0;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+		}
+	else {
+		L = -L >> Exp_shift;
+		if (L < Exp_shift) {
+			word0(a) = 0x80000 >> L;
+			word1(a) = 0;
+			}
+		else {
+			word0(a) = 0;
+			L -= Exp_shift;
+			word1(a) = L >= 31 ? 1 : 1 << 31 - L;
+			}
+		}
+#endif
+#endif
+	return dval(a);
+	}
+
+ static double
+b2d
+#ifdef KR_headers
+	(a, e) Bigint *a; int *e;
+#else
+	(Bigint *a, int *e)
+#endif
+{
+	ULong *xa, *xa0, w, y, z;
+	int k;
+	U d;
+#ifdef VAX
+	ULong d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+	xa0 = a->x;
+	xa = xa0 + a->wds;
+	y = *--xa;
+#ifdef DEBUG
+	if (!y) Bug("zero y in b2d");
+#endif
+	k = hi0bits(y);
+	*e = 32 - k;
+#ifdef Pack_32
+	if (k < Ebits) {
+		d0 = Exp_1 | y >> Ebits - k;
+		w = xa > xa0 ? *--xa : 0;
+		d1 = y << (32-Ebits) + k | w >> Ebits - k;
+		goto ret_d;
+		}
+	z = xa > xa0 ? *--xa : 0;
+	if (k -= Ebits) {
+		d0 = Exp_1 | y << k | z >> 32 - k;
+		y = xa > xa0 ? *--xa : 0;
+		d1 = z << k | y >> 32 - k;
+		}
+	else {
+		d0 = Exp_1 | y;
+		d1 = z;
+		}
+#else
+	if (k < Ebits + 16) {
+		z = xa > xa0 ? *--xa : 0;
+		d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+		w = xa > xa0 ? *--xa : 0;
+		y = xa > xa0 ? *--xa : 0;
+		d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+		goto ret_d;
+		}
+	z = xa > xa0 ? *--xa : 0;
+	w = xa > xa0 ? *--xa : 0;
+	k -= Ebits + 16;
+	d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+	y = xa > xa0 ? *--xa : 0;
+	d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+	word0(d) = d0 >> 16 | d0 << 16;
+	word1(d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+	return dval(d);
+	}
+
+ static Bigint *
+d2b
+#ifdef KR_headers
+	(dd, e, bits) double dd; int *e, *bits;
+#else
+	(double dd, int *e, int *bits)
+#endif
+{
+	U d;
+	Bigint *b;
+	int de, k;
+	ULong *x, y, z;
+#ifndef Sudden_Underflow
+	int i;
+#endif
+#ifdef VAX
+	ULong d0, d1;
+#endif
+
+	dval(d) = dd;
+#ifdef VAX
+	d0 = word0(d) >> 16 | word0(d) << 16;
+	d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+	b = Balloc(1);
+#else
+	b = Balloc(2);
+#endif
+	x = b->x;
+
+	z = d0 & Frac_mask;
+	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+	de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+	z |= Exp_msk11;
+#endif
+#else
+	if (de = (int)(d0 >> Exp_shift))
+		z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+	if (y = d1) {
+		if (k = lo0bits(&y)) {
+			x[0] = y | z << 32 - k;
+			z >>= k;
+			}
+		else
+			x[0] = y;
+#ifndef Sudden_Underflow
+		i =
+#endif
+		    b->wds = (x[1] = z) ? 2 : 1;
+		}
+	else {
+		k = lo0bits(&z);
+		x[0] = z;
+#ifndef Sudden_Underflow
+		i =
+#endif
+		    b->wds = 1;
+		k += 32;
+		}
+#else
+	if (y = d1) {
+		if (k = lo0bits(&y))
+			if (k >= 16) {
+				x[0] = y | z << 32 - k & 0xffff;
+				x[1] = z >> k - 16 & 0xffff;
+				x[2] = z >> k;
+				i = 2;
+				}
+			else {
+				x[0] = y & 0xffff;
+				x[1] = y >> 16 | z << 16 - k & 0xffff;
+				x[2] = z >> k & 0xffff;
+				x[3] = z >> k+16;
+				i = 3;
+				}
+		else {
+			x[0] = y & 0xffff;
+			x[1] = y >> 16;
+			x[2] = z & 0xffff;
+			x[3] = z >> 16;
+			i = 3;
+			}
+		}
+	else {
+#ifdef DEBUG
+		if (!z)
+			Bug("Zero passed to d2b");
+#endif
+		k = lo0bits(&z);
+		if (k >= 16) {
+			x[0] = z;
+			i = 0;
+			}
+		else {
+			x[0] = z & 0xffff;
+			x[1] = z >> 16;
+			i = 1;
+			}
+		k += 32;
+		}
+	while(!x[i])
+		--i;
+	b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+	if (de) {
+#endif
+#ifdef IBM
+		*e = (de - Bias - (P-1) << 2) + k;
+		*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+		*e = de - Bias - (P-1) + k;
+		*bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+		}
+	else {
+		*e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+		*bits = 32*i - hi0bits(x[i-1]);
+#else
+		*bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+		}
+#endif
+	return b;
+	}
+#undef d0
+#undef d1
+
+ static double
+ratio
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	U da, db;
+	int k, ka, kb;
+
+	dval(da) = b2d(a, &ka);
+	dval(db) = b2d(b, &kb);
+#ifdef Pack_32
+	k = ka - kb + 32*(a->wds - b->wds);
+#else
+	k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+	if (k > 0) {
+		word0(da) += (k >> 2)*Exp_msk1;
+		if (k &= 3)
+			dval(da) *= 1 << k;
+		}
+	else {
+		k = -k;
+		word0(db) += (k >> 2)*Exp_msk1;
+		if (k &= 3)
+			dval(db) *= 1 << k;
+		}
+#else
+	if (k > 0)
+		word0(da) += k*Exp_msk1;
+	else {
+		k = -k;
+		word0(db) += k*Exp_msk1;
+		}
+#endif
+	return dval(da) / dval(db);
+	}
+
+ static CONST double
+tens[] = {
+		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+		1e20, 1e21, 1e22
+#ifdef VAX
+		, 1e23, 1e24
+#endif
+		};
+
+ static CONST double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+#ifdef Avoid_Underflow
+		9007199254740992.*9007199254740992.e-256
+		/* = 2^106 * 1e-53 */
+#else
+		1e-256
+#endif
+		};
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily.  It leads to a song and dance at the end of strtod. */
+#define Scale_Bit 0x10
+#define n_bigtens 5
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+bigtens[] = { 1e16, 1e32 };
+static CONST double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#undef INFNAN_CHECK
+#endif
+
+#ifdef INFNAN_CHECK
+
+#ifndef NAN_WORD0
+#define NAN_WORD0 0x7ff80000
+#endif
+
+#ifndef NAN_WORD1
+#define NAN_WORD1 0
+#endif
+
+ static int
+match
+#ifdef KR_headers
+	(sp, t) char **sp, *t;
+#else
+	(CONST char **sp, char *t)
+#endif
+{
+	int c, d;
+	CONST char *s = *sp;
+
+	while(d = *t++) {
+		if ((c = *++s) >= 'A' && c <= 'Z')
+			c += 'a' - 'A';
+		if (c != d)
+			return 0;
+		}
+	*sp = s + 1;
+	return 1;
+	}
+
+#ifndef No_Hex_NaN
+ static void
+hexnan
+#ifdef KR_headers
+	(rvp, sp) double *rvp; CONST char **sp;
+#else
+	(double *rvp, CONST char **sp)
+#endif
+{
+	ULong c, x[2];
+	CONST char *s;
+	int havedig, udx0, xshift;
+
+	x[0] = x[1] = 0;
+	havedig = xshift = 0;
+	udx0 = 1;
+	s = *sp;
+	while(c = *(CONST unsigned char*)++s) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'a' && c <= 'f')
+			c += 10 - 'a';
+		else if (c >= 'A' && c <= 'F')
+			c += 10 - 'A';
+		else if (c <= ' ') {
+			if (udx0 && havedig) {
+				udx0 = 0;
+				xshift = 1;
+				}
+			continue;
+			}
+		else if (/*(*/ c == ')' && havedig) {
+			*sp = s + 1;
+			break;
+			}
+		else
+			return;	/* invalid form: don't change *sp */
+		havedig = 1;
+		if (xshift) {
+			xshift = 0;
+			x[0] = x[1];
+			x[1] = 0;
+			}
+		if (udx0)
+			x[0] = (x[0] << 4) | (x[1] >> 28);
+		x[1] = (x[1] << 4) | c;
+		}
+	if ((x[0] &= 0xfffff) || x[1]) {
+		word0(*rvp) = Exp_mask | x[0];
+		word1(*rvp) = x[1];
+		}
+	}
+#endif /*No_Hex_NaN*/
+#endif /* INFNAN_CHECK */
+
+ PR_IMPLEMENT(double)
+PR_strtod
+#ifdef KR_headers
+	(s00, se) CONST char *s00; char **se;
+#else
+	(CONST char *s00, char **se)
+#endif
+{
+#ifdef Avoid_Underflow
+	int scale;
+#endif
+	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+	CONST char *s, *s0, *s1;
+	double aadj, aadj1, adj;
+	U aadj2, rv, rv0;
+	Long L;
+	ULong y, z;
+	Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+#ifdef SET_INEXACT
+	int inexact, oldinexact;
+#endif
+#ifdef Honor_FLT_ROUNDS
+	int rounding;
+#endif
+#ifdef USE_LOCALE
+	CONST char *s2;
+#endif
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	sign = nz0 = nz = 0;
+	dval(rv) = 0.;
+	for(s = s00;;s++) switch(*s) {
+		case '-':
+			sign = 1;
+			/* no break */
+		case '+':
+			if (*++s)
+				goto break2;
+			/* no break */
+		case 0:
+			goto ret0;
+		case '\t':
+		case '\n':
+		case '\v':
+		case '\f':
+		case '\r':
+		case ' ':
+			continue;
+		default:
+			goto break2;
+		}
+ break2:
+	if (*s == '0') {
+		nz0 = 1;
+		while(*++s == '0') ;
+		if (!*s)
+			goto ret;
+		}
+	s0 = s;
+	y = z = 0;
+	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+		if (nd < 9)
+			y = 10*y + c - '0';
+		else if (nd < 16)
+			z = 10*z + c - '0';
+	nd0 = nd;
+#ifdef USE_LOCALE
+	s1 = localeconv()->decimal_point;
+	if (c == *s1) {
+		c = '.';
+		if (*++s1) {
+			s2 = s;
+			for(;;) {
+				if (*++s2 != *s1) {
+					c = 0;
+					break;
+					}
+				if (!*++s1) {
+					s = s2;
+					break;
+					}
+				}
+			}
+		}
+#endif
+	if (c == '.') {
+		c = *++s;
+		if (!nd) {
+			for(; c == '0'; c = *++s)
+				nz++;
+			if (c > '0' && c <= '9') {
+				s0 = s;
+				nf += nz;
+				nz = 0;
+				goto have_dig;
+				}
+			goto dig_done;
+			}
+		for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+			nz++;
+			if (c -= '0') {
+				nf += nz;
+				for(i = 1; i < nz; i++)
+					if (nd++ < 9)
+						y *= 10;
+					else if (nd <= DBL_DIG + 1)
+						z *= 10;
+				if (nd++ < 9)
+					y = 10*y + c;
+				else if (nd <= DBL_DIG + 1)
+					z = 10*z + c;
+				nz = 0;
+				}
+			}
+		}
+ dig_done:
+	if (nd > 64 * 1024)
+		goto ret0;
+	e = 0;
+	if (c == 'e' || c == 'E') {
+		if (!nd && !nz && !nz0) {
+			goto ret0;
+			}
+		s00 = s;
+		esign = 0;
+		switch(c = *++s) {
+			case '-':
+				esign = 1;
+			case '+':
+				c = *++s;
+			}
+		if (c >= '0' && c <= '9') {
+			while(c == '0')
+				c = *++s;
+			if (c > '0' && c <= '9') {
+				L = c - '0';
+				s1 = s;
+				while((c = *++s) >= '0' && c <= '9')
+					L = 10*L + c - '0';
+				if (s - s1 > 8 || L > 19999)
+					/* Avoid confusion from exponents
+					 * so large that e might overflow.
+					 */
+					e = 19999; /* safe for 16 bit ints */
+				else
+					e = (int)L;
+				if (esign)
+					e = -e;
+				}
+			else
+				e = 0;
+			}
+		else
+			s = s00;
+		}
+	if (!nd) {
+		if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+			/* Check for Nan and Infinity */
+			switch(c) {
+			  case 'i':
+			  case 'I':
+				if (match(&s,"nf")) {
+					--s;
+					if (!match(&s,"inity"))
+						++s;
+					word0(rv) = 0x7ff00000;
+					word1(rv) = 0;
+					goto ret;
+					}
+				break;
+			  case 'n':
+			  case 'N':
+				if (match(&s, "an")) {
+					word0(rv) = NAN_WORD0;
+					word1(rv) = NAN_WORD1;
+#ifndef No_Hex_NaN
+					if (*s == '(') /*)*/
+						hexnan(&rv, &s);
+#endif
+					goto ret;
+					}
+			  }
+#endif /* INFNAN_CHECK */
+ ret0:
+			s = s00;
+			sign = 0;
+			}
+		goto ret;
+		}
+	e1 = e -= nf;
+
+	/* Now we have nd0 digits, starting at s0, followed by a
+	 * decimal point, followed by nd-nd0 digits.  The number we're
+	 * after is the integer represented by those digits times
+	 * 10**e */
+
+	if (!nd0)
+		nd0 = nd;
+	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+	dval(rv) = y;
+	if (k > 9) {
+#ifdef SET_INEXACT
+		if (k > DBL_DIG)
+			oldinexact = get_inexact();
+#endif
+		dval(rv) = tens[k - 9] * dval(rv) + z;
+		}
+	bd0 = 0;
+	if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+#ifndef Honor_FLT_ROUNDS
+		&& Flt_Rounds == 1
+#endif
+#endif
+			) {
+		if (!e)
+			goto ret;
+		if (e > 0) {
+			if (e <= Ten_pmax) {
+#ifdef VAX
+				goto vax_ovfl_check;
+#else
+#ifdef Honor_FLT_ROUNDS
+				/* round correctly FLT_ROUNDS = 2 or 3 */
+				if (sign) {
+					rv = -rv;
+					sign = 0;
+					}
+#endif
+				/* rv = */ rounded_product(dval(rv), tens[e]);
+				goto ret;
+#endif
+				}
+			i = DBL_DIG - nd;
+			if (e <= Ten_pmax + i) {
+				/* A fancier test would sometimes let us do
+				 * this for larger i values.
+				 */
+#ifdef Honor_FLT_ROUNDS
+				/* round correctly FLT_ROUNDS = 2 or 3 */
+				if (sign) {
+					rv = -rv;
+					sign = 0;
+					}
+#endif
+				e -= i;
+				dval(rv) *= tens[i];
+#ifdef VAX
+				/* VAX exponent range is so narrow we must
+				 * worry about overflow here...
+				 */
+ vax_ovfl_check:
+				word0(rv) -= P*Exp_msk1;
+				/* rv = */ rounded_product(dval(rv), tens[e]);
+				if ((word0(rv) & Exp_mask)
+				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+					goto ovfl;
+				word0(rv) += P*Exp_msk1;
+#else
+				/* rv = */ rounded_product(dval(rv), tens[e]);
+#endif
+				goto ret;
+				}
+			}
+#ifndef Inaccurate_Divide
+		else if (e >= -Ten_pmax) {
+#ifdef Honor_FLT_ROUNDS
+			/* round correctly FLT_ROUNDS = 2 or 3 */
+			if (sign) {
+				rv = -rv;
+				sign = 0;
+				}
+#endif
+			/* rv = */ rounded_quotient(dval(rv), tens[-e]);
+			goto ret;
+			}
+#endif
+		}
+	e1 += nd - k;
+
+#ifdef IEEE_Arith
+#ifdef SET_INEXACT
+	inexact = 1;
+	if (k <= DBL_DIG)
+		oldinexact = get_inexact();
+#endif
+#ifdef Avoid_Underflow
+	scale = 0;
+#endif
+#ifdef Honor_FLT_ROUNDS
+	if ((rounding = Flt_Rounds) >= 2) {
+		if (sign)
+			rounding = rounding == 2 ? 0 : 2;
+		else
+			if (rounding != 2)
+				rounding = 0;
+		}
+#endif
+#endif /*IEEE_Arith*/
+
+	/* Get starting approximation = rv * 10**e1 */
+
+	if (e1 > 0) {
+		if (i = e1 & 15)
+			dval(rv) *= tens[i];
+		if (e1 &= ~15) {
+			if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+#ifndef NO_ERRNO
+				PR_SetError(PR_RANGE_ERROR, 0);
+#endif
+				/* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+#ifdef Honor_FLT_ROUNDS
+				switch(rounding) {
+				  case 0: /* toward 0 */
+				  case 3: /* toward -infinity */
+					word0(rv) = Big0;
+					word1(rv) = Big1;
+					break;
+				  default:
+					word0(rv) = Exp_mask;
+					word1(rv) = 0;
+				  }
+#else /*Honor_FLT_ROUNDS*/
+				word0(rv) = Exp_mask;
+				word1(rv) = 0;
+#endif /*Honor_FLT_ROUNDS*/
+#ifdef SET_INEXACT
+				/* set overflow bit */
+				dval(rv0) = 1e300;
+				dval(rv0) *= dval(rv0);
+#endif
+#else /*IEEE_Arith*/
+				word0(rv) = Big0;
+				word1(rv) = Big1;
+#endif /*IEEE_Arith*/
+				if (bd0)
+					goto retfree;
+				goto ret;
+				}
+			e1 >>= 4;
+			for(j = 0; e1 > 1; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(rv) *= bigtens[j];
+		/* The last multiplication could overflow. */
+			word0(rv) -= P*Exp_msk1;
+			dval(rv) *= bigtens[j];
+			if ((z = word0(rv) & Exp_mask)
+			 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+				goto ovfl;
+			if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+				/* set to largest number */
+				/* (Can't trust DBL_MAX) */
+				word0(rv) = Big0;
+				word1(rv) = Big1;
+				}
+			else
+				word0(rv) += P*Exp_msk1;
+			}
+		}
+	else if (e1 < 0) {
+		e1 = -e1;
+		if (i = e1 & 15)
+			dval(rv) /= tens[i];
+		if (e1 >>= 4) {
+			if (e1 >= 1 << n_bigtens)
+				goto undfl;
+#ifdef Avoid_Underflow
+			if (e1 & Scale_Bit)
+				scale = 2*P;
+			for(j = 0; e1 > 0; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(rv) *= tinytens[j];
+			if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
+						>> Exp_shift)) > 0) {
+				/* scaled rv is denormal; zap j low bits */
+				if (j >= 32) {
+					word1(rv) = 0;
+					if (j >= 53)
+					 word0(rv) = (P+2)*Exp_msk1;
+					else
+					 word0(rv) &= 0xffffffff << j-32;
+					}
+				else
+					word1(rv) &= 0xffffffff << j;
+				}
+#else
+			for(j = 0; e1 > 1; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(rv) *= tinytens[j];
+			/* The last multiplication could underflow. */
+			dval(rv0) = dval(rv);
+			dval(rv) *= tinytens[j];
+			if (!dval(rv)) {
+				dval(rv) = 2.*dval(rv0);
+				dval(rv) *= tinytens[j];
+#endif
+				if (!dval(rv)) {
+ undfl:
+					dval(rv) = 0.;
+#ifndef NO_ERRNO
+					PR_SetError(PR_RANGE_ERROR, 0);
+#endif
+					if (bd0)
+						goto retfree;
+					goto ret;
+					}
+#ifndef Avoid_Underflow
+				word0(rv) = Tiny0;
+				word1(rv) = Tiny1;
+				/* The refinement below will clean
+				 * this approximation up.
+				 */
+				}
+#endif
+			}
+		}
+
+	/* Now the hard part -- adjusting rv to the correct value.*/
+
+	/* Put digits into bd: true value = bd * 10^e */
+
+	bd0 = s2b(s0, nd0, nd, y);
+
+	for(;;) {
+		bd = Balloc(bd0->k);
+		Bcopy(bd, bd0);
+		bb = d2b(dval(rv), &bbe, &bbbits);	/* rv = bb * 2^bbe */
+		bs = i2b(1);
+
+		if (e >= 0) {
+			bb2 = bb5 = 0;
+			bd2 = bd5 = e;
+			}
+		else {
+			bb2 = bb5 = -e;
+			bd2 = bd5 = 0;
+			}
+		if (bbe >= 0)
+			bb2 += bbe;
+		else
+			bd2 -= bbe;
+		bs2 = bb2;
+#ifdef Honor_FLT_ROUNDS
+		if (rounding != 1)
+			bs2++;
+#endif
+#ifdef Avoid_Underflow
+		j = bbe - scale;
+		i = j + bbbits - 1;	/* logb(rv) */
+		if (i < Emin)	/* denormal */
+			j += P - Emin;
+		else
+			j = P + 1 - bbbits;
+#else /*Avoid_Underflow*/
+#ifdef Sudden_Underflow
+#ifdef IBM
+		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+		j = P + 1 - bbbits;
+#endif
+#else /*Sudden_Underflow*/
+		j = bbe;
+		i = j + bbbits - 1;	/* logb(rv) */
+		if (i < Emin)	/* denormal */
+			j += P - Emin;
+		else
+			j = P + 1 - bbbits;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+		bb2 += j;
+		bd2 += j;
+#ifdef Avoid_Underflow
+		bd2 += scale;
+#endif
+		i = bb2 < bd2 ? bb2 : bd2;
+		if (i > bs2)
+			i = bs2;
+		if (i > 0) {
+			bb2 -= i;
+			bd2 -= i;
+			bs2 -= i;
+			}
+		if (bb5 > 0) {
+			bs = pow5mult(bs, bb5);
+			bb1 = mult(bs, bb);
+			Bfree(bb);
+			bb = bb1;
+			}
+		if (bb2 > 0)
+			bb = lshift(bb, bb2);
+		if (bd5 > 0)
+			bd = pow5mult(bd, bd5);
+		if (bd2 > 0)
+			bd = lshift(bd, bd2);
+		if (bs2 > 0)
+			bs = lshift(bs, bs2);
+		delta = diff(bb, bd);
+		dsign = delta->sign;
+		delta->sign = 0;
+		i = cmp(delta, bs);
+#ifdef Honor_FLT_ROUNDS
+		if (rounding != 1) {
+			if (i < 0) {
+				/* Error is less than an ulp */
+				if (!delta->x[0] && delta->wds <= 1) {
+					/* exact */
+#ifdef SET_INEXACT
+					inexact = 0;
+#endif
+					break;
+					}
+				if (rounding) {
+					if (dsign) {
+						adj = 1.;
+						goto apply_adj;
+						}
+					}
+				else if (!dsign) {
+					adj = -1.;
+					if (!word1(rv)
+					 && !(word0(rv) & Frac_mask)) {
+						y = word0(rv) & Exp_mask;
+#ifdef Avoid_Underflow
+						if (!scale || y > 2*P*Exp_msk1)
+#else
+						if (y)
+#endif
+						  {
+						  delta = lshift(delta,Log2P);
+						  if (cmp(delta, bs) <= 0)
+							adj = -0.5;
+						  }
+						}
+ apply_adj:
+#ifdef Avoid_Underflow
+					if (scale && (y = word0(rv) & Exp_mask)
+						<= 2*P*Exp_msk1)
+					  word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+					if ((word0(rv) & Exp_mask) <=
+							P*Exp_msk1) {
+						word0(rv) += P*Exp_msk1;
+						dval(rv) += adj*ulp(dval(rv));
+						word0(rv) -= P*Exp_msk1;
+						}
+					else
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+					dval(rv) += adj*ulp(dval(rv));
+					}
+				break;
+				}
+			adj = ratio(delta, bs);
+			if (adj < 1.)
+				adj = 1.;
+			if (adj <= 0x7ffffffe) {
+				/* adj = rounding ? ceil(adj) : floor(adj); */
+				y = adj;
+				if (y != adj) {
+					if (!((rounding>>1) ^ dsign))
+						y++;
+					adj = y;
+					}
+				}
+#ifdef Avoid_Underflow
+			if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+				word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+				word0(rv) += P*Exp_msk1;
+				adj *= ulp(dval(rv));
+				if (dsign)
+					dval(rv) += adj;
+				else
+					dval(rv) -= adj;
+				word0(rv) -= P*Exp_msk1;
+				goto cont;
+				}
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+			adj *= ulp(dval(rv));
+			if (dsign)
+				dval(rv) += adj;
+			else
+				dval(rv) -= adj;
+			goto cont;
+			}
+#endif /*Honor_FLT_ROUNDS*/
+
+		if (i < 0) {
+			/* Error is less than half an ulp -- check for
+			 * special case of mantissa a power of two.
+			 */
+			if (dsign || word1(rv) || word0(rv) & Bndry_mask
+#ifdef IEEE_Arith
+#ifdef Avoid_Underflow
+			 || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+#else
+			 || (word0(rv) & Exp_mask) <= Exp_msk1
+#endif
+#endif
+				) {
+#ifdef SET_INEXACT
+				if (!delta->x[0] && delta->wds <= 1)
+					inexact = 0;
+#endif
+				break;
+				}
+			if (!delta->x[0] && delta->wds <= 1) {
+				/* exact result */
+#ifdef SET_INEXACT
+				inexact = 0;
+#endif
+				break;
+				}
+			delta = lshift(delta,Log2P);
+			if (cmp(delta, bs) > 0)
+				goto drop_down;
+			break;
+			}
+		if (i == 0) {
+			/* exactly half-way between */
+			if (dsign) {
+				if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+				 &&  word1(rv) == (
+#ifdef Avoid_Underflow
+			(scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+		? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
+#endif
+						   0xffffffff)) {
+					/*boundary case -- increment exponent*/
+					word0(rv) = (word0(rv) & Exp_mask)
+						+ Exp_msk1
+#ifdef IBM
+						| Exp_msk1 >> 4
+#endif
+						;
+					word1(rv) = 0;
+#ifdef Avoid_Underflow
+					dsign = 0;
+#endif
+					break;
+					}
+				}
+			else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+				/* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow /*{{*/
+				L = word0(rv) & Exp_mask;
+#ifdef IBM
+				if (L <  Exp_msk1)
+#else
+#ifdef Avoid_Underflow
+				if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
+#else
+				if (L <= Exp_msk1)
+#endif /*Avoid_Underflow*/
+#endif /*IBM*/
+					goto undfl;
+				L -= Exp_msk1;
+#else /*Sudden_Underflow}{*/
+#ifdef Avoid_Underflow
+				if (scale) {
+					L = word0(rv) & Exp_mask;
+					if (L <= (2*P+1)*Exp_msk1) {
+						if (L > (P+2)*Exp_msk1)
+							/* round even ==> */
+							/* accept rv */
+							break;
+						/* rv = smallest denormal */
+						goto undfl;
+						}
+					}
+#endif /*Avoid_Underflow*/
+				L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif /*Sudden_Underflow}}*/
+				word0(rv) = L | Bndry_mask1;
+				word1(rv) = 0xffffffff;
+#ifdef IBM
+				goto cont;
+#else
+				break;
+#endif
+				}
+#ifndef ROUND_BIASED
+			if (!(word1(rv) & LSB))
+				break;
+#endif
+			if (dsign)
+				dval(rv) += ulp(dval(rv));
+#ifndef ROUND_BIASED
+			else {
+				dval(rv) -= ulp(dval(rv));
+#ifndef Sudden_Underflow
+				if (!dval(rv))
+					goto undfl;
+#endif
+				}
+#ifdef Avoid_Underflow
+			dsign = 1 - dsign;
+#endif
+#endif
+			break;
+			}
+		if ((aadj = ratio(delta, bs)) <= 2.) {
+			if (dsign)
+				aadj = aadj1 = 1.;
+			else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+				if (word1(rv) == Tiny1 && !word0(rv))
+					goto undfl;
+#endif
+				aadj = 1.;
+				aadj1 = -1.;
+				}
+			else {
+				/* special case -- power of FLT_RADIX to be */
+				/* rounded down... */
+
+				if (aadj < 2./FLT_RADIX)
+					aadj = 1./FLT_RADIX;
+				else
+					aadj *= 0.5;
+				aadj1 = -aadj;
+				}
+			}
+		else {
+			aadj *= 0.5;
+			aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+			switch(Rounding) {
+				case 2: /* towards +infinity */
+					aadj1 -= 0.5;
+					break;
+				case 0: /* towards 0 */
+				case 3: /* towards -infinity */
+					aadj1 += 0.5;
+				}
+#else
+			if (Flt_Rounds == 0)
+				aadj1 += 0.5;
+#endif /*Check_FLT_ROUNDS*/
+			}
+		y = word0(rv) & Exp_mask;
+
+		/* Check for overflow */
+
+		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+			dval(rv0) = dval(rv);
+			word0(rv) -= P*Exp_msk1;
+			adj = aadj1 * ulp(dval(rv));
+			dval(rv) += adj;
+			if ((word0(rv) & Exp_mask) >=
+					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+				if (word0(rv0) == Big0 && word1(rv0) == Big1)
+					goto ovfl;
+				word0(rv) = Big0;
+				word1(rv) = Big1;
+				goto cont;
+				}
+			else
+				word0(rv) += P*Exp_msk1;
+			}
+		else {
+#ifdef Avoid_Underflow
+			if (scale && y <= 2*P*Exp_msk1) {
+				if (aadj <= 0x7fffffff) {
+					if ((z = aadj) <= 0)
+						z = 1;
+					aadj = z;
+					aadj1 = dsign ? aadj : -aadj;
+					}
+				dval(aadj2) = aadj1;
+				word0(aadj2) += (2*P+1)*Exp_msk1 - y;
+				aadj1 = dval(aadj2);
+				}
+			adj = aadj1 * ulp(dval(rv));
+			dval(rv) += adj;
+#else
+#ifdef Sudden_Underflow
+			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+				dval(rv0) = dval(rv);
+				word0(rv) += P*Exp_msk1;
+				adj = aadj1 * ulp(dval(rv));
+				dval(rv) += adj;
+#ifdef IBM
+				if ((word0(rv) & Exp_mask) <  P*Exp_msk1)
+#else
+				if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+					{
+					if (word0(rv0) == Tiny0
+					 && word1(rv0) == Tiny1)
+						goto undfl;
+					word0(rv) = Tiny0;
+					word1(rv) = Tiny1;
+					goto cont;
+					}
+				else
+					word0(rv) -= P*Exp_msk1;
+				}
+			else {
+				adj = aadj1 * ulp(dval(rv));
+				dval(rv) += adj;
+				}
+#else /*Sudden_Underflow*/
+			/* Compute adj so that the IEEE rounding rules will
+			 * correctly round rv + adj in some half-way cases.
+			 * If rv * ulp(rv) is denormalized (i.e.,
+			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+			 * trouble from bits lost to denormalization;
+			 * example: 1.2e-307 .
+			 */
+			if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
+				aadj1 = (double)(int)(aadj + 0.5);
+				if (!dsign)
+					aadj1 = -aadj1;
+				}
+			adj = aadj1 * ulp(dval(rv));
+			dval(rv) += adj;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+			}
+		z = word0(rv) & Exp_mask;
+#ifndef SET_INEXACT
+#ifdef Avoid_Underflow
+		if (!scale)
+#endif
+		if (y == z) {
+			/* Can we stop now? */
+			L = (Long)aadj;
+			aadj -= L;
+			/* The tolerances below are conservative. */
+			if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+				if (aadj < .4999999 || aadj > .5000001)
+					break;
+				}
+			else if (aadj < .4999999/FLT_RADIX)
+				break;
+			}
+#endif
+ cont:
+		Bfree(bb);
+		Bfree(bd);
+		Bfree(bs);
+		Bfree(delta);
+		}
+#ifdef SET_INEXACT
+	if (inexact) {
+		if (!oldinexact) {
+			word0(rv0) = Exp_1 + (70 << Exp_shift);
+			word1(rv0) = 0;
+			dval(rv0) += 1.;
+			}
+		}
+	else if (!oldinexact)
+		clear_inexact();
+#endif
+#ifdef Avoid_Underflow
+	if (scale) {
+		word0(rv0) = Exp_1 - 2*P*Exp_msk1;
+		word1(rv0) = 0;
+		dval(rv) *= dval(rv0);
+#ifndef NO_ERRNO
+		/* try to avoid the bug of testing an 8087 register value */
+		if (word0(rv) == 0 && word1(rv) == 0)
+			PR_SetError(PR_RANGE_ERROR, 0);
+#endif
+		}
+#endif /* Avoid_Underflow */
+#ifdef SET_INEXACT
+	if (inexact && !(word0(rv) & Exp_mask)) {
+		/* set underflow bit */
+		dval(rv0) = 1e-300;
+		dval(rv0) *= dval(rv0);
+		}
+#endif
+ retfree:
+	Bfree(bb);
+	Bfree(bd);
+	Bfree(bs);
+	Bfree(bd0);
+	Bfree(delta);
+ ret:
+	if (se)
+		*se = (char *)s;
+	return sign ? -dval(rv) : dval(rv);
+	}
+
+ static int
+quorem
+#ifdef KR_headers
+	(b, S) Bigint *b, *S;
+#else
+	(Bigint *b, Bigint *S)
+#endif
+{
+	int n;
+	ULong *bx, *bxe, q, *sx, *sxe;
+#ifdef ULLong
+	ULLong borrow, carry, y, ys;
+#else
+	ULong borrow, carry, y, ys;
+#ifdef Pack_32
+	ULong si, z, zs;
+#endif
+#endif
+
+	n = S->wds;
+#ifdef DEBUG
+	/*debug*/ if (b->wds > n)
+	/*debug*/	Bug("oversize b in quorem");
+#endif
+	if (b->wds < n)
+		return 0;
+	sx = S->x;
+	sxe = sx + --n;
+	bx = b->x;
+	bxe = bx + n;
+	q = *bxe / (*sxe + 1);	/* ensure q <= true quotient */
+#ifdef DEBUG
+	/*debug*/ if (q > 9)
+	/*debug*/	Bug("oversized quotient in quorem");
+#endif
+	if (q) {
+		borrow = 0;
+		carry = 0;
+		do {
+#ifdef ULLong
+			ys = *sx++ * (ULLong)q + carry;
+			carry = ys >> 32;
+			y = *bx - (ys & FFFFFFFF) - borrow;
+			borrow = y >> 32 & (ULong)1;
+			*bx++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+			si = *sx++;
+			ys = (si & 0xffff) * q + carry;
+			zs = (si >> 16) * q + (ys >> 16);
+			carry = zs >> 16;
+			y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			z = (*bx >> 16) - (zs & 0xffff) - borrow;
+			borrow = (z & 0x10000) >> 16;
+			Storeinc(bx, z, y);
+#else
+			ys = *sx++ * q + carry;
+			carry = ys >> 16;
+			y = *bx - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			*bx++ = y & 0xffff;
+#endif
+#endif
+			}
+			while(sx <= sxe);
+		if (!*bxe) {
+			bx = b->x;
+			while(--bxe > bx && !*bxe)
+				--n;
+			b->wds = n;
+			}
+		}
+	if (cmp(b, S) >= 0) {
+		q++;
+		borrow = 0;
+		carry = 0;
+		bx = b->x;
+		sx = S->x;
+		do {
+#ifdef ULLong
+			ys = *sx++ + carry;
+			carry = ys >> 32;
+			y = *bx - (ys & FFFFFFFF) - borrow;
+			borrow = y >> 32 & (ULong)1;
+			*bx++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+			si = *sx++;
+			ys = (si & 0xffff) + carry;
+			zs = (si >> 16) + (ys >> 16);
+			carry = zs >> 16;
+			y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			z = (*bx >> 16) - (zs & 0xffff) - borrow;
+			borrow = (z & 0x10000) >> 16;
+			Storeinc(bx, z, y);
+#else
+			ys = *sx++ + carry;
+			carry = ys >> 16;
+			y = *bx - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			*bx++ = y & 0xffff;
+#endif
+#endif
+			}
+			while(sx <= sxe);
+		bx = b->x;
+		bxe = bx + n;
+		if (!*bxe) {
+			while(--bxe > bx && !*bxe)
+				--n;
+			b->wds = n;
+			}
+		}
+	return q;
+	}
+
+#ifndef MULTIPLE_THREADS
+ static char *dtoa_result;
+#endif
+
+ static char *
+#ifdef KR_headers
+rv_alloc(i) int i;
+#else
+rv_alloc(int i)
+#endif
+{
+	int j, k, *r;
+
+	j = sizeof(ULong);
+	for(k = 0;
+		sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
+		j <<= 1)
+			k++;
+	r = (int*)Balloc(k);
+	*r = k;
+	return
+#ifndef MULTIPLE_THREADS
+	dtoa_result =
+#endif
+		(char *)(r+1);
+	}
+
+ static char *
+#ifdef KR_headers
+nrv_alloc(s, rve, n) char *s, **rve; int n;
+#else
+nrv_alloc(char *s, char **rve, int n)
+#endif
+{
+	char *rv, *t;
+
+	t = rv = rv_alloc(n);
+	while(*t = *s++) t++;
+	if (rve)
+		*rve = t;
+	return rv;
+	}
+
+/* freedtoa(s) must be used to free values s returned by dtoa
+ * when MULTIPLE_THREADS is #defined.  It should be used in all cases,
+ * but for consistency with earlier versions of dtoa, it is optional
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+ static void
+#ifdef KR_headers
+freedtoa(s) char *s;
+#else
+freedtoa(char *s)
+#endif
+{
+	Bigint *b = (Bigint *)((int *)s - 1);
+	b->maxwds = 1 << (b->k = *(int*)b);
+	Bfree(b);
+#ifndef MULTIPLE_THREADS
+	if (s == dtoa_result)
+		dtoa_result = 0;
+#endif
+	}
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ *	1. Rather than iterating, we use a simple numeric overestimate
+ *	   to determine k = floor(log10(d)).  We scale relevant
+ *	   quantities using O(log2(k)) rather than O(k) multiplications.
+ *	2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ *	   try to generate digits strictly left to right.  Instead, we
+ *	   compute with fewer bits and propagate the carry if necessary
+ *	   when rounding the final digit up.  This is often faster.
+ *	3. Under the assumption that input will be rounded nearest,
+ *	   mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ *	   That is, we allow equality in stopping tests when the
+ *	   round-nearest rule will give the same floating-point value
+ *	   as would satisfaction of the stopping test with strict
+ *	   inequality.
+ *	4. We remove common factors of powers of 2 from relevant
+ *	   quantities.
+ *	5. When converting floating-point integers less than 1e16,
+ *	   we use floating-point arithmetic rather than resorting
+ *	   to multiple-precision integers.
+ *	6. When asked to produce fewer than 15 digits, we first try
+ *	   to get by with floating-point arithmetic; we resort to
+ *	   multiple-precision integer arithmetic only if we cannot
+ *	   guarantee that the floating-point calculation has given
+ *	   the correctly rounded result.  For k requested digits and
+ *	   "uniformly" distributed input, the probability is
+ *	   something like 10^(k-15) that we must resort to the Long
+ *	   calculation.
+ */
+
+ static char *
+dtoa
+#ifdef KR_headers
+	(dd, mode, ndigits, decpt, sign, rve)
+	double dd; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+	(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /*	Arguments ndigits, decpt, sign are similar to those
+	of ecvt and fcvt; trailing zeros are suppressed from
+	the returned string.  If not null, *rve is set to point
+	to the end of the return value.  If d is +-Infinity or NaN,
+	then *decpt is set to 9999.
+
+	mode:
+		0 ==> shortest string that yields d when read in
+			and rounded to nearest.
+		1 ==> like 0, but with Steele & White stopping rule;
+			e.g. with IEEE P754 arithmetic , mode 0 gives
+			1e23 whereas mode 1 gives 9.999999999999999e22.
+		2 ==> max(1,ndigits) significant digits.  This gives a
+			return value similar to that of ecvt, except
+			that trailing zeros are suppressed.
+		3 ==> through ndigits past the decimal point.  This
+			gives a return value similar to that from fcvt,
+			except that trailing zeros are suppressed, and
+			ndigits can be negative.
+		4,5 ==> similar to 2 and 3, respectively, but (in
+			round-nearest mode) with the tests of mode 0 to
+			possibly return a shorter string that rounds to d.
+			With IEEE arithmetic and compilation with
+			-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+			as modes 2 and 3 when FLT_ROUNDS != 1.
+		6-9 ==> Debugging modes similar to mode - 4:  don't try
+			fast floating-point estimate (if applicable).
+
+		Values of mode other than 0-9 are treated as mode 0.
+
+		Sufficient space is allocated to the return value
+		to hold the suppressed trailing zeros.
+	*/
+
+	int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+		j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+		spec_case, try_quick;
+	Long L;
+#ifndef Sudden_Underflow
+	int denorm;
+	ULong x;
+#endif
+	Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+	U d, d2, eps;
+	double ds;
+	char *s, *s0;
+#ifdef Honor_FLT_ROUNDS
+	int rounding;
+#endif
+#ifdef SET_INEXACT
+	int inexact, oldinexact;
+#endif
+
+#ifndef MULTIPLE_THREADS
+	if (dtoa_result) {
+		freedtoa(dtoa_result);
+		dtoa_result = 0;
+		}
+#endif
+
+	dval(d) = dd;
+	if (word0(d) & Sign_bit) {
+		/* set sign for everything, including 0's and NaNs */
+		*sign = 1;
+		word0(d) &= ~Sign_bit;	/* clear sign bit */
+		}
+	else
+		*sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+	if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+	if (word0(d)  == 0x8000)
+#endif
+		{
+		/* Infinity or NaN */
+		*decpt = 9999;
+#ifdef IEEE_Arith
+		if (!word1(d) && !(word0(d) & 0xfffff))
+			return nrv_alloc("Infinity", rve, 8);
+#endif
+		return nrv_alloc("NaN", rve, 3);
+		}
+#endif
+#ifdef IBM
+	dval(d) += 0; /* normalize */
+#endif
+	if (!dval(d)) {
+		*decpt = 1;
+		return nrv_alloc("0", rve, 1);
+		}
+
+#ifdef SET_INEXACT
+	try_quick = oldinexact = get_inexact();
+	inexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+	if ((rounding = Flt_Rounds) >= 2) {
+		if (*sign)
+			rounding = rounding == 2 ? 0 : 2;
+		else
+			if (rounding != 2)
+				rounding = 0;
+		}
+#endif
+
+	b = d2b(dval(d), &be, &bbits);
+#ifdef Sudden_Underflow
+	i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+	if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
+#endif
+		dval(d2) = dval(d);
+		word0(d2) &= Frac_mask1;
+		word0(d2) |= Exp_11;
+#ifdef IBM
+		if (j = 11 - hi0bits(word0(d2) & Frac_mask))
+			dval(d2) /= 1 << j;
+#endif
+
+		/* log(x)	~=~ log(1.5) + (x-1.5)/1.5
+		 * log10(x)	 =  log(x) / log(10)
+		 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+		 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+		 *
+		 * This suggests computing an approximation k to log10(d) by
+		 *
+		 * k = (i - Bias)*0.301029995663981
+		 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+		 *
+		 * We want k to be too large rather than too small.
+		 * The error in the first-order Taylor series approximation
+		 * is in our favor, so we just round up the constant enough
+		 * to compensate for any error in the multiplication of
+		 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+		 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+		 * adding 1e-13 to the constant term more than suffices.
+		 * Hence we adjust the constant term to 0.1760912590558.
+		 * (We could get a more accurate k by invoking log10,
+		 *  but this is probably not worthwhile.)
+		 */
+
+		i -= Bias;
+#ifdef IBM
+		i <<= 2;
+		i += j;
+#endif
+#ifndef Sudden_Underflow
+		denorm = 0;
+		}
+	else {
+		/* d is denormalized */
+
+		i = bbits + be + (Bias + (P-1) - 1);
+		x = i > 32  ? word0(d) << 64 - i | word1(d) >> i - 32
+			    : word1(d) << 32 - i;
+		dval(d2) = x;
+		word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+		i -= (Bias + (P-1) - 1) + 1;
+		denorm = 1;
+		}
+#endif
+	ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+	k = (int)ds;
+	if (ds < 0. && ds != k)
+		k--;	/* want k = floor(ds) */
+	k_check = 1;
+	if (k >= 0 && k <= Ten_pmax) {
+		if (dval(d) < tens[k])
+			k--;
+		k_check = 0;
+		}
+	j = bbits - i - 1;
+	if (j >= 0) {
+		b2 = 0;
+		s2 = j;
+		}
+	else {
+		b2 = -j;
+		s2 = 0;
+		}
+	if (k >= 0) {
+		b5 = 0;
+		s5 = k;
+		s2 += k;
+		}
+	else {
+		b2 -= k;
+		b5 = -k;
+		s5 = 0;
+		}
+	if (mode < 0 || mode > 9)
+		mode = 0;
+
+#ifndef SET_INEXACT
+#ifdef Check_FLT_ROUNDS
+	try_quick = Rounding == 1;
+#else
+	try_quick = 1;
+#endif
+#endif /*SET_INEXACT*/
+
+	if (mode > 5) {
+		mode -= 4;
+		try_quick = 0;
+		}
+	leftright = 1;
+	switch(mode) {
+		case 0:
+		case 1:
+			ilim = ilim1 = -1;
+			i = 18;
+			ndigits = 0;
+			break;
+		case 2:
+			leftright = 0;
+			/* no break */
+		case 4:
+			if (ndigits <= 0)
+				ndigits = 1;
+			ilim = ilim1 = i = ndigits;
+			break;
+		case 3:
+			leftright = 0;
+			/* no break */
+		case 5:
+			i = ndigits + k + 1;
+			ilim = i;
+			ilim1 = i - 1;
+			if (i <= 0)
+				i = 1;
+		}
+	s = s0 = rv_alloc(i);
+
+#ifdef Honor_FLT_ROUNDS
+	if (mode > 1 && rounding != 1)
+		leftright = 0;
+#endif
+
+	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+		/* Try to get by with floating-point arithmetic. */
+
+		i = 0;
+		dval(d2) = dval(d);
+		k0 = k;
+		ilim0 = ilim;
+		ieps = 2; /* conservative */
+		if (k > 0) {
+			ds = tens[k&0xf];
+			j = k >> 4;
+			if (j & Bletch) {
+				/* prevent overflows */
+				j &= Bletch - 1;
+				dval(d) /= bigtens[n_bigtens-1];
+				ieps++;
+				}
+			for(; j; j >>= 1, i++)
+				if (j & 1) {
+					ieps++;
+					ds *= bigtens[i];
+					}
+			dval(d) /= ds;
+			}
+		else if (j1 = -k) {
+			dval(d) *= tens[j1 & 0xf];
+			for(j = j1 >> 4; j; j >>= 1, i++)
+				if (j & 1) {
+					ieps++;
+					dval(d) *= bigtens[i];
+					}
+			}
+		if (k_check && dval(d) < 1. && ilim > 0) {
+			if (ilim1 <= 0)
+				goto fast_failed;
+			ilim = ilim1;
+			k--;
+			dval(d) *= 10.;
+			ieps++;
+			}
+		dval(eps) = ieps*dval(d) + 7.;
+		word0(eps) -= (P-1)*Exp_msk1;
+		if (ilim == 0) {
+			S = mhi = 0;
+			dval(d) -= 5.;
+			if (dval(d) > dval(eps))
+				goto one_digit;
+			if (dval(d) < -dval(eps))
+				goto no_digits;
+			goto fast_failed;
+			}
+#ifndef No_leftright
+		if (leftright) {
+			/* Use Steele & White method of only
+			 * generating digits needed.
+			 */
+			dval(eps) = 0.5/tens[ilim-1] - dval(eps);
+			for(i = 0;;) {
+				L = dval(d);
+				dval(d) -= L;
+				*s++ = '0' + (int)L;
+				if (dval(d) < dval(eps))
+					goto ret1;
+				if (1. - dval(d) < dval(eps))
+					goto bump_up;
+				if (++i >= ilim)
+					break;
+				dval(eps) *= 10.;
+				dval(d) *= 10.;
+				}
+			}
+		else {
+#endif
+			/* Generate ilim digits, then fix them up. */
+			dval(eps) *= tens[ilim-1];
+			for(i = 1;; i++, dval(d) *= 10.) {
+				L = (Long)(dval(d));
+				if (!(dval(d) -= L))
+					ilim = i;
+				*s++ = '0' + (int)L;
+				if (i == ilim) {
+					if (dval(d) > 0.5 + dval(eps))
+						goto bump_up;
+					else if (dval(d) < 0.5 - dval(eps)) {
+						while(*--s == '0');
+						s++;
+						goto ret1;
+						}
+					break;
+					}
+				}
+#ifndef No_leftright
+			}
+#endif
+ fast_failed:
+		s = s0;
+		dval(d) = dval(d2);
+		k = k0;
+		ilim = ilim0;
+		}
+
+	/* Do we have a "small" integer? */
+
+	if (be >= 0 && k <= Int_max) {
+		/* Yes. */
+		ds = tens[k];
+		if (ndigits < 0 && ilim <= 0) {
+			S = mhi = 0;
+			if (ilim < 0 || dval(d) <= 5*ds)
+				goto no_digits;
+			goto one_digit;
+			}
+		for(i = 1; i <= k+1; i++, dval(d) *= 10.) {
+			L = (Long)(dval(d) / ds);
+			dval(d) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+			/* If FLT_ROUNDS == 2, L will usually be high by 1 */
+			if (dval(d) < 0) {
+				L--;
+				dval(d) += ds;
+				}
+#endif
+			*s++ = '0' + (int)L;
+			if (!dval(d)) {
+#ifdef SET_INEXACT
+				inexact = 0;
+#endif
+				break;
+				}
+			if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+				if (mode > 1)
+				switch(rounding) {
+				  case 0: goto ret1;
+				  case 2: goto bump_up;
+				  }
+#endif
+				dval(d) += dval(d);
+				if (dval(d) > ds || dval(d) == ds && L & 1) {
+ bump_up:
+					while(*--s == '9')
+						if (s == s0) {
+							k++;
+							*s = '0';
+							break;
+							}
+					++*s++;
+					}
+				break;
+				}
+			}
+		goto ret1;
+		}
+
+	m2 = b2;
+	m5 = b5;
+	mhi = mlo = 0;
+	if (leftright) {
+		i =
+#ifndef Sudden_Underflow
+			denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+			1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+			1 + P - bbits;
+#endif
+		b2 += i;
+		s2 += i;
+		mhi = i2b(1);
+		}
+	if (m2 > 0 && s2 > 0) {
+		i = m2 < s2 ? m2 : s2;
+		b2 -= i;
+		m2 -= i;
+		s2 -= i;
+		}
+	if (b5 > 0) {
+		if (leftright) {
+			if (m5 > 0) {
+				mhi = pow5mult(mhi, m5);
+				b1 = mult(mhi, b);
+				Bfree(b);
+				b = b1;
+				}
+			if (j = b5 - m5)
+				b = pow5mult(b, j);
+			}
+		else
+			b = pow5mult(b, b5);
+		}
+	S = i2b(1);
+	if (s5 > 0)
+		S = pow5mult(S, s5);
+
+	/* Check for special case that d is a normalized power of 2. */
+
+	spec_case = 0;
+	if ((mode < 2 || leftright)
+#ifdef Honor_FLT_ROUNDS
+			&& rounding == 1
+#endif
+				) {
+		if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+		 && word0(d) & (Exp_mask & ~Exp_msk1)
+#endif
+				) {
+			/* The special case */
+			b2 += Log2P;
+			s2 += Log2P;
+			spec_case = 1;
+			}
+		}
+
+	/* Arrange for convenient computation of quotients:
+	 * shift left if necessary so divisor has 4 leading 0 bits.
+	 *
+	 * Perhaps we should just compute leading 28 bits of S once
+	 * and for all and pass them and a shift to quorem, so it
+	 * can do shifts and ors to compute the numerator for q.
+	 */
+#ifdef Pack_32
+	if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
+		i = 32 - i;
+#else
+	if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
+		i = 16 - i;
+#endif
+	if (i > 4) {
+		i -= 4;
+		b2 += i;
+		m2 += i;
+		s2 += i;
+		}
+	else if (i < 4) {
+		i += 28;
+		b2 += i;
+		m2 += i;
+		s2 += i;
+		}
+	if (b2 > 0)
+		b = lshift(b, b2);
+	if (s2 > 0)
+		S = lshift(S, s2);
+	if (k_check) {
+		if (cmp(b,S) < 0) {
+			k--;
+			b = multadd(b, 10, 0);	/* we botched the k estimate */
+			if (leftright)
+				mhi = multadd(mhi, 10, 0);
+			ilim = ilim1;
+			}
+		}
+	if (ilim <= 0 && (mode == 3 || mode == 5)) {
+		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+			/* no digits, fcvt style */
+ no_digits:
+			k = -1 - ndigits;
+			goto ret;
+			}
+ one_digit:
+		*s++ = '1';
+		k++;
+		goto ret;
+		}
+	if (leftright) {
+		if (m2 > 0)
+			mhi = lshift(mhi, m2);
+
+		/* Compute mlo -- check for special case
+		 * that d is a normalized power of 2.
+		 */
+
+		mlo = mhi;
+		if (spec_case) {
+			mhi = Balloc(mhi->k);
+			Bcopy(mhi, mlo);
+			mhi = lshift(mhi, Log2P);
+			}
+
+		for(i = 1;;i++) {
+			dig = quorem(b,S) + '0';
+			/* Do we yet have the shortest decimal string
+			 * that will round to d?
+			 */
+			j = cmp(b, mlo);
+			delta = diff(S, mhi);
+			j1 = delta->sign ? 1 : cmp(b, delta);
+			Bfree(delta);
+#ifndef ROUND_BIASED
+			if (j1 == 0 && mode != 1 && !(word1(d) & 1)
+#ifdef Honor_FLT_ROUNDS
+				&& rounding >= 1
+#endif
+								   ) {
+				if (dig == '9')
+					goto round_9_up;
+				if (j > 0)
+					dig++;
+#ifdef SET_INEXACT
+				else if (!b->x[0] && b->wds <= 1)
+					inexact = 0;
+#endif
+				*s++ = dig;
+				goto ret;
+				}
+#endif
+			if (j < 0 || j == 0 && mode != 1
+#ifndef ROUND_BIASED
+							&& !(word1(d) & 1)
+#endif
+					) {
+				if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+					inexact = 0;
+#endif
+					goto accept_dig;
+					}
+#ifdef Honor_FLT_ROUNDS
+				if (mode > 1)
+				 switch(rounding) {
+				  case 0: goto accept_dig;
+				  case 2: goto keep_dig;
+				  }
+#endif /*Honor_FLT_ROUNDS*/
+				if (j1 > 0) {
+					b = lshift(b, 1);
+					j1 = cmp(b, S);
+					if ((j1 > 0 || j1 == 0 && dig & 1)
+					&& dig++ == '9')
+						goto round_9_up;
+					}
+ accept_dig:
+				*s++ = dig;
+				goto ret;
+				}
+			if (j1 > 0) {
+#ifdef Honor_FLT_ROUNDS
+				if (!rounding)
+					goto accept_dig;
+#endif
+				if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+					*s++ = '9';
+					goto roundoff;
+					}
+				*s++ = dig + 1;
+				goto ret;
+				}
+#ifdef Honor_FLT_ROUNDS
+ keep_dig:
+#endif
+			*s++ = dig;
+			if (i == ilim)
+				break;
+			b = multadd(b, 10, 0);
+			if (mlo == mhi)
+				mlo = mhi = multadd(mhi, 10, 0);
+			else {
+				mlo = multadd(mlo, 10, 0);
+				mhi = multadd(mhi, 10, 0);
+				}
+			}
+		}
+	else
+		for(i = 1;; i++) {
+			*s++ = dig = quorem(b,S) + '0';
+			if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+				inexact = 0;
+#endif
+				goto ret;
+				}
+			if (i >= ilim)
+				break;
+			b = multadd(b, 10, 0);
+			}
+
+	/* Round off last digit */
+
+#ifdef Honor_FLT_ROUNDS
+	switch(rounding) {
+	  case 0: goto trimzeros;
+	  case 2: goto roundoff;
+	  }
+#endif
+	b = lshift(b, 1);
+	j = cmp(b, S);
+	if (j > 0 || j == 0 && dig & 1) {
+ roundoff:
+		while(*--s == '9')
+			if (s == s0) {
+				k++;
+				*s++ = '1';
+				goto ret;
+				}
+		++*s++;
+		}
+	else {
+#ifdef Honor_FLT_ROUNDS
+ trimzeros:
+#endif
+		while(*--s == '0');
+		s++;
+		}
+ ret:
+	Bfree(S);
+	if (mhi) {
+		if (mlo && mlo != mhi)
+			Bfree(mlo);
+		Bfree(mhi);
+		}
+ ret1:
+#ifdef SET_INEXACT
+	if (inexact) {
+		if (!oldinexact) {
+			word0(d) = Exp_1 + (70 << Exp_shift);
+			word1(d) = 0;
+			dval(d) += 1.;
+			}
+		}
+	else if (!oldinexact)
+		clear_inexact();
+#endif
+	Bfree(b);
+	*s = 0;
+	*decpt = k + 1;
+	if (rve)
+		*rve = s;
+	return s0;
+	}
+#ifdef __cplusplus
+}
+#endif
+
+PR_IMPLEMENT(PRStatus)
+PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits,
+	PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize)
+{
+    char *result;
+    PRSize resultlen;
+    PRStatus rv = PR_FAILURE;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (mode < 0 || mode > 3) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return rv;
+    }
+    result = dtoa(d, mode, ndigits, decpt, sign, rve);
+    if (!result) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return rv;
+    }
+    resultlen = strlen(result)+1;
+    if (bufsize < resultlen) {
+        PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+    } else {
+        memcpy(buf, result, resultlen);
+        if (rve) {
+            *rve = buf + (*rve - result);
+        }
+        rv = PR_SUCCESS;
+    }
+    freedtoa(result);
+    return rv;  
+}
+
+/*
+** conversion routines for floating point
+** prcsn - number of digits of precision to generate floating
+** point value.
+** This should be reparameterized so that you can send in a
+**   prcn for the positive and negative ranges.  For now, 
+**   conform to the ECMA JavaScript spec which says numbers
+**   less than 1e-6 are in scientific notation.
+** Also, the ECMA spec says that there should always be a
+**   '+' or '-' after the 'e' in scientific notation
+*/
+PR_IMPLEMENT(void)
+PR_cnvtf(char *buf, int bufsz, int prcsn, double dfval)
+{
+    PRIntn decpt, sign, numdigits;
+    char *num, *nump;
+    char *bufp = buf;
+    char *endnum;
+    U fval;
+
+    dval(fval) = dfval;
+    /* If anything fails, we store an empty string in 'buf' */
+    num = (char*)PR_MALLOC(bufsz);
+    if (num == NULL) {
+        buf[0] = '\0';
+        return;
+    }
+    /* XXX Why use mode 1? */
+    if (PR_dtoa(dval(fval),1,prcsn,&decpt,&sign,&endnum,num,bufsz)
+            == PR_FAILURE) {
+        buf[0] = '\0';
+        goto done;
+    }
+    numdigits = endnum - num;
+    nump = num;
+
+    if (sign &&
+        !(word0(fval) == Sign_bit && word1(fval) == 0) &&
+        !((word0(fval) & Exp_mask) == Exp_mask &&
+          (word1(fval) || (word0(fval) & 0xfffff)))) {
+        *bufp++ = '-';
+    }
+
+    if (decpt == 9999) {
+        while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
+        goto done;
+    }
+
+    if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
+        *bufp++ = *nump++;
+        if (numdigits != 1) {
+            *bufp++ = '.';
+        }
+
+        while (*nump != '\0') {
+            *bufp++ = *nump++;
+        }
+        *bufp++ = 'e';
+        PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
+    } else if (decpt >= 0) {
+        if (decpt == 0) {
+            *bufp++ = '0';
+        } else {
+            while (decpt--) {
+                if (*nump != '\0') {
+                    *bufp++ = *nump++;
+                } else {
+                    *bufp++ = '0';
+                }
+            }
+        }
+        if (*nump != '\0') {
+            *bufp++ = '.';
+            while (*nump != '\0') {
+                *bufp++ = *nump++;
+            }
+        }
+        *bufp++ = '\0';
+    } else if (decpt < 0) {
+        *bufp++ = '0';
+        *bufp++ = '.';
+        while (decpt++) {
+            *bufp++ = '0';
+        }
+
+        while (*nump != '\0') {
+            *bufp++ = *nump++;
+        }
+        *bufp++ = '\0';
+    }
+done:
+    PR_DELETE(num);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prenv.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prenv.c
new file mode 100644
index 0000000..e07e073
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prenv.c
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <string.h>
+#include "primpl.h"
+
+/* Lock used to lock the environment */
+#if defined(_PR_NO_PREEMPT)
+#define _PR_NEW_LOCK_ENV()
+#define _PR_DELETE_LOCK_ENV()
+#define _PR_LOCK_ENV()
+#define _PR_UNLOCK_ENV()
+#elif defined(_PR_LOCAL_THREADS_ONLY)
+extern _PRCPU * _pr_primordialCPU;
+static PRIntn _is;
+#define _PR_NEW_LOCK_ENV()
+#define _PR_DELETE_LOCK_ENV()
+#define _PR_LOCK_ENV() if (_pr_primordialCPU) _PR_INTSOFF(_is);
+#define _PR_UNLOCK_ENV() if (_pr_primordialCPU) _PR_INTSON(_is);
+#else
+static PRLock *_pr_envLock = NULL;
+#define _PR_NEW_LOCK_ENV() {_pr_envLock = PR_NewLock();}
+#define _PR_DELETE_LOCK_ENV() \
+    { if (_pr_envLock) { PR_DestroyLock(_pr_envLock); _pr_envLock = NULL; } }
+#define _PR_LOCK_ENV() { if (_pr_envLock) PR_Lock(_pr_envLock); }
+#define _PR_UNLOCK_ENV() { if (_pr_envLock) PR_Unlock(_pr_envLock); }
+#endif
+
+/************************************************************************/
+
+void _PR_InitEnv(void)
+{
+	_PR_NEW_LOCK_ENV();
+}
+
+void _PR_CleanupEnv(void)
+{
+    _PR_DELETE_LOCK_ENV();
+}
+
+PR_IMPLEMENT(char*) PR_GetEnv(const char *var)
+{
+    char *ev;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    _PR_LOCK_ENV();
+    ev = _PR_MD_GET_ENV(var);
+    _PR_UNLOCK_ENV();
+    return ev;
+}
+
+PR_IMPLEMENT(PRStatus) PR_SetEnv(const char *string)
+{
+    PRIntn result;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if ( !strchr(string, '=')) return(PR_FAILURE);
+
+    _PR_LOCK_ENV();
+    result = _PR_MD_PUT_ENV(string);
+    _PR_UNLOCK_ENV();
+    return (result)? PR_FAILURE : PR_SUCCESS;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.c
new file mode 100644
index 0000000..4db3113
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *
+ * prerr.c
+ * This file is automatically generated; please do not edit it.
+ */
+#include "prerror.h"
+static const struct PRErrorMessage text[] = {
+	{"PR_OUT_OF_MEMORY_ERROR",    "Memory allocation attempt failed"},
+	{"PR_BAD_DESCRIPTOR_ERROR",    "Invalid file descriptor"},
+	{"PR_WOULD_BLOCK_ERROR",    "The operation would have blocked"},
+	{"PR_ACCESS_FAULT_ERROR",    "Invalid memory address argument"},
+	{"PR_INVALID_METHOD_ERROR",    "Invalid function for file type"},
+	{"PR_ILLEGAL_ACCESS_ERROR",    "Invalid memory address argument"},
+	{"PR_UNKNOWN_ERROR",    "Some unknown error has occurred"},
+	{"PR_PENDING_INTERRUPT_ERROR",    "Operation interrupted by another thread"},
+	{"PR_NOT_IMPLEMENTED_ERROR",    "function not implemented"},
+	{"PR_IO_ERROR",    "I/O function error"},
+	{"PR_IO_TIMEOUT_ERROR",    "I/O operation timed out"},
+	{"PR_IO_PENDING_ERROR",    "I/O operation on busy file descriptor"},
+	{"PR_DIRECTORY_OPEN_ERROR",    "The directory could not be opened"},
+	{"PR_INVALID_ARGUMENT_ERROR",    "Invalid function argument"},
+	{"PR_ADDRESS_NOT_AVAILABLE_ERROR",    "Network address not available (in use?)"},
+	{"PR_ADDRESS_NOT_SUPPORTED_ERROR",    "Network address type not supported"},
+	{"PR_IS_CONNECTED_ERROR",    "Already connected"},
+	{"PR_BAD_ADDRESS_ERROR",    "Network address is invalid"},
+	{"PR_ADDRESS_IN_USE_ERROR",    "Local Network address is in use"},
+	{"PR_CONNECT_REFUSED_ERROR",    "Connection refused by peer"},
+	{"PR_NETWORK_UNREACHABLE_ERROR",    "Network address is presently unreachable"},
+	{"PR_CONNECT_TIMEOUT_ERROR",    "Connection attempt timed out"},
+	{"PR_NOT_CONNECTED_ERROR",    "Network file descriptor is not connected"},
+	{"PR_LOAD_LIBRARY_ERROR",    "Failure to load dynamic library"},
+	{"PR_UNLOAD_LIBRARY_ERROR",    "Failure to unload dynamic library"},
+	{"PR_FIND_SYMBOL_ERROR",    "Symbol not found in any of the loaded dynamic libraries"},
+	{"PR_INSUFFICIENT_RESOURCES_ERROR",    "Insufficient system resources"},
+	{"PR_DIRECTORY_LOOKUP_ERROR",    "A directory lookup on a network address has failed"},
+	{"PR_TPD_RANGE_ERROR",    "Attempt to access a TPD key that is out of range"},
+	{"PR_PROC_DESC_TABLE_FULL_ERROR",    "Process open FD table is full"},
+	{"PR_SYS_DESC_TABLE_FULL_ERROR",    "System open FD table is full"},
+	{"PR_NOT_SOCKET_ERROR",    "Network operation attempted on non-network file descriptor"},
+	{"PR_NOT_TCP_SOCKET_ERROR",    "TCP-specific function attempted on a non-TCP file descriptor"},
+	{"PR_SOCKET_ADDRESS_IS_BOUND_ERROR",    "TCP file descriptor is already bound"},
+	{"PR_NO_ACCESS_RIGHTS_ERROR",    "Access Denied"},
+	{"PR_OPERATION_NOT_SUPPORTED_ERROR",    "The requested operation is not supported by the platform"},
+	{"PR_PROTOCOL_NOT_SUPPORTED_ERROR",    "The host operating system does not support the protocol requested"},
+	{"PR_REMOTE_FILE_ERROR",    "Access to the remote file has been severed"},
+	{"PR_BUFFER_OVERFLOW_ERROR",    "The value requested is too large to be stored in the data buffer provided"},
+	{"PR_CONNECT_RESET_ERROR",    "TCP connection reset by peer"},
+	{"PR_RANGE_ERROR",    "Unused"},
+	{"PR_DEADLOCK_ERROR",    "The operation would have deadlocked"},
+	{"PR_FILE_IS_LOCKED_ERROR",    "The file is already locked"},
+	{"PR_FILE_TOO_BIG_ERROR",    "Write would result in file larger than the system allows"},
+	{"PR_NO_DEVICE_SPACE_ERROR",    "The device for storing the file is full"},
+	{"PR_PIPE_ERROR",    "Unused"},
+	{"PR_NO_SEEK_DEVICE_ERROR",    "Unused"},
+	{"PR_IS_DIRECTORY_ERROR",    "Cannot perform a normal file operation on a directory"},
+	{"PR_LOOP_ERROR",    "Symbolic link loop"},
+	{"PR_NAME_TOO_LONG_ERROR",    "File name is too long"},
+	{"PR_FILE_NOT_FOUND_ERROR",    "File not found"},
+	{"PR_NOT_DIRECTORY_ERROR",    "Cannot perform directory operation on a normal file"},
+	{"PR_READ_ONLY_FILESYSTEM_ERROR",    "Cannot write to a read-only file system"},
+	{"PR_DIRECTORY_NOT_EMPTY_ERROR",    "Cannot delete a directory that is not empty"},
+	{"PR_FILESYSTEM_MOUNTED_ERROR",    "Cannot delete or rename a file object while the file system is busy"},
+	{"PR_NOT_SAME_DEVICE_ERROR",    "Cannot rename a file to a file system on another device"},
+	{"PR_DIRECTORY_CORRUPTED_ERROR",    "The directory object in the file system is corrupted"},
+	{"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_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"},
+	{"PR_LIBRARY_NOT_LOADED_ERROR",    "The library is not loaded"},
+	{"PR_CALL_ONCE_ERROR",    "The one-time function was previously called and failed. Its error code is no longer available"},
+	{"PR_MAX_ERROR",    "Placeholder for the end of the list"},
+	{0, 0}
+};
+
+static const struct PRErrorTable et = { text, "prerr", -6000L, 77 };
+
+void nspr_InitializePRErrorTable(void) {
+    PR_ErrorInstallTable(&et);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.et b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.et
new file mode 100644
index 0000000..8578f95
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.et
@@ -0,0 +1,140 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+et nspr -6000
+
+ec PR_OUT_OF_MEMORY_ERROR,      "Memory allocation attempt failed"
+ec PR_BAD_DESCRIPTOR_ERROR,     "Invalid file descriptor"
+ec PR_WOULD_BLOCK_ERROR,        "The operation would have blocked"
+ec PR_ACCESS_FAULT_ERROR,       "Invalid memory address argument"
+ec PR_INVALID_METHOD_ERROR,     "Invalid function for file type"
+ec PR_ILLEGAL_ACCESS_ERROR,     "Invalid memory address argument"
+ec PR_UNKNOWN_ERROR,            "Some unknown error has occurred"
+ec PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread"
+ec PR_NOT_IMPLEMENTED_ERROR,    "function not implemented"
+ec PR_IO_ERROR,                 "I/O function error"
+ec PR_IO_TIMEOUT_ERROR,         "I/O operation timed out"
+ec PR_IO_PENDING_ERROR,         "I/O operation on busy file descriptor"
+ec PR_DIRECTORY_OPEN_ERROR,     "The directory could not be opened"
+ec PR_INVALID_ARGUMENT_ERROR, "Invalid function argument"
+ec PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)"
+ec PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported"
+ec PR_IS_CONNECTED_ERROR,       "Already connected"
+ec PR_BAD_ADDRESS_ERROR,        "Network address is invalid"
+ec PR_ADDRESS_IN_USE_ERROR,     "Local Network address is in use"
+ec PR_CONNECT_REFUSED_ERROR,    "Connection refused by peer"
+ec PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable"
+ec PR_CONNECT_TIMEOUT_ERROR,    "Connection attempt timed out"
+ec PR_NOT_CONNECTED_ERROR,      "Network file descriptor is not connected"
+ec PR_LOAD_LIBRARY_ERROR,       "Failure to load dynamic library"
+ec PR_UNLOAD_LIBRARY_ERROR,     "Failure to unload dynamic library"
+ec PR_FIND_SYMBOL_ERROR,
+"Symbol not found in any of the loaded dynamic libraries"
+ec PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources"
+ec PR_DIRECTORY_LOOKUP_ERROR,
+"A directory lookup on a network address has failed"
+ec PR_TPD_RANGE_ERROR,
+"Attempt to access a TPD key that is out of range"
+ec PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full"
+ec PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full"
+ec PR_NOT_SOCKET_ERROR,
+"Network operation attempted on non-network file descriptor"
+ec PR_NOT_TCP_SOCKET_ERROR,
+"TCP-specific function attempted on a non-TCP file descriptor"
+ec PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound"
+ec PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied"
+ec PR_OPERATION_NOT_SUPPORTED_ERROR,
+"The requested operation is not supported by the platform"
+ec PR_PROTOCOL_NOT_SUPPORTED_ERROR,
+"The host operating system does not support the protocol requested"
+ec PR_REMOTE_FILE_ERROR,        "Access to the remote file has been severed"
+ec PR_BUFFER_OVERFLOW_ERROR,
+"The value requested is too large to be stored in the data buffer provided"
+ec PR_CONNECT_RESET_ERROR,      "TCP connection reset by peer"
+ec PR_RANGE_ERROR,              "Unused"
+ec PR_DEADLOCK_ERROR,   "The operation would have deadlocked"
+ec PR_FILE_IS_LOCKED_ERROR,     "The file is already locked"
+ec PR_FILE_TOO_BIG_ERROR,
+"Write would result in file larger than the system allows"
+ec PR_NO_DEVICE_SPACE_ERROR,    "The device for storing the file is full"
+ec PR_PIPE_ERROR,               "Unused"
+ec PR_NO_SEEK_DEVICE_ERROR,     "Unused"
+ec PR_IS_DIRECTORY_ERROR,
+"Cannot perform a normal file operation on a directory"
+ec PR_LOOP_ERROR,               "Symbolic link loop"
+ec PR_NAME_TOO_LONG_ERROR,      "File name is too long"
+ec PR_FILE_NOT_FOUND_ERROR,     "File not found"
+ec PR_NOT_DIRECTORY_ERROR,
+"Cannot perform directory operation on a normal file"
+ec PR_READ_ONLY_FILESYSTEM_ERROR,
+"Cannot write to a read-only file system"
+ec PR_DIRECTORY_NOT_EMPTY_ERROR,
+"Cannot delete a directory that is not empty"
+ec PR_FILESYSTEM_MOUNTED_ERROR,
+"Cannot delete or rename a file object while the file system is busy"
+ec PR_NOT_SAME_DEVICE_ERROR,
+"Cannot rename a file to a file system on another device"
+ec PR_DIRECTORY_CORRUPTED_ERROR,
+"The directory object in the file system is corrupted"
+ec PR_FILE_EXISTS_ERROR,
+"Cannot create or rename a filename that already exists"
+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_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"
+ec PR_CONNECT_ABORTED_ERROR,    "Connection aborted"
+ec PR_HOST_UNREACHABLE_ERROR,   "Host is unreachable"
+ec PR_LIBRARY_NOT_LOADED_ERROR, "The library is not loaded"
+ec PR_CALL_ONCE_ERROR, "The one-time function was previously called and failed. Its error code is no longer available"
+
+ec PR_MAX_ERROR,                "Placeholder for the end of the list"
+
+end
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.properties b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.properties
new file mode 100644
index 0000000..58a0285
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerr.properties
@@ -0,0 +1,117 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# prerr.properties
+# This file is automatically generated; please do not edit it.
+PR_OUT_OF_MEMORY_ERROR=Memory allocation attempt failed
+PR_BAD_DESCRIPTOR_ERROR=Invalid file descriptor
+PR_WOULD_BLOCK_ERROR=The operation would have blocked
+PR_ACCESS_FAULT_ERROR=Invalid memory address argument
+PR_INVALID_METHOD_ERROR=Invalid function for file type
+PR_ILLEGAL_ACCESS_ERROR=Invalid memory address argument
+PR_UNKNOWN_ERROR=Some unknown error has occurred
+PR_PENDING_INTERRUPT_ERROR=Operation interrupted by another thread
+PR_NOT_IMPLEMENTED_ERROR=function not implemented
+PR_IO_ERROR=I/O function error
+PR_IO_TIMEOUT_ERROR=I/O operation timed out
+PR_IO_PENDING_ERROR=I/O operation on busy file descriptor
+PR_DIRECTORY_OPEN_ERROR=The directory could not be opened
+PR_INVALID_ARGUMENT_ERROR=Invalid function argument
+PR_ADDRESS_NOT_AVAILABLE_ERROR=Network address not available (in use?)
+PR_ADDRESS_NOT_SUPPORTED_ERROR=Network address type not supported
+PR_IS_CONNECTED_ERROR=Already connected
+PR_BAD_ADDRESS_ERROR=Network address is invalid
+PR_ADDRESS_IN_USE_ERROR=Local Network address is in use
+PR_CONNECT_REFUSED_ERROR=Connection refused by peer
+PR_NETWORK_UNREACHABLE_ERROR=Network address is presently unreachable
+PR_CONNECT_TIMEOUT_ERROR=Connection attempt timed out
+PR_NOT_CONNECTED_ERROR=Network file descriptor is not connected
+PR_LOAD_LIBRARY_ERROR=Failure to load dynamic library
+PR_UNLOAD_LIBRARY_ERROR=Failure to unload dynamic library
+PR_FIND_SYMBOL_ERROR=Symbol not found in any of the loaded dynamic libraries
+PR_INSUFFICIENT_RESOURCES_ERROR=Insufficient system resources
+PR_DIRECTORY_LOOKUP_ERROR=A directory lookup on a network address has failed
+PR_TPD_RANGE_ERROR=Attempt to access a TPD key that is out of range
+PR_PROC_DESC_TABLE_FULL_ERROR=Process open FD table is full
+PR_SYS_DESC_TABLE_FULL_ERROR=System open FD table is full
+PR_NOT_SOCKET_ERROR=Network operation attempted on non-network file descriptor
+PR_NOT_TCP_SOCKET_ERROR=TCP-specific function attempted on a non-TCP file descriptor
+PR_SOCKET_ADDRESS_IS_BOUND_ERROR=TCP file descriptor is already bound
+PR_NO_ACCESS_RIGHTS_ERROR=Access Denied
+PR_OPERATION_NOT_SUPPORTED_ERROR=The requested operation is not supported by the platform
+PR_PROTOCOL_NOT_SUPPORTED_ERROR=The host operating system does not support the protocol requested
+PR_REMOTE_FILE_ERROR=Access to the remote file has been severed
+PR_BUFFER_OVERFLOW_ERROR=The value requested is too large to be stored in the data buffer provided
+PR_CONNECT_RESET_ERROR=TCP connection reset by peer
+PR_RANGE_ERROR=Unused
+PR_DEADLOCK_ERROR=The operation would have deadlocked
+PR_FILE_IS_LOCKED_ERROR=The file is already locked
+PR_FILE_TOO_BIG_ERROR=Write would result in file larger than the system allows
+PR_NO_DEVICE_SPACE_ERROR=The device for storing the file is full
+PR_PIPE_ERROR=Unused
+PR_NO_SEEK_DEVICE_ERROR=Unused
+PR_IS_DIRECTORY_ERROR=Cannot perform a normal file operation on a directory
+PR_LOOP_ERROR=Symbolic link loop
+PR_NAME_TOO_LONG_ERROR=File name is too long
+PR_FILE_NOT_FOUND_ERROR=File not found
+PR_NOT_DIRECTORY_ERROR=Cannot perform directory operation on a normal file
+PR_READ_ONLY_FILESYSTEM_ERROR=Cannot write to a read-only file system
+PR_DIRECTORY_NOT_EMPTY_ERROR=Cannot delete a directory that is not empty
+PR_FILESYSTEM_MOUNTED_ERROR=Cannot delete or rename a file object while the file system is busy
+PR_NOT_SAME_DEVICE_ERROR=Cannot rename a file to a file system on another device
+PR_DIRECTORY_CORRUPTED_ERROR=The directory object in the file system is corrupted
+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_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
+PR_LIBRARY_NOT_LOADED_ERROR=The library is not loaded
+PR_CALL_ONCE_ERROR=The one-time function was previously called and failed. Its error code is no longer available
+PR_MAX_ERROR=Placeholder for the end of the list
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerror.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerror.c
new file mode 100644
index 0000000..f578f2d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerror.c
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+PR_IMPLEMENT(PRErrorCode) PR_GetError(void)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    return thread->errorCode;
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetOSError(void)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    return thread->osErrorCode;
+}
+
+PR_IMPLEMENT(void) PR_SetError(PRErrorCode code, PRInt32 osErr)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    thread->errorCode = code;
+    thread->osErrorCode = osErr;
+    thread->errorStringLength = 0;
+}
+
+PR_IMPLEMENT(void) PR_SetErrorText(PRIntn textLength, const char *text)
+{
+    PRThread *thread = PR_GetCurrentThread();
+
+    if (0 == textLength)
+    {
+	    if (NULL != thread->errorString)
+	        PR_DELETE(thread->errorString);
+	    thread->errorStringSize = 0;
+    }
+    else
+    {
+	    PRIntn size = textLength + 31;  /* actual length to allocate. Plus a little extra */
+        if (thread->errorStringSize < textLength+1)  /* do we have room? */
+        {
+	        if (NULL != thread->errorString)
+	            PR_DELETE(thread->errorString);
+		    thread->errorString = (char*)PR_MALLOC(size);
+            if ( NULL == thread->errorString ) {
+                thread->errorStringSize = 0;
+                thread->errorStringLength = 0;
+                return;
+            }
+            thread->errorStringSize = size;
+	    }
+        memcpy(thread->errorString, text, textLength+1 );
+    }
+    thread->errorStringLength = textLength;
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetErrorTextLength(void)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    return thread->errorStringLength;
+}  /* PR_GetErrorTextLength */
+
+PR_IMPLEMENT(PRInt32) PR_GetErrorText(char *text)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    if (0 != thread->errorStringLength)
+        memcpy(text, thread->errorString, thread->errorStringLength+1);
+    return thread->errorStringLength;
+}  /* PR_GetErrorText */
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerrortable.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerrortable.c
new file mode 100644
index 0000000..a51b4e8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prerrortable.c
@@ -0,0 +1,240 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+
+/*
+
+Copyright 1987, 1988 by the Student Information Processing Board
+	of the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this software
+and its documentation for any purpose and without fee is
+hereby granted, provided that the above copyright notice
+appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation,
+and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+M.I.T. and the M.I.T. S.I.P.B. make no representations about
+the suitability of this software for any purpose.  It is
+provided "as is" without express or implied warranty.
+
+*/
+
+#include <string.h>
+#ifdef SUNOS4
+#include "md/sunos4.h"  /* for strerror */
+#endif
+#include <assert.h>
+#include <errno.h>
+#include "prmem.h"
+#include "prerror.h"
+
+#define	ERRCODE_RANGE	8	/* # of bits to shift table number */
+#define	BITS_PER_CHAR	6	/* # bits to shift per character in name */
+
+#ifdef NEED_SYS_ERRLIST
+extern char const * const sys_errlist[];
+extern const int sys_nerr;
+#endif
+
+/* List of error tables */
+struct PRErrorTableList {
+    struct PRErrorTableList *next;
+    const struct PRErrorTable *table;
+    struct PRErrorCallbackTablePrivate *table_private;
+};
+static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL;
+
+/* Supported languages */
+static const char * default_languages[] = { "i-default", "en", 0 };
+static const char * const * callback_languages = default_languages;
+
+/* Callback info */
+static struct PRErrorCallbackPrivate *callback_private = 0;
+static PRErrorCallbackLookupFn *callback_lookup = 0;
+static PRErrorCallbackNewTableFn *callback_newtable = 0;
+
+
+static const char char_set[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+
+static const char *
+error_table_name (PRErrorCode num)
+{
+    static char buf[6];	/* only used if internal code problems exist */
+
+    long ch;
+    int i;
+    char *p;
+
+    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
+    p = buf;
+    num >>= ERRCODE_RANGE;
+    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
+    num &= 077777777;
+    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
+    for (i = 4; i >= 0; i--) {
+	ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
+	if (ch != 0)
+	    *p++ = char_set[ch-1];
+    }
+    *p = '\0';
+    return(buf);
+}
+
+PR_IMPLEMENT(const char *)
+PR_ErrorToString(PRErrorCode code, PRLanguageCode language)
+{
+    /* static buffer only used if code is using inconsistent error message
+     * numbers, so just ignore the possible thread contention
+     */
+    static char buffer[25];
+
+    const char *msg;
+    int offset;
+    PRErrorCode table_num;
+    struct PRErrorTableList *et;
+    int started = 0;
+    char *cp;
+
+    for (et = Table_List; et; et = et->next) {
+	if (et->table->base <= code &&
+	    et->table->base + et->table->n_msgs > code) {
+	    /* This is the right table */
+	    if (callback_lookup) {
+		msg = callback_lookup(code, language, et->table,
+		    callback_private, et->table_private);
+		if (msg) return msg;
+	    }
+    
+	    return(et->table->msgs[code - et->table->base].en_text);
+	}
+    }
+
+    if (code >= 0 && code < 256) {
+	return strerror(code);
+    }
+
+    offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
+    table_num = code - offset;
+    strcpy (buffer, "Unknown code ");
+    if (table_num) {
+	strcat(buffer, error_table_name (table_num));
+	strcat(buffer, " ");
+    }
+    for (cp = buffer; *cp; cp++)
+	;
+    if (offset >= 100) {
+	*cp++ = (char)('0' + offset / 100);
+	offset %= 100;
+	started++;
+    }
+    if (started || offset >= 10) {
+	*cp++ = (char)('0' + offset / 10);
+	offset %= 10;
+    }
+    *cp++ = (char)('0' + offset);
+    *cp = '\0';
+    return(buffer);
+}
+
+PR_IMPLEMENT(const char *)
+PR_ErrorToName(PRErrorCode code)
+{
+    struct PRErrorTableList *et;
+
+    for (et = Table_List; et; et = et->next) {
+	if (et->table->base <= code &&
+	    et->table->base + et->table->n_msgs > code) {
+	    /* This is the right table */
+	    return(et->table->msgs[code - et->table->base].name);
+	}
+    }
+
+    return 0;
+}
+
+PR_IMPLEMENT(const char * const *)
+PR_ErrorLanguages(void)
+{
+    return callback_languages;
+}
+
+PR_IMPLEMENT(PRErrorCode)
+PR_ErrorInstallTable(const struct PRErrorTable *table)
+{
+    struct PRErrorTableList * new_et;
+
+    new_et = (struct PRErrorTableList *)
+					PR_Malloc(sizeof(struct PRErrorTableList));
+    if (!new_et)
+	return errno;	/* oops */
+    new_et->table = table;
+    if (callback_newtable) {
+	new_et->table_private = callback_newtable(table, callback_private);
+    } else {
+	new_et->table_private = 0;
+    }
+    new_et->next = Table_List;
+    Table_List = new_et;
+    return 0;
+}
+
+PR_IMPLEMENT(void)
+PR_ErrorInstallCallback(const char * const * languages,
+		       PRErrorCallbackLookupFn *lookup, 
+		       PRErrorCallbackNewTableFn *newtable,
+		       struct PRErrorCallbackPrivate *cb_private)
+{
+    struct PRErrorTableList *et;
+
+    assert(strcmp(languages[0], "i-default") == 0);
+    assert(strcmp(languages[1], "en") == 0);
+    
+    callback_languages = languages;
+    callback_lookup = lookup;
+    callback_newtable = newtable;
+    callback_private = cb_private;
+
+    if (callback_newtable) {
+	for (et = Table_List; et; et = et->next) {
+	    et->table_private = callback_newtable(et->table, callback_private);
+	}
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prinit.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prinit.c
new file mode 100644
index 0000000..e419e89
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prinit.c
@@ -0,0 +1,868 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <ctype.h>
+#include <string.h>
+
+PRLogModuleInfo *_pr_clock_lm;
+PRLogModuleInfo *_pr_cmon_lm;
+PRLogModuleInfo *_pr_io_lm;
+PRLogModuleInfo *_pr_cvar_lm;
+PRLogModuleInfo *_pr_mon_lm;
+PRLogModuleInfo *_pr_linker_lm;
+PRLogModuleInfo *_pr_sched_lm;
+PRLogModuleInfo *_pr_thread_lm;
+PRLogModuleInfo *_pr_gc_lm;
+PRLogModuleInfo *_pr_shm_lm;
+PRLogModuleInfo *_pr_shma_lm;
+
+PRFileDesc *_pr_stdin;
+PRFileDesc *_pr_stdout;
+PRFileDesc *_pr_stderr;
+
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+
+PRCList _pr_active_local_threadQ =
+			PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ);
+PRCList _pr_active_global_threadQ =
+			PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ);
+
+_MDLock  _pr_cpuLock;           /* lock for the CPU Q */
+PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ);
+
+PRUint32 _pr_utid;
+
+PRInt32 _pr_userActive;
+PRInt32 _pr_systemActive;
+PRUintn _pr_maxPTDs;
+
+#ifdef _PR_LOCAL_THREADS_ONLY
+
+struct _PRCPU 	*_pr_currentCPU;
+PRThread 	*_pr_currentThread;
+PRThread 	*_pr_lastThread;
+PRInt32 	_pr_intsOff;
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+/* Lock protecting all "termination" condition variables of all threads */
+PRLock *_pr_terminationCVLock;
+
+#endif /* !defined(_PR_PTHREADS) */
+
+PRLock *_pr_sleeplock;  /* used in PR_Sleep(), classic and pthreads */
+
+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 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++;
+    }
+    if (*ptr == '.') {
+        ptr++;
+        while (isdigit(*ptr)) {
+            vminor = 10 * vminor + *ptr - '0';
+            ptr++;
+        }
+        if (*ptr == '.') {
+            ptr++;
+            while (isdigit(*ptr)) {
+                vpatch = 10 * vpatch + *ptr - '0';
+                ptr++;
+            }
+        }
+    }
+
+    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;
+    }
+    return PR_TRUE;
+}  /* PR_VersionCheck */
+
+
+PR_IMPLEMENT(PRBool) PR_Initialized(void)
+{
+    return _pr_initialized;
+}
+
+PRInt32 _native_threads_only = 0;
+
+#ifdef WINNT
+static void _pr_SetNativeThreadsOnlyMode(void)
+{
+    HMODULE mainExe;
+    PRBool *globalp;
+    char *envp;
+
+    mainExe = GetModuleHandle(NULL);
+    PR_ASSERT(NULL != mainExe);
+    globalp = (PRBool *) GetProcAddress(mainExe, "nspr_native_threads_only");
+    if (globalp) {
+        _native_threads_only = (*globalp != PR_FALSE);
+    } else if (envp = getenv("NSPR_NATIVE_THREADS_ONLY")) {
+        _native_threads_only = (atoi(envp) == 1);
+    }
+}
+#endif
+
+static void _PR_InitStuff(void)
+{
+
+    if (_pr_initialized) return;
+    _pr_initialized = PR_TRUE;
+#ifdef _PR_ZONE_ALLOCATOR
+    _PR_InitZones();
+#endif
+#ifdef WINNT
+    _pr_SetNativeThreadsOnlyMode();
+#endif
+
+
+    (void) PR_GetPageSize();
+
+	_pr_clock_lm = PR_NewLogModule("clock");
+	_pr_cmon_lm = PR_NewLogModule("cmon");
+	_pr_io_lm = PR_NewLogModule("io");
+	_pr_mon_lm = PR_NewLogModule("mon");
+	_pr_linker_lm = PR_NewLogModule("linker");
+	_pr_cvar_lm = PR_NewLogModule("cvar");
+	_pr_sched_lm = PR_NewLogModule("sched");
+	_pr_thread_lm = PR_NewLogModule("thread");
+	_pr_gc_lm = PR_NewLogModule("gc");
+	_pr_shm_lm = PR_NewLogModule("shm");
+	_pr_shma_lm = PR_NewLogModule("shma");
+      
+    /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */ 
+    _PR_MD_EARLY_INIT();
+
+    _PR_InitLocks();
+    _PR_InitAtomic();
+    _PR_InitSegs();
+    _PR_InitStacks();
+	_PR_InitTPD();
+    _PR_InitEnv();
+    _PR_InitLayerCache();
+    _PR_InitClock();
+
+    _pr_sleeplock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_sleeplock);
+
+#ifdef GC_LEAK_DETECTOR
+    _PR_InitGarbageCollector();
+#endif
+
+    _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    
+#ifdef WIN16
+	{
+	PRInt32 top;   /* artificial top of stack, win16 */
+    _pr_top_of_task_stack = (char *) &top;
+	}
+#endif    
+
+#ifndef _PR_GLOBAL_THREADS_ONLY
+	_PR_InitCPUs();
+#endif
+
+/*
+ * XXX: call _PR_InitMem only on those platforms for which nspr implements
+ *	malloc, for now.
+ */
+#ifdef _PR_OVERRIDE_MALLOC
+    _PR_InitMem();
+#endif
+
+    _PR_InitCMon();
+    _PR_InitIO();
+    _PR_InitNet();
+    _PR_InitTime();
+    _PR_InitLog();
+    _PR_InitLinker();
+    _PR_InitCallOnce();
+    _PR_InitDtoa();
+    _PR_InitMW();
+    _PR_InitRWLocks();
+
+    nspr_InitializePRErrorTable();
+
+    _PR_MD_FINAL_INIT();
+}
+
+void _PR_ImplicitInitialization(void)
+{
+	_PR_InitStuff();
+
+    /* Enable interrupts */
+#if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY)
+    _PR_MD_START_INTERRUPTS();
+#endif
+
+}
+
+PR_IMPLEMENT(void) PR_DisableClockInterrupts(void)
+{
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+	if (!_pr_initialized) {
+		_PR_InitStuff();
+	} else {
+    	_PR_MD_DISABLE_CLOCK_INTERRUPTS();
+	}
+#endif
+}
+
+PR_IMPLEMENT(void) PR_EnableClockInterrupts(void)
+{
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+	if (!_pr_initialized) {
+		_PR_InitStuff();
+	}
+    _PR_MD_ENABLE_CLOCK_INTERRUPTS();
+#endif
+}
+
+PR_IMPLEMENT(void) PR_BlockClockInterrupts(void)
+{
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+    	_PR_MD_BLOCK_CLOCK_INTERRUPTS();
+#endif
+}
+
+PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void)
+{
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+    	_PR_MD_UNBLOCK_CLOCK_INTERRUPTS();
+#endif
+}
+
+PR_IMPLEMENT(void) PR_Init(
+    PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs)
+{
+    _PR_ImplicitInitialization();
+}
+
+PR_IMPLEMENT(PRIntn) PR_Initialize(
+    PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs)
+{
+    PRIntn rv;
+    _PR_ImplicitInitialization();
+    rv = prmain(argc, argv);
+	PR_Cleanup();
+    return rv;
+}  /* PR_Initialize */
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * _PR_CleanupBeforeExit --
+ *
+ *   Perform the cleanup work before exiting the process. 
+ *   We first do the cleanup generic to all platforms.  Then
+ *   we call _PR_MD_CLEANUP_BEFORE_EXIT(), where platform-dependent
+ *   cleanup is done.  This function is used by PR_Cleanup().
+ *
+ * See also: PR_Cleanup().
+ *
+ *-----------------------------------------------------------------------
+ */
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+    /* see ptthread.c */
+#else
+static void
+_PR_CleanupBeforeExit(void)
+{
+/* 
+Do not make any calls here other than to destroy resources.  For example,
+do not make any calls that eventually may end up in PR_Lock.  Because the
+thread is destroyed, can not access current thread any more.
+*/
+    _PR_CleanupTPD();
+    if (_pr_terminationCVLock)
+    /*
+     * In light of the comment above, this looks real suspicious.
+     * I'd go so far as to say it's just a problem waiting to happen.
+     */
+        PR_DestroyLock(_pr_terminationCVLock);
+
+    _PR_MD_CLEANUP_BEFORE_EXIT();
+}
+#endif /* defined(_PR_PTHREADS) */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PR_Cleanup --
+ *
+ *   Perform a graceful shutdown of the NSPR runtime.  PR_Cleanup() may
+ *   only be called from the primordial thread, typically at the
+ *   end of the main() function.  It returns when it has completed
+ *   its platform-dependent duty and the process must not make any other
+ *   NSPR library calls prior to exiting from main().
+ *
+ *   PR_Cleanup() first blocks the primordial thread until all the
+ *   other user (non-system) threads, if any, have terminated.
+ *   Then it performs cleanup in preparation for exiting the process.
+ *   PR_Cleanup() does not exit the primordial thread (which would
+ *   in turn exit the process).
+ *   
+ *   PR_Cleanup() only responds when it is called by the primordial
+ *   thread. Calls by any other thread are silently ignored.
+ *
+ * See also: PR_ExitProcess()
+ *
+ *----------------------------------------------------------------------
+ */
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+    /* see ptthread.c */
+#else
+
+PR_IMPLEMENT(PRStatus) PR_Cleanup()
+{
+    PRThread *me = PR_GetCurrentThread();
+    PR_ASSERT((NULL != me) && (me->flags & _PR_PRIMORDIAL));
+    if ((NULL != me) && (me->flags & _PR_PRIMORDIAL))
+    {
+        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR"));
+
+        /*
+         * No more recycling of threads
+         */
+        _pr_recycleThreads = 0;
+
+        /*
+         * Wait for all other user (non-system/daemon) threads
+         * to terminate.
+         */
+        PR_Lock(_pr_activeLock);
+        while (_pr_userActive > _pr_primordialExitCount) {
+            PR_WaitCondVar(_pr_primordialExitCVar, PR_INTERVAL_NO_TIMEOUT);
+        }
+        if (me->flags & _PR_SYSTEM) {
+            _pr_systemActive--;
+        } else {
+            _pr_userActive--;
+        }
+        PR_Unlock(_pr_activeLock);
+
+#ifdef IRIX
+		_PR_MD_PRE_CLEANUP(me);
+		/*
+		 * The primordial thread must now be running on the primordial cpu
+		 */
+    	PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0));
+#endif
+
+        _PR_MD_EARLY_CLEANUP();
+
+        _PR_CleanupMW();
+        _PR_CleanupTime();
+        _PR_CleanupDtoa();
+        _PR_CleanupCallOnce();
+		_PR_ShutdownLinker();
+        _PR_CleanupNet();
+        _PR_CleanupIO();
+        /* Release the primordial thread's private data, etc. */
+        _PR_CleanupThread(me);
+
+        _PR_MD_STOP_INTERRUPTS();
+
+	    PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+	            ("PR_Cleanup: clean up before destroying thread"));
+	    _PR_LogCleanup();
+
+        /*
+         * This part should look like the end of _PR_NativeRunThread
+         * and _PR_UserRunThread.
+         */
+        if (_PR_IS_NATIVE_THREAD(me)) {
+            _PR_MD_EXIT_THREAD(me);
+            _PR_NativeDestroyThread(me);
+        } else {
+            _PR_UserDestroyThread(me);
+            PR_DELETE(me->stack);
+            PR_DELETE(me);
+        }
+
+        /*
+         * XXX: We are freeing the heap memory here so that Purify won't
+         * complain, but we should also free other kinds of resources
+         * that are allocated by the _PR_InitXXX() functions.
+         * Ideally, for each _PR_InitXXX(), there should be a corresponding
+         * _PR_XXXCleanup() that we can call here.
+         */
+#ifdef WINNT
+        _PR_CleanupCPUs();
+#endif
+        _PR_CleanupThreads();
+        _PR_CleanupCMon();
+        PR_DestroyLock(_pr_sleeplock);
+        _pr_sleeplock = NULL;
+        _PR_CleanupLayerCache();
+        _PR_CleanupEnv();
+        _PR_CleanupStacks();
+        _PR_CleanupBeforeExit();
+        _pr_initialized = PR_FALSE;
+        return PR_SUCCESS;
+    }
+    return PR_FAILURE;
+}
+#endif /* defined(_PR_PTHREADS) */
+
+/*
+ *------------------------------------------------------------------------
+ * PR_ProcessExit --
+ * 
+ *   Cause an immediate, nongraceful, forced termination of the process.
+ *   It takes a PRIntn argument, which is the exit status code of the
+ *   process.
+ *   
+ * See also: PR_Cleanup()
+ *
+ *------------------------------------------------------------------------
+ */
+
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+    /* see ptthread.c */
+#else
+PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status)
+{
+    _PR_MD_EXIT(status);
+}
+
+#endif /* defined(_PR_PTHREADS) */
+
+PR_IMPLEMENT(PRProcessAttr *)
+PR_NewProcessAttr(void)
+{
+    PRProcessAttr *attr;
+
+    attr = PR_NEWZAP(PRProcessAttr);
+    if (!attr) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return attr;
+}
+
+PR_IMPLEMENT(void)
+PR_ResetProcessAttr(PRProcessAttr *attr)
+{
+    PR_FREEIF(attr->currentDirectory);
+    PR_FREEIF(attr->fdInheritBuffer);
+    memset(attr, 0, sizeof(*attr));
+}
+
+PR_IMPLEMENT(void)
+PR_DestroyProcessAttr(PRProcessAttr *attr)
+{
+    PR_FREEIF(attr->currentDirectory);
+    PR_FREEIF(attr->fdInheritBuffer);
+    PR_DELETE(attr);
+}
+
+PR_IMPLEMENT(void)
+PR_ProcessAttrSetStdioRedirect(
+    PRProcessAttr *attr,
+    PRSpecialFD stdioFd,
+    PRFileDesc *redirectFd)
+{
+    switch (stdioFd) {
+        case PR_StandardInput:
+            attr->stdinFd = redirectFd;
+            break;
+        case PR_StandardOutput:
+            attr->stdoutFd = redirectFd;
+            break;
+        case PR_StandardError:
+            attr->stderrFd = redirectFd;
+            break;
+        default:
+            PR_ASSERT(0);
+    }
+}
+
+/*
+ * OBSOLETE
+ */
+PR_IMPLEMENT(void)
+PR_SetStdioRedirect(
+    PRProcessAttr *attr,
+    PRSpecialFD stdioFd,
+    PRFileDesc *redirectFd)
+{
+#if defined(DEBUG)
+    static PRBool warn = PR_TRUE;
+    if (warn) {
+        warn = _PR_Obsolete("PR_SetStdioRedirect()",
+                "PR_ProcessAttrSetStdioRedirect()");
+    }
+#endif
+    PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd);
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ProcessAttrSetCurrentDirectory(
+    PRProcessAttr *attr,
+    const char *dir)
+{
+    PR_FREEIF(attr->currentDirectory);
+    attr->currentDirectory = (char *) PR_MALLOC(strlen(dir) + 1);
+    if (!attr->currentDirectory) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return PR_FAILURE;
+    }
+    strcpy(attr->currentDirectory, dir);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ProcessAttrSetInheritableFD(
+    PRProcessAttr *attr,
+    PRFileDesc *fd,
+    const char *name)
+{
+    /* We malloc the fd inherit buffer in multiples of this number. */
+#define FD_INHERIT_BUFFER_INCR 128
+    /* The length of "NSPR_INHERIT_FDS=" */
+#define NSPR_INHERIT_FDS_STRLEN 17
+    /* The length of osfd (PROsfd) printed in hexadecimal with 0x prefix */
+#ifdef _WIN64
+#define OSFD_STRLEN 18
+#else
+#define OSFD_STRLEN 10
+#endif
+    /* The length of fd type (PRDescType) printed in decimal */
+#define FD_TYPE_STRLEN 1
+    PRSize newSize;
+    int remainder;
+    char *newBuffer;
+    int nwritten;
+    char *cur;
+    int freeSize;
+
+    if (fd->identity != PR_NSPR_IO_LAYER) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (fd->secret->inheritable == _PR_TRI_UNKNOWN) {
+        _PR_MD_QUERY_FD_INHERITABLE(fd);
+    }
+    if (fd->secret->inheritable != _PR_TRI_TRUE) {
+        PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    /*
+     * We also need to account for the : separators and the
+     * terminating null byte.
+     */
+    if (NULL == attr->fdInheritBuffer) {
+        /* The first time, we print "NSPR_INHERIT_FDS=<name>:<type>:<val>" */
+        newSize = NSPR_INHERIT_FDS_STRLEN + strlen(name)
+                + FD_TYPE_STRLEN + OSFD_STRLEN + 2 + 1;
+    } else {
+        /* At other times, we print ":<name>:<type>:<val>" */
+        newSize = attr->fdInheritBufferUsed + strlen(name)
+                + FD_TYPE_STRLEN + OSFD_STRLEN + 3 + 1;
+    }
+    if (newSize > attr->fdInheritBufferSize) {
+        /* Make newSize a multiple of FD_INHERIT_BUFFER_INCR */
+        remainder = newSize % FD_INHERIT_BUFFER_INCR;
+        if (remainder != 0) {
+            newSize += (FD_INHERIT_BUFFER_INCR - remainder);
+        }
+        if (NULL == attr->fdInheritBuffer) {
+            newBuffer = (char *) PR_MALLOC(newSize);
+        } else {
+            newBuffer = (char *) PR_REALLOC(attr->fdInheritBuffer, newSize);
+        }
+        if (NULL == newBuffer) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return PR_FAILURE;
+        }
+        attr->fdInheritBuffer = newBuffer;
+        attr->fdInheritBufferSize = newSize;
+    }
+    cur = attr->fdInheritBuffer + attr->fdInheritBufferUsed;
+    freeSize = attr->fdInheritBufferSize - attr->fdInheritBufferUsed;
+    if (0 == attr->fdInheritBufferUsed) {
+        nwritten = PR_snprintf(cur, freeSize,
+                "NSPR_INHERIT_FDS=%s:%d:0x%" PR_PRIxOSFD,
+                name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd);
+    } else {
+        nwritten = PR_snprintf(cur, freeSize, ":%s:%d:0x%" PR_PRIxOSFD,
+                name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd);
+    }
+    attr->fdInheritBufferUsed += nwritten; 
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRFileDesc *) PR_GetInheritedFD(
+    const char *name)
+{
+    PRFileDesc *fd;
+    const char *envVar;
+    const char *ptr;
+    int len = strlen(name);
+    PROsfd osfd;
+    int nColons;
+    PRIntn fileType;
+
+    envVar = PR_GetEnv("NSPR_INHERIT_FDS");
+    if (NULL == envVar || '\0' == envVar[0]) {
+        PR_SetError(PR_UNKNOWN_ERROR, 0);
+        return NULL;
+    }
+
+    ptr = envVar;
+    while (1) {
+        if ((ptr[len] == ':') && (strncmp(ptr, name, len) == 0)) {
+            ptr += len + 1;
+            PR_sscanf(ptr, "%d:0x%" PR_SCNxOSFD, &fileType, &osfd);
+            switch ((PRDescType)fileType) {
+                case PR_DESC_FILE:
+                    fd = PR_ImportFile(osfd);
+                    break;
+                case PR_DESC_PIPE:
+                    fd = PR_ImportPipe(osfd);
+                    break;
+                case PR_DESC_SOCKET_TCP:
+                    fd = PR_ImportTCPSocket(osfd);
+                    break;
+                case PR_DESC_SOCKET_UDP:
+                    fd = PR_ImportUDPSocket(osfd);
+                    break;
+                default:
+                    PR_ASSERT(0);
+                    PR_SetError(PR_UNKNOWN_ERROR, 0);
+                    fd = NULL;
+                    break;
+            }
+            if (fd) {
+                /*
+                 * An inherited FD is inheritable by default.
+                 * The child process needs to call PR_SetFDInheritable
+                 * to make it non-inheritable if so desired.
+                 */
+                fd->secret->inheritable = _PR_TRI_TRUE;
+            }
+            return fd;
+        }
+        /* Skip three colons */
+        nColons = 0;
+        while (*ptr) {
+            if (*ptr == ':') {
+                if (++nColons == 3) {
+                    break;
+                }
+            }
+            ptr++;
+        }
+        if (*ptr == '\0') {
+            PR_SetError(PR_UNKNOWN_ERROR, 0);
+            return NULL;
+        }
+        ptr++;
+    }
+}
+
+PR_IMPLEMENT(PRProcess*) PR_CreateProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    return _PR_MD_CREATE_PROCESS(path, argv, envp, attr);
+}  /* PR_CreateProcess */
+
+PR_IMPLEMENT(PRStatus) PR_CreateProcessDetached(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    PRProcess *process;
+    PRStatus rv;
+
+    process = PR_CreateProcess(path, argv, envp, attr);
+    if (NULL == process) {
+	return PR_FAILURE;
+    }
+    rv = PR_DetachProcess(process);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (rv == PR_FAILURE) {
+	PR_DELETE(process);
+	return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DetachProcess(PRProcess *process)
+{
+    return _PR_MD_DETACH_PROCESS(process);
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode)
+{
+    return _PR_MD_WAIT_PROCESS(process, exitCode);
+}  /* PR_WaitProcess */
+
+PR_IMPLEMENT(PRStatus) PR_KillProcess(PRProcess *process)
+{
+    return _PR_MD_KILL_PROCESS(process);
+}
+
+/*
+ ********************************************************************
+ *
+ * Module initialization
+ *
+ ********************************************************************
+ */
+
+static struct {
+    PRLock *ml;
+    PRCondVar *cv;
+} mod_init;
+
+static void _PR_InitCallOnce(void) {
+    mod_init.ml = PR_NewLock();
+    PR_ASSERT(NULL != mod_init.ml);
+    mod_init.cv = PR_NewCondVar(mod_init.ml);
+    PR_ASSERT(NULL != mod_init.cv);
+}
+
+void _PR_CleanupCallOnce()
+{
+    PR_DestroyLock(mod_init.ml);
+    mod_init.ml = NULL;
+    PR_DestroyCondVar(mod_init.cv);
+    mod_init.cv = NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CallOnce(
+    PRCallOnceType *once,
+    PRCallOnceFN    func)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (!once->initialized) {
+	if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) {
+	    once->status = (*func)();
+	    PR_Lock(mod_init.ml);
+	    once->initialized = 1;
+	    PR_NotifyAllCondVar(mod_init.cv);
+	    PR_Unlock(mod_init.ml);
+	} else {
+	    PR_Lock(mod_init.ml);
+	    while (!once->initialized) {
+		PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
+            }
+	    PR_Unlock(mod_init.ml);
+	}
+    } else {
+        if (PR_SUCCESS != once->status) {
+            PR_SetError(PR_CALL_ONCE_ERROR, 0);
+        }
+    }
+    return once->status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
+    PRCallOnceType      *once,
+    PRCallOnceWithArgFN  func,
+    void                *arg)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (!once->initialized) {
+	if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) {
+	    once->status = (*func)(arg);
+	    PR_Lock(mod_init.ml);
+	    once->initialized = 1;
+	    PR_NotifyAllCondVar(mod_init.cv);
+	    PR_Unlock(mod_init.ml);
+	} else {
+	    PR_Lock(mod_init.ml);
+	    while (!once->initialized) {
+		PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
+            }
+	    PR_Unlock(mod_init.ml);
+	}
+    } else {
+        if (PR_SUCCESS != once->status) {
+            PR_SetError(PR_CALL_ONCE_ERROR, 0);
+        }
+    }
+    return once->status;
+}
+
+PRBool _PR_Obsolete(const char *obsolete, const char *preferred)
+{
+#if defined(DEBUG)
+    PR_fprintf(
+        PR_STDERR, "'%s' is obsolete. Use '%s' instead.\n",
+        obsolete, (NULL == preferred) ? "something else" : preferred);
+#endif
+    return PR_FALSE;
+}  /* _PR_Obsolete */
+
+/* prinit.c */
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prinrval.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prinrval.c
new file mode 100644
index 0000000..17229e8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prinrval.c
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * file:			prinrval.c
+ * description:		implementation for the kernel interval timing functions
+ */
+
+#include "primpl.h"
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * _PR_InitClock --
+ *
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void _PR_InitClock(void)
+{
+    _PR_MD_INTERVAL_INIT();
+#ifdef DEBUG
+    {
+        PRIntervalTime ticksPerSec = PR_TicksPerSecond();
+
+        PR_ASSERT(ticksPerSec >= PR_INTERVAL_MIN);
+        PR_ASSERT(ticksPerSec <= PR_INTERVAL_MAX);
+    }
+#endif /* DEBUG */
+}
+
+/*
+ * This version of interval times is based on the time of day
+ * capability offered by system. This isn't valid for two reasons:
+ * 1) The time of day is neither linear nor montonically increasing
+ * 2) The units here are milliseconds. That's not appropriate for our use.
+ */
+
+PR_IMPLEMENT(PRIntervalTime) PR_IntervalNow(void)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return _PR_MD_GET_INTERVAL();
+}  /* PR_IntervalNow */
+
+PR_EXTERN(PRUint32) PR_TicksPerSecond(void)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return _PR_MD_INTERVAL_PER_SEC();
+}  /* PR_TicksPerSecond */
+
+PR_IMPLEMENT(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds)
+{
+    return seconds * PR_TicksPerSecond();
+}  /* PR_SecondsToInterval */
+
+PR_IMPLEMENT(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli)
+{
+    PRIntervalTime ticks;
+    PRUint64 tock, tps, msecPerSec, rounding;
+    LL_UI2L(tock, milli);
+    LL_I2L(msecPerSec, PR_MSEC_PER_SEC);
+    LL_I2L(rounding, (PR_MSEC_PER_SEC >> 1));
+    LL_I2L(tps, PR_TicksPerSecond());
+    LL_MUL(tock, tock, tps);
+    LL_ADD(tock, tock, rounding);
+    LL_DIV(tock, tock, msecPerSec);
+    LL_L2UI(ticks, tock);
+    return ticks;
+}  /* PR_MillisecondsToInterval */
+
+PR_IMPLEMENT(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro)
+{
+    PRIntervalTime ticks;
+    PRUint64 tock, tps, usecPerSec, rounding;
+    LL_UI2L(tock, micro);
+    LL_I2L(usecPerSec, PR_USEC_PER_SEC);
+    LL_I2L(rounding, (PR_USEC_PER_SEC >> 1));
+    LL_I2L(tps, PR_TicksPerSecond());
+    LL_MUL(tock, tock, tps);
+    LL_ADD(tock, tock, rounding);
+    LL_DIV(tock, tock, usecPerSec);
+    LL_L2UI(ticks, tock);
+    return ticks;
+}  /* PR_MicrosecondsToInterval */
+
+PR_IMPLEMENT(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks)
+{
+    return ticks / PR_TicksPerSecond();
+}  /* PR_IntervalToSeconds */
+
+PR_IMPLEMENT(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks)
+{
+    PRUint32 milli;
+    PRUint64 tock, tps, msecPerSec, rounding;
+    LL_UI2L(tock, ticks);
+    LL_I2L(msecPerSec, PR_MSEC_PER_SEC);
+    LL_I2L(tps, PR_TicksPerSecond());
+    LL_USHR(rounding, tps, 1);
+    LL_MUL(tock, tock, msecPerSec);
+    LL_ADD(tock, tock, rounding);
+    LL_DIV(tock, tock, tps);
+    LL_L2UI(milli, tock);
+    return milli;
+}  /* PR_IntervalToMilliseconds */
+
+PR_IMPLEMENT(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks)
+{
+    PRUint32 micro;
+    PRUint64 tock, tps, usecPerSec, rounding;
+    LL_UI2L(tock, ticks);
+    LL_I2L(usecPerSec, PR_USEC_PER_SEC);
+    LL_I2L(tps, PR_TicksPerSecond());
+    LL_USHR(rounding, tps, 1);
+    LL_MUL(tock, tock, usecPerSec);
+    LL_ADD(tock, tock, rounding);
+    LL_DIV(tock, tock, tps);
+    LL_L2UI(micro, tock);
+    return micro;
+}  /* PR_IntervalToMicroseconds */
+
+/* prinrval.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pripc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pripc.c
new file mode 100644
index 0000000..cb16aad
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pripc.c
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: pripc.c
+ *
+ * Description: functions for IPC support
+ */
+
+#include "primpl.h"
+
+#include <string.h>
+
+/*
+ * A POSIX IPC name must begin with a '/'.
+ * A POSIX IPC name on Solaris cannot contain any '/' except
+ * the required leading '/'.
+ * A POSIX IPC name on HP-UX and OSF1 must be a valid pathname
+ * in the file system.
+ *
+ * The ftok() function for System V IPC requires a valid pathname
+ * in the file system.
+ *
+ * A Win32 IPC name cannot contain '\'.
+ */
+
+static void _pr_ConvertSemName(char *result)
+{
+#ifdef _PR_HAVE_POSIX_SEMAPHORES
+#if defined(SOLARIS)
+    char *p;
+
+    /* Convert '/' to '_' except for the leading '/' */
+    for (p = result+1; *p; p++) {
+        if (*p == '/') {
+            *p = '_';
+        }
+    }
+    return;
+#else
+    return;
+#endif
+#elif defined(_PR_HAVE_SYSV_SEMAPHORES)
+    return;
+#elif defined(WIN32)
+    return;
+#endif
+}
+
+static void _pr_ConvertShmName(char *result)
+{
+#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY)
+#if defined(SOLARIS)
+    char *p;
+
+    /* Convert '/' to '_' except for the leading '/' */
+    for (p = result+1; *p; p++) {
+        if (*p == '/') {
+            *p = '_';
+        }
+    }
+    return;
+#else
+    return;
+#endif
+#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY)
+    return;
+#elif defined(WIN32)
+    return;
+#else
+    return;
+#endif
+}
+
+PRStatus _PR_MakeNativeIPCName(
+    const char *name,
+    char *result,
+    PRIntn size,
+    _PRIPCType type)
+{
+    if (strlen(name) >= (PRSize)size) {
+        PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+        return PR_FAILURE;
+    }
+    strcpy(result, name);
+    switch (type) {
+        case _PRIPCSem:
+            _pr_ConvertSemName(result);
+            break;
+        case _PRIPCShm:
+            _pr_ConvertShmName(result);
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pripcsem.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pripcsem.c
new file mode 100644
index 0000000..c6c59ec
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/pripcsem.c
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: pripcsem.c
+ *
+ * Description: implements the named semaphores API in prsemipc.h
+ * for classic NSPR.  If _PR_HAVE_NAMED_SEMAPHORES is not defined,
+ * the named semaphore functions all fail with the error code
+ * PR_NOT_IMPLEMENTED_ERROR.
+ */
+
+#include "primpl.h"
+
+#ifdef _PR_PTHREADS
+
+#error "This file should not be compiled for the pthreads version"
+
+#else
+
+#ifndef _PR_HAVE_NAMED_SEMAPHORES
+
+PRSem * _PR_MD_OPEN_SEMAPHORE(
+    const char *osname, PRIntn flags, PRIntn mode, PRUintn value)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+#endif /* !_PR_HAVE_NAMED_SEMAPHORES */
+
+PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(
+    const char *name, PRIntn flags, PRIntn mode, PRUintn value)
+{
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+            == PR_FAILURE) {
+        return NULL;
+    }
+    return _PR_MD_OPEN_SEMAPHORE(osname, flags, mode, value);
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem)
+{
+    return _PR_MD_WAIT_SEMAPHORE(sem);
+}
+
+PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem)
+{
+    return _PR_MD_POST_SEMAPHORE(sem);
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem)
+{
+    return _PR_MD_CLOSE_SEMAPHORE(sem);
+}
+
+PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
+{
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+            == PR_FAILURE) {
+        return PR_FAILURE;
+    }
+    return _PR_MD_DELETE_SEMAPHORE(osname);
+}
+
+#endif /* _PR_PTHREADS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prlog2.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prlog2.c
new file mode 100644
index 0000000..979be95
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prlog2.c
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prbit.h"
+
+/*
+** Compute the log of the least power of 2 greater than or equal to n
+*/
+PR_IMPLEMENT(PRIntn) PR_CeilingLog2(PRUint32 n)
+{
+    PRIntn log2;
+    PR_CEILING_LOG2(log2, n);
+    return log2;
+}
+
+/*
+** Compute the log of the greatest power of 2 less than or equal to n.
+** This really just finds the highest set bit in the word.
+*/
+PR_IMPLEMENT(PRIntn) PR_FloorLog2(PRUint32 n)
+{
+    PRIntn log2;
+    PR_FLOOR_LOG2(log2, n);
+    return log2;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prlong.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prlong.c
new file mode 100644
index 0000000..650d4bc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prlong.c
@@ -0,0 +1,271 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+static PRInt64 ll_zero = LL_INIT( 0x00000000,0x00000000 );
+static PRInt64 ll_maxint = LL_INIT( 0x7fffffff, 0xffffffff );
+static PRInt64 ll_minint = LL_INIT( 0x80000000, 0x00000000 );
+static PRUint64 ll_maxuint = LL_INIT( 0xffffffff, 0xffffffff );
+
+PR_IMPLEMENT(PRInt64) LL_Zero(void) { return ll_zero; }
+PR_IMPLEMENT(PRInt64) LL_MaxInt(void) { return ll_maxint; }
+PR_IMPLEMENT(PRInt64) LL_MinInt(void) { return ll_minint; }
+PR_IMPLEMENT(PRUint64) LL_MaxUint(void) { return ll_maxuint; }
+
+#ifndef HAVE_LONG_LONG
+/*
+** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1.
+*/
+static void norm_udivmod32(PRUint32 *qp, PRUint32 *rp, PRUint64 a, PRUint32 b)
+{
+    PRUint32 d1, d0, q1, q0;
+    PRUint32 r1, r0, m;
+
+    d1 = _hi16(b);
+    d0 = _lo16(b);
+    r1 = a.hi % d1;
+    q1 = a.hi / d1;
+    m = q1 * d0;
+    r1 = (r1 << 16) | _hi16(a.lo);
+    if (r1 < m) {
+        q1--, r1 += b;
+        if (r1 >= b	/* i.e., we didn't get a carry when adding to r1 */
+	    && r1 < m) {
+	    q1--, r1 += b;
+	}
+    }
+    r1 -= m;
+    r0 = r1 % d1;
+    q0 = r1 / d1;
+    m = q0 * d0;
+    r0 = (r0 << 16) | _lo16(a.lo);
+    if (r0 < m) {
+        q0--, r0 += b;
+        if (r0 >= b
+	    && r0 < m) {
+	    q0--, r0 += b;
+	}
+    }
+    *qp = (q1 << 16) | q0;
+    *rp = r0 - m;
+}
+
+static PRUint32 CountLeadingZeros(PRUint32 a)
+{
+    PRUint32 t;
+    PRUint32 r = 32;
+
+    if ((t = a >> 16) != 0)
+	r -= 16, a = t;
+    if ((t = a >> 8) != 0)
+	r -= 8, a = t;
+    if ((t = a >> 4) != 0)
+	r -= 4, a = t;
+    if ((t = a >> 2) != 0)
+	r -= 2, a = t;
+    if ((t = a >> 1) != 0)
+	r -= 1, a = t;
+    if (a & 1)
+	r--;
+    return r;
+}
+
+PR_IMPLEMENT(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b)
+{
+    PRUint32 n0, n1, n2;
+    PRUint32 q0, q1;
+    PRUint32 rsh, lsh;
+
+    n0 = a.lo;
+    n1 = a.hi;
+
+    if (b.hi == 0) {
+	if (b.lo > n1) {
+	    /* (0 q0) = (n1 n0) / (0 D0) */
+
+	    lsh = CountLeadingZeros(b.lo);
+
+	    if (lsh) {
+		/*
+		 * Normalize, i.e. make the most significant bit of the
+		 * denominator be set.
+		 */
+		b.lo = b.lo << lsh;
+		n1 = (n1 << lsh) | (n0 >> (32 - lsh));
+		n0 = n0 << lsh;
+	    }
+
+	    a.lo = n0, a.hi = n1;
+	    norm_udivmod32(&q0, &n0, a, b.lo);
+	    q1 = 0;
+
+	    /* remainder is in n0 >> lsh */
+	} else {
+	    /* (q1 q0) = (n1 n0) / (0 d0) */
+
+	    if (b.lo == 0)		/* user wants to divide by zero! */
+		b.lo = 1 / b.lo;	/* so go ahead and crash */
+
+	    lsh = CountLeadingZeros(b.lo);
+
+	    if (lsh == 0) {
+		/*
+		 * From (n1 >= b.lo)
+		 *   && (the most significant bit of b.lo is set),
+		 * conclude that
+		 *	(the most significant bit of n1 is set)
+		 *   && (the leading quotient digit q1 = 1).
+		 *
+		 * This special case is necessary, not an optimization
+		 * (Shifts counts of 32 are undefined).
+		 */
+		n1 -= b.lo;
+		q1 = 1;
+	    } else {
+		/*
+		 * Normalize.
+		 */
+		rsh = 32 - lsh;
+
+		b.lo = b.lo << lsh;
+		n2 = n1 >> rsh;
+		n1 = (n1 << lsh) | (n0 >> rsh);
+		n0 = n0 << lsh;
+
+		a.lo = n1, a.hi = n2;
+		norm_udivmod32(&q1, &n1, a, b.lo);
+	    }
+
+	    /* n1 != b.lo... */
+
+	    a.lo = n0, a.hi = n1;
+	    norm_udivmod32(&q0, &n0, a, b.lo);
+
+	    /* remainder in n0 >> lsh */
+	}
+
+	if (rp) {
+	    rp->lo = n0 >> lsh;
+	    rp->hi = 0;
+	}
+    } else {
+	if (b.hi > n1) {
+	    /* (0 0) = (n1 n0) / (D1 d0) */
+
+	    q0 = 0;
+	    q1 = 0;
+
+	    /* remainder in (n1 n0) */
+	    if (rp) {
+		rp->lo = n0;
+		rp->hi = n1;
+	    }
+	} else {
+	    /* (0 q0) = (n1 n0) / (d1 d0) */
+
+	    lsh = CountLeadingZeros(b.hi);
+	    if (lsh == 0) {
+		/*
+		 * From (n1 >= b.hi)
+		 *   && (the most significant bit of b.hi is set),
+		 * conclude that
+		 *      (the most significant bit of n1 is set)
+		 *   && (the quotient digit q0 = 0 or 1).
+		 *
+		 * This special case is necessary, not an optimization.
+		 */
+
+		/*
+		 * The condition on the next line takes advantage of that
+		 * n1 >= b.hi (true due to control flow).
+		 */
+		if (n1 > b.hi || n0 >= b.lo) {
+		    q0 = 1;
+		    a.lo = n0, a.hi = n1;
+		    LL_SUB(a, a, b);
+		} else {
+		    q0 = 0;
+		}
+		q1 = 0;
+
+		if (rp) {
+		    rp->lo = n0;
+		    rp->hi = n1;
+		}
+	    } else {
+		PRInt64 m;
+
+		/*
+		 * Normalize.
+		 */
+		rsh = 32 - lsh;
+
+		b.hi = (b.hi << lsh) | (b.lo >> rsh);
+		b.lo = b.lo << lsh;
+		n2 = n1 >> rsh;
+		n1 = (n1 << lsh) | (n0 >> rsh);
+		n0 = n0 << lsh;
+
+		a.lo = n1, a.hi = n2;
+		norm_udivmod32(&q0, &n1, a, b.hi);
+		LL_MUL32(m, q0, b.lo);
+
+		if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
+		    q0--;
+		    LL_SUB(m, m, b);
+		}
+
+		q1 = 0;
+
+		/* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
+		if (rp) {
+		    a.lo = n0, a.hi = n1;
+		    LL_SUB(a, a, m);
+		    rp->lo = (a.hi << rsh) | (a.lo >> lsh);
+		    rp->hi = a.hi >> lsh;
+		}
+	    }
+	}
+    }
+
+    if (qp) {
+	qp->lo = q0;
+	qp->hi = q1;
+    }
+}
+#endif /* !HAVE_LONG_LONG */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prnetdb.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prnetdb.c
new file mode 100644
index 0000000..355f3c8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prnetdb.c
@@ -0,0 +1,2343 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+
+/*
+ * On Unix, the error code for gethostbyname() and gethostbyaddr()
+ * is returned in the global variable h_errno, instead of the usual
+ * errno.
+ */
+#if defined(XP_UNIX)
+#if defined(_PR_NEED_H_ERRNO)
+extern int h_errno;
+#endif
+#define _MD_GETHOST_ERRNO() h_errno
+#else
+#define _MD_GETHOST_ERRNO() _MD_ERRNO()
+#endif
+
+/*
+ * The meaning of the macros related to gethostbyname, gethostbyaddr,
+ * and gethostbyname2 is defined below.
+ * - _PR_HAVE_THREADSAFE_GETHOST: the gethostbyXXX functions return
+ *   the result in thread specific storage.  For example, AIX, HP-UX,
+ *   and OSF1.
+ * -  _PR_HAVE_GETHOST_R: have the gethostbyXXX_r functions. See next
+ *   two macros.
+ * - _PR_HAVE_GETHOST_R_INT: the gethostbyXXX_r functions return an
+ *   int.  For example, Linux glibc.
+ * - _PR_HAVE_GETHOST_R_POINTER: the gethostbyXXX_r functions return
+ *   a struct hostent* pointer.  For example, Solaris and IRIX.
+ */
+#if defined(_PR_NO_PREEMPT) || defined(_PR_HAVE_GETHOST_R) \
+    || defined(_PR_HAVE_THREADSAFE_GETHOST)
+#define _PR_NO_DNS_LOCK
+#endif
+
+#if defined(_PR_NO_DNS_LOCK)
+#define LOCK_DNS()
+#define UNLOCK_DNS()
+#else
+PRLock *_pr_dnsLock = NULL;
+#define LOCK_DNS() PR_Lock(_pr_dnsLock)
+#define UNLOCK_DNS() PR_Unlock(_pr_dnsLock)
+#endif  /* defined(_PR_NO_DNS_LOCK) */
+
+/*
+ * Some platforms have the reentrant getprotobyname_r() and
+ * getprotobynumber_r().  However, they come in three flavors.
+ * Some return a pointer to struct protoent, others return
+ * an int, and glibc's flavor takes five arguments.
+ */
+#if defined(XP_BEOS) && defined(BONE_VERSION)
+#include <arpa/inet.h>  /* pick up define for inet_addr */
+#include <sys/socket.h>
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_GETPROTO_R_POINTER
+#endif
+
+#if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \
+	|| (defined(LINUX) && defined(_REENTRANT) \
+        && !(defined(__GLIBC__) && __GLIBC__ >= 2)) \
+        && !defined(ANDROID)
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_GETPROTO_R_POINTER
+#endif
+
+#if defined(OSF1) \
+        || defined(AIX4_3_PLUS) || (defined(AIX) && defined(_THREAD_SAFE)) \
+	|| (defined(HPUX10_10) && defined(_REENTRANT)) \
+        || (defined(HPUX10_20) && defined(_REENTRANT)) \
+        || defined(OPENBSD)
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_GETPROTO_R_INT
+#endif
+
+#if __FreeBSD_version >= 602000
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_5_ARG_GETPROTO_R
+#endif
+
+/* BeOS has glibc but not the glibc-style getprotobyxxx_r functions. */
+#if (defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(XP_BEOS))
+#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_PROBE)
+extern PRBool _pr_ipv6_is_present(void);
+#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])
+
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+
+/*
+ * The _pr_QueryNetIfs() function finds out if the system has
+ * IPv4 or IPv6 source addresses configured and sets _pr_have_inet_if
+ * and _pr_have_inet6_if accordingly.
+ *
+ * We have an implementation using SIOCGIFCONF ioctl and a
+ * default implementation that simply sets _pr_have_inet_if
+ * and _pr_have_inet6_if to true.  A better implementation
+ * would be to use the routing sockets (see Chapter 17 of
+ * W. Richard Stevens' Unix Network Programming, Vol. 1, 2nd. Ed.)
+ */
+
+static PRLock *_pr_query_ifs_lock = NULL;
+static PRBool _pr_have_inet_if = PR_FALSE;
+static PRBool _pr_have_inet6_if = PR_FALSE;
+
+#undef DEBUG_QUERY_IFS
+
+#if defined(AIX) \
+    || (defined(DARWIN) && (!defined(HAVE_GETIFADDRS) \
+        || (defined(XP_MACOSX) && (!defined(MAC_OS_X_VERSION_10_2) || \
+        MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2))))
+
+/*
+ * Use SIOCGIFCONF ioctl on platforms that don't have routing
+ * sockets.  Warning: whether SIOCGIFCONF ioctl returns AF_INET6
+ * network interfaces is not portable.
+ *
+ * The _pr_QueryNetIfs() function is derived from the code in
+ * src/lib/libc/net/getifaddrs.c in BSD Unix and the code in
+ * Section 16.6 of W. Richard Stevens' Unix Network Programming,
+ * Vol. 1, 2nd. Ed.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+
+#ifdef DEBUG_QUERY_IFS
+static void
+_pr_PrintIfreq(struct ifreq *ifr)
+{
+    PRNetAddr addr;
+    struct sockaddr *sa;
+    const char* family;
+    char addrstr[64];
+
+    sa = &ifr->ifr_addr;
+    if (sa->sa_family == AF_INET) {
+        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+        family = "inet";
+        memcpy(&addr.inet.ip, &sin->sin_addr, sizeof(sin->sin_addr));
+    } else if (sa->sa_family == AF_INET6) {
+        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+        family = "inet6";
+        memcpy(&addr.ipv6.ip, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
+    } else {
+        return;  /* skip if not AF_INET or AF_INET6 */
+    }
+    addr.raw.family = sa->sa_family;
+    PR_NetAddrToString(&addr, addrstr, sizeof(addrstr));
+    printf("%s: %s %s\n", ifr->ifr_name, family, addrstr);
+}
+#endif
+
+static void
+_pr_QueryNetIfs(void)
+{
+    int sock;
+    int rv;
+    struct ifconf ifc;
+    struct ifreq *ifr;
+    struct ifreq *lifr;
+    PRUint32 len, lastlen;
+    char *buf;
+
+    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+        return;
+    }
+
+    /* Issue SIOCGIFCONF request in a loop. */
+    lastlen = 0;
+    len = 100 * sizeof(struct ifreq);  /* initial buffer size guess */
+    for (;;) {
+        buf = (char *)PR_Malloc(len);
+        if (NULL == buf) {
+            close(sock);
+            return;
+        }
+        ifc.ifc_buf = buf;
+        ifc.ifc_len = len;
+        rv = ioctl(sock, SIOCGIFCONF, &ifc);
+        if (rv < 0) {
+            if (errno != EINVAL || lastlen != 0) {
+                close(sock);
+                PR_Free(buf);
+                return;
+            }
+        } else {
+            if (ifc.ifc_len == lastlen)
+                break;  /* success, len has not changed */
+            lastlen = ifc.ifc_len;
+        }
+        len += 10 * sizeof(struct ifreq);  /* increment */
+        PR_Free(buf);
+    }
+    close(sock);
+
+    ifr = ifc.ifc_req;
+    lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
+
+    while (ifr < lifr) {
+        struct sockaddr *sa;
+        int sa_len;
+
+#ifdef DEBUG_QUERY_IFS
+        _pr_PrintIfreq(ifr);
+#endif
+        sa = &ifr->ifr_addr;
+        if (sa->sa_family == AF_INET) {
+            struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+            if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+                _pr_have_inet_if = PR_TRUE;
+            } 
+        } else if (sa->sa_family == AF_INET6) {
+            struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+            if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)
+                    && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+                _pr_have_inet6_if = PR_TRUE;
+            } 
+        }
+
+#ifdef _PR_HAVE_SOCKADDR_LEN
+        sa_len = PR_MAX(sa->sa_len, sizeof(struct sockaddr));
+#else
+        switch (sa->sa_family) {
+#ifdef AF_LINK
+        case AF_LINK:
+            sa_len = sizeof(struct sockaddr_dl);
+            break;
+#endif
+        case AF_INET6:
+            sa_len = sizeof(struct sockaddr_in6);
+            break;
+        default:
+            sa_len = sizeof(struct sockaddr);
+            break;
+        }
+#endif
+        ifr = (struct ifreq *)(((char *)sa) + sa_len);
+    }
+    PR_Free(buf);
+}
+
+#elif (defined(DARWIN) && defined(HAVE_GETIFADDRS)) || defined(FREEBSD) \
+    || defined(NETBSD) || defined(OPENBSD)
+
+/*
+ * Use the BSD getifaddrs function.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+
+#ifdef DEBUG_QUERY_IFS
+static void
+_pr_PrintIfaddrs(struct ifaddrs *ifa)
+{
+    struct sockaddr *sa;
+    const char* family;
+    void *addrp;
+    char addrstr[64];
+
+    sa = ifa->ifa_addr;
+    if (sa->sa_family == AF_INET) {
+        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+        family = "inet";
+        addrp = &sin->sin_addr;
+    } else if (sa->sa_family == AF_INET6) {
+        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+        family = "inet6";
+        addrp = &sin6->sin6_addr;
+    } else {
+        return;  /* skip if not AF_INET or AF_INET6 */
+    }
+    inet_ntop(sa->sa_family, addrp, addrstr, sizeof(addrstr));
+    printf("%s: %s %s\n", ifa->ifa_name, family, addrstr);
+}
+#endif
+
+static void
+_pr_QueryNetIfs(void)
+{
+    struct ifaddrs *ifp;
+    struct ifaddrs *ifa;
+
+    if (getifaddrs(&ifp) == -1) {
+        return;
+    }
+    for (ifa = ifp; ifa; ifa = ifa->ifa_next) {
+        struct sockaddr *sa;
+
+#ifdef DEBUG_QUERY_IFS
+        _pr_PrintIfaddrs(ifa);
+#endif
+        sa = ifa->ifa_addr;
+        if (sa->sa_family == AF_INET) {
+            struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+            if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+                _pr_have_inet_if = 1;
+            } 
+        } else if (sa->sa_family == AF_INET6) {
+            struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+            if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)
+                    && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+                _pr_have_inet6_if = 1;
+            } 
+        }
+    } 
+    freeifaddrs(ifp);
+}
+
+#else  /* default */
+
+/*
+ * Emulate the code in NSPR 4.2 or older.  PR_GetIPNodeByName behaves
+ * as if the system had both IPv4 and IPv6 source addresses configured.
+ */
+static void
+_pr_QueryNetIfs(void)
+{
+    _pr_have_inet_if = PR_TRUE;
+    _pr_have_inet6_if = PR_TRUE;
+}
+
+#endif
+
+#endif  /* _PR_INET6 && _PR_HAVE_GETHOSTBYNAME2 */
+
+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.
+	 */
+	 (void)setnetconfig();
+#endif
+#endif
+#if !defined(_PR_NO_DNS_LOCK)
+	_pr_dnsLock = PR_NewLock();
+#endif
+#if !defined(_PR_HAVE_GETPROTO_R)
+	_getproto_lock = PR_NewLock();
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+	_pr_query_ifs_lock = PR_NewLock();
+#endif
+}
+
+void _PR_CleanupNet(void)
+{
+#if !defined(_PR_NO_DNS_LOCK)
+    if (_pr_dnsLock) {
+        PR_DestroyLock(_pr_dnsLock);
+        _pr_dnsLock = NULL;
+    }
+#endif
+#if !defined(_PR_HAVE_GETPROTO_R)
+    if (_getproto_lock) {
+        PR_DestroyLock(_getproto_lock);
+        _getproto_lock = NULL;
+    }
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+    if (_pr_query_ifs_lock) {
+        PR_DestroyLock(_pr_query_ifs_lock);
+        _pr_query_ifs_lock = NULL;
+    }
+#endif
+}
+
+/*
+** 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)
+{
+	char *buf = *bufp;
+	PRIntn buflen = *buflenp;
+
+	if (align && ((long)buf & (align - 1))) {
+		PRIntn skip = align - ((ptrdiff_t)buf & (align - 1));
+		if (buflen < skip) {
+			return 0;
+		}
+		buf += skip;
+		buflen -= skip;
+	}
+	if (buflen < amount) {
+		return 0;
+	}
+	*bufp = buf + amount;
+	*buflenp = buflen - amount;
+	return buf;
+}
+
+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);
+}
+
+/*
+** 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);
+}
+
+/*
+** 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,
+    _PRIPAddrConversion conversion,
+    PRHostEnt *to)
+{
+	PRIntn len, na;
+	char **ap;
+
+	if (conversion != _PRIPAddrNoConversion
+			&& from->h_addrtype == AF_INET) {
+		PR_ASSERT(from->h_length == 4);
+		to->h_addrtype = PR_AF_INET6;
+		to->h_length = 16;
+	} else {
+#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;
+	}
+
+	/* 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);
+	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**));
+	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);
+			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**));
+	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);
+		if (!to->h_addr_list[na]) return PR_FAILURE;
+		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);
+		}
+	}
+	to->h_addr_list[na] = 0;
+	return PR_SUCCESS;
+}
+
+#ifdef SYMBIAN
+/* Set p_aliases by hand because Symbian's getprotobyname() returns NULL. */
+static void AssignAliases(struct protoent *Protoent, char** aliases)
+{
+    if (NULL == Protoent->p_aliases) {
+        if (0 == strcmp(Protoent->p_name, "ip"))
+            aliases[0] = "IP";
+        else if (0 == strcmp(Protoent->p_name, "tcp"))
+            aliases[0] = "TCP";
+        else if (0 == strcmp(Protoent->p_name, "udp"))
+            aliases[0] = "UDP";
+        else
+            aliases[0] = "UNKNOWN";
+        aliases[1] = NULL;
+        Protoent->p_aliases = aliases;
+    }
+}
+#endif
+
+#if !defined(_PR_HAVE_GETPROTO_R)
+/*
+** Copy a protoent, and all of the memory that it refers to into
+** (hopefully) stacked buffers.
+*/
+static PRStatus CopyProtoent(
+    struct protoent *from, char *buf, PRIntn bufsize, PRProtoEnt *to)
+{
+	PRIntn len, na;
+	char **ap;
+
+	/* Do the easy stuff */
+	to->p_num = from->p_proto;
+
+	/* Copy the official name */
+	if (!from->p_name) return PR_FAILURE;
+	len = strlen(from->p_name) + 1;
+	to->p_name = Alloc(len, &buf, &bufsize, 0);
+	if (!to->p_name) return PR_FAILURE;
+	memcpy(to->p_name, from->p_name, len);
+
+	/* Count the aliases, then allocate storage for the pointers */
+	for (na = 1, ap = from->p_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */
+	to->p_aliases = (char**)Alloc(
+	    na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+	if (!to->p_aliases) return PR_FAILURE;
+
+	/* Copy the aliases, one at a time */
+	for (na = 0, ap = from->p_aliases; *ap != 0; na++, ap++) {
+		len = strlen(*ap) + 1;
+		to->p_aliases[na] = Alloc(len, &buf, &bufsize, 0);
+		if (!to->p_aliases[na]) return PR_FAILURE;
+		memcpy(to->p_aliases[na], *ap, len);
+	}
+	to->p_aliases[na] = 0;
+
+	return PR_SUCCESS;
+}
+#endif /* !defined(_PR_HAVE_GETPROTO_R) */
+
+/*
+ * #################################################################
+ * NOTE: tmphe, tmpbuf, bufsize, h, and h_err are local variables
+ * or arguments of PR_GetHostByName, PR_GetIPNodeByName, and
+ * PR_GetHostByAddr.  DO NOT CHANGE THE NAMES OF THESE LOCAL 
+ * VARIABLES OR ARGUMENTS.
+ * #################################################################
+ */
+#if defined(_PR_HAVE_GETHOST_R_INT)
+
+#define GETHOSTBYNAME(name) \
+    (gethostbyname_r(name, &tmphe, tmpbuf, bufsize, &h, &h_err), h)
+#define GETHOSTBYNAME2(name, af) \
+    (gethostbyname2_r(name, af, &tmphe, tmpbuf, bufsize, &h, &h_err), h)
+#define GETHOSTBYADDR(addr, addrlen, af) \
+    (gethostbyaddr_r(addr, addrlen, af, \
+    &tmphe, tmpbuf, bufsize, &h, &h_err), h)
+
+#elif defined(_PR_HAVE_GETHOST_R_POINTER)
+
+#define GETHOSTBYNAME(name) \
+    gethostbyname_r(name, &tmphe, tmpbuf, bufsize, &h_err)
+#define GETHOSTBYNAME2(name, af) \
+    gethostbyname2_r(name, af, &tmphe, tmpbuf, bufsize, &h_err)
+#define GETHOSTBYADDR(addr, addrlen, af) \
+    gethostbyaddr_r(addr, addrlen, af, &tmphe, tmpbuf, bufsize, &h_err)
+
+#else
+
+#define GETHOSTBYNAME(name) gethostbyname(name)
+#define GETHOSTBYNAME2(name, af) gethostbyname2(name, af)
+#define GETHOSTBYADDR(addr, addrlen, af) gethostbyaddr(addr, addrlen, af)
+
+#endif  /* definition of GETHOSTBYXXX */
+
+PR_IMPLEMENT(PRStatus) PR_GetHostByName(
+    const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp)
+{
+	struct hostent *h;
+	PRStatus rv = PR_FAILURE;
+#if defined(_PR_HAVE_GETHOST_R)
+    char localbuf[PR_NETDB_BUF_SIZE];
+    char *tmpbuf;
+    struct hostent tmphe;
+    int h_err;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if defined(_PR_HAVE_GETHOST_R)
+    tmpbuf = localbuf;
+    if (bufsize > sizeof(localbuf))
+    {
+        tmpbuf = (char *)PR_Malloc(bufsize);
+        if (NULL == tmpbuf)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return rv;
+        }
+    }
+#endif
+
+	LOCK_DNS();
+
+	h = GETHOSTBYNAME(name);
+    
+	if (NULL == h)
+	{
+	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
+	}
+	else
+	{
+		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
+		if (PR_SUCCESS != rv)
+		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+	}
+	UNLOCK_DNS();
+#if defined(_PR_HAVE_GETHOST_R)
+    if (tmpbuf != localbuf)
+        PR_Free(tmpbuf);
+#endif
+	return rv;
+}
+
+#if !defined(_PR_INET6) && \
+        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 *);
+static void * _pr_getipnodebyname_fp;
+static void * _pr_getipnodebyaddr_fp;
+static void * _pr_freehostent_fp;
+
+/*
+ * Look up the addresses of getipnodebyname, getipnodebyaddr,
+ * and freehostent.
+ */
+PRStatus
+_pr_find_getipnodebyname(void)
+{
+    PRLibrary *lib;	
+    PRStatus rv;
+#define GETIPNODEBYNAME "getipnodebyname"
+#define GETIPNODEBYADDR "getipnodebyaddr"
+#define FREEHOSTENT     "freehostent"
+
+    _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)
+                rv = PR_SUCCESS;
+            else
+                rv = PR_FAILURE;
+        } else
+            rv = PR_FAILURE;
+        (void)PR_UnloadLibrary(lib);
+    } else
+        rv = PR_FAILURE;
+    return rv;
+}
+#endif
+
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+/*
+** Append the V4 addresses to the end of the list
+*/
+static PRStatus AppendV4AddrsToHostent(
+    struct hostent *from,
+    char **buf,
+    PRIntn *bufsize,
+    PRHostEnt *to)
+{
+    PRIntn na, na_old;
+    char **ap;
+    char **new_addr_list;
+			
+    /* Count the addresses, then grow storage for the pointers */
+    for (na_old = 0, ap = to->h_addr_list; *ap != 0; na_old++, ap++)
+        {;} /* nothing to execute */
+    for (na = na_old + 1, ap = from->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 = to->h_addr_list; *ap != 0; na++, ap++) {
+        new_addr_list[na] = to->h_addr_list[na];
+    }
+    to->h_addr_list = new_addr_list;
+
+    /* Copy the V4 addresses, one at a time */
+    for (ap = from->h_addr_list; *ap != 0; na++, ap++) {
+        to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0);
+        if (!to->h_addr_list[na]) return PR_FAILURE;
+        MakeIPv4MappedAddr(*ap, to->h_addr_list[na]);
+    }
+    to->h_addr_list[na] = 0;
+    return PR_SUCCESS;
+}
+#endif
+
+PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
+    const char *name, PRUint16 af, PRIntn flags,
+    char *buf, PRIntn bufsize, PRHostEnt *hp)
+{
+	struct hostent *h = 0;
+	PRStatus rv = PR_FAILURE;
+#if defined(_PR_HAVE_GETHOST_R)
+    char localbuf[PR_NETDB_BUF_SIZE];
+    char *tmpbuf;
+    struct hostent tmphe;
+    int h_err;
+#endif
+#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;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (af != PR_AF_INET && af != PR_AF_INET6) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+    PR_Lock(_pr_query_ifs_lock);
+    /*
+     * Keep querying the presence of IPv4 and IPv6 interfaces until
+     * at least one is up.  This allows us to detect the local
+     * machine going from offline to online.
+     */
+    if (!_pr_have_inet_if && !_pr_have_inet6_if) {
+	_pr_QueryNetIfs();
+#ifdef DEBUG_QUERY_IFS
+	if (_pr_have_inet_if)
+		printf("Have IPv4 source address\n");
+	if (_pr_have_inet6_if)
+		printf("Have IPv6 source address\n");
+#endif
+    }
+    PR_Unlock(_pr_query_ifs_lock);
+#endif
+
+#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
+
+#if defined(_PR_HAVE_GETHOST_R)
+    tmpbuf = localbuf;
+    if (bufsize > sizeof(localbuf))
+    {
+        tmpbuf = (char *)PR_Malloc(bufsize);
+        if (NULL == tmpbuf)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return rv;
+        }
+    }
+#endif
+
+    /* Do not need to lock the DNS lock if getipnodebyname() is called */
+#ifdef _PR_INET6
+#ifdef _PR_HAVE_GETHOSTBYNAME2
+    LOCK_DNS();
+    if (af == PR_AF_INET6)
+    {
+        if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet6_if)
+        {
+#ifdef _PR_INET6_PROBE
+          if (_pr_ipv6_is_present())
+#endif
+            h = GETHOSTBYNAME2(name, AF_INET6); 
+        }
+        if ((NULL == h) && (flags & PR_AI_V4MAPPED)
+        && ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if))
+        {
+            did_af_inet = PR_TRUE;
+            h = GETHOSTBYNAME2(name, AF_INET);
+        }
+    }
+    else
+    {
+        if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if)
+        {
+            did_af_inet = PR_TRUE;
+            h = GETHOSTBYNAME2(name, af);
+        }
+    }
+#elif defined(_PR_HAVE_GETIPNODEBYNAME)
+    h = getipnodebyname(name, md_af, tmp_flags, &error_num);
+#else
+#error "Unknown name-to-address translation function"
+#endif	/* _PR_HAVE_GETHOSTBYNAME2 */
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    if (_pr_ipv6_is_present())
+    {
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+        LOCK_DNS();
+#endif
+    	h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num);
+    }
+    else
+    {
+        LOCK_DNS();
+    	h = GETHOSTBYNAME(name);
+    }
+#else /* _PR_INET6 */
+    LOCK_DNS();
+    h = GETHOSTBYNAME(name);
+#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_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
+	{
+		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
+
+		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_freehostent_t)_pr_freehostent_fp))(h);
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+		if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED)
+				&& ((flags & PR_AI_ALL)
+				|| ((flags & PR_AI_ADDRCONFIG) && _pr_have_inet_if))
+				&& !did_af_inet && (h = GETHOSTBYNAME2(name, AF_INET)) != 0) {
+			rv = AppendV4AddrsToHostent(h, &buf, &bufsize, hp);
+			if (PR_SUCCESS != rv)
+				PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+		}
+#endif
+	}
+
+    /* Must match the convoluted logic above for LOCK_DNS() */
+#ifdef _PR_INET6
+#ifdef _PR_HAVE_GETHOSTBYNAME2
+    UNLOCK_DNS();
+#endif	/* _PR_HAVE_GETHOSTBYNAME2 */
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+    UNLOCK_DNS();
+#else
+    if (!_pr_ipv6_is_present())
+        UNLOCK_DNS();
+#endif
+#else /* _PR_INET6 */
+    UNLOCK_DNS();
+#endif /* _PR_INET6 */
+
+#if defined(_PR_HAVE_GETHOST_R)
+    if (tmpbuf != localbuf)
+        PR_Free(tmpbuf);
+#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;
+#if defined(_PR_HAVE_GETHOST_R)
+    char localbuf[PR_NETDB_BUF_SIZE];
+    char *tmpbuf;
+    struct hostent tmphe;
+    int h_err;
+#endif
+#if defined(_PR_HAVE_GETIPNODEBYADDR)
+	int error_num;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	if (hostaddr->raw.family == PR_AF_INET6)
+	{
+#if defined(_PR_INET6_PROBE)
+		af = _pr_ipv6_is_present() ? AF_INET6 : AF_INET;
+#elif defined(_PR_INET6)
+		af = AF_INET6;
+#else
+		af = AF_INET;
+#endif
+#if defined(_PR_GHBA_DISALLOW_V4MAPPED)
+		if (_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip))
+			af = AF_INET;
+#endif
+	}
+	else
+	{
+		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_HAVE_GETHOST_R)
+    tmpbuf = localbuf;
+    if (bufsize > sizeof(localbuf))
+    {
+        tmpbuf = (char *)PR_Malloc(bufsize);
+        if (NULL == tmpbuf)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return rv;
+        }
+    }
+#endif
+
+    /* Do not need to lock the DNS lock if getipnodebyaddr() is called */
+#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())
+    {
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+        LOCK_DNS();
+#endif
+    	h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen,
+				af, &error_num);
+    }
+	else
+    {
+        LOCK_DNS();
+		h = GETHOSTBYADDR(addr, addrlen, af);
+    }
+#else	/* _PR_HAVE_GETIPNODEBYADDR */
+    LOCK_DNS();
+	h = GETHOSTBYADDR(addr, addrlen, af);
+#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_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
+	{
+		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
+		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);
+		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_freehostent_t)_pr_freehostent_fp))(h);
+#endif
+	}
+
+    /* Must match the convoluted logic above for LOCK_DNS() */
+#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)
+#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+    UNLOCK_DNS();
+#else
+    if (!_pr_ipv6_is_present())
+        UNLOCK_DNS();
+#endif
+#else	/* _PR_HAVE_GETIPNODEBYADDR */
+    UNLOCK_DNS();
+#endif /* _PR_HAVE_GETIPNODEBYADDR */
+
+#if defined(_PR_HAVE_GETHOST_R)
+    if (tmpbuf != localbuf)
+        PR_Free(tmpbuf);
+#endif
+
+	return rv;
+}
+
+/******************************************************************************/
+/*
+ * Some systems define a reentrant version of getprotobyname(). Too bad
+ * the signature isn't always the same. But hey, they tried. If there
+ * is such a definition, use it. Otherwise, grab a lock and do it here.
+ */
+/******************************************************************************/
+
+#if !defined(_PR_HAVE_GETPROTO_R)
+/*
+ * This may seem like a silly thing to do, but the compiler SHOULD
+ * complain if getprotobyname_r() is implemented on some system and
+ * we're not using it. For sure these signatures are different than
+ * any usable implementation.
+ */
+
+#if defined(ANDROID)
+/* Android's Bionic libc system includes prototypes for these in netdb.h,
+ * but doesn't actually include implementations.  It uses the 5-arg form,
+ * so these functions end up not matching the prototype.  So just rename
+ * them if not found.
+ */
+#define getprotobyname_r _pr_getprotobyname_r
+#define getprotobynumber_r _pr_getprotobynumber_r
+#endif
+
+static struct protoent *getprotobyname_r(const char* name)
+{
+	return getprotobyname(name);
+} /* getprotobyname_r */
+
+static struct protoent *getprotobynumber_r(PRInt32 number)
+{
+	return getprotobynumber(number);
+} /* getprotobynumber_r */
+
+#endif /* !defined(_PR_HAVE_GETPROTO_R) */
+
+PR_IMPLEMENT(PRStatus) PR_GetProtoByName(
+    const char* name, char* buffer, PRInt32 buflen, PRProtoEnt* result)
+{
+	PRStatus rv = PR_SUCCESS;
+#if defined(_PR_HAVE_GETPROTO_R)
+	struct protoent* res = (struct protoent*)result;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if defined(_PR_HAVE_GETPROTO_R_INT)
+    {
+        /*
+        ** The protoent_data has a pointer as the first field.
+        ** That implies the buffer better be aligned, and char*
+        ** doesn't promise much.
+        */
+        PRUptrdiff aligned = (PRUptrdiff)buffer;
+        if (0 != (aligned & (sizeof(struct protoent_data*) - 1)))
+        {
+            aligned += sizeof(struct protoent_data*) - 1;
+            aligned &= ~(sizeof(struct protoent_data*) - 1);
+            buflen -= (aligned - (PRUptrdiff)buffer);
+            buffer = (char*)aligned;
+        }
+    }
+#endif  /* defined(_PR_HAVE_GETPROTO_R_INT) */
+
+    if (PR_NETDB_BUF_SIZE > buflen)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+#if defined(_PR_HAVE_GETPROTO_R_POINTER)
+    if (NULL == getprotobyname_r(name, res, buffer, buflen))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#elif defined(_PR_HAVE_GETPROTO_R_INT)
+    /*
+    ** The buffer needs to be zero'd, and it should be
+    ** at least the size of a struct protoent_data.
+    */
+    memset(buffer, 0, buflen);
+	if (-1 == getprotobyname_r(name, res, (struct protoent_data*)buffer))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#elif defined(_PR_HAVE_5_ARG_GETPROTO_R)
+    /* The 5th argument for getprotobyname_r() cannot be NULL */
+    if (-1 == getprotobyname_r(name, res, buffer, buflen, &res))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#else  /* do it the hard way */
+	{
+		struct protoent *staticBuf;
+		PR_Lock(_getproto_lock);
+		staticBuf = getprotobyname_r(name);
+		if (NULL == staticBuf)
+		{
+		    rv = PR_FAILURE;
+		    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        }
+		else
+		{
+#if defined(SYMBIAN)
+			char* aliases[2];
+			AssignAliases(staticBuf, aliases);
+#endif
+			rv = CopyProtoent(staticBuf, buffer, buflen, result);
+			if (PR_FAILURE == rv)
+			    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        }
+		PR_Unlock(_getproto_lock);
+	}
+#endif  /* all that */
+    return rv;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber(
+    PRInt32 number, char* buffer, PRInt32 buflen, PRProtoEnt* result)
+{
+	PRStatus rv = PR_SUCCESS;
+#if defined(_PR_HAVE_GETPROTO_R)
+	struct protoent* res = (struct protoent*)result;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if defined(_PR_HAVE_GETPROTO_R_INT)
+    {
+        /*
+        ** The protoent_data has a pointer as the first field.
+        ** That implies the buffer better be aligned, and char*
+        ** doesn't promise much.
+        */
+        PRUptrdiff aligned = (PRUptrdiff)buffer;
+        if (0 != (aligned & (sizeof(struct protoent_data*) - 1)))
+        {
+            aligned += sizeof(struct protoent_data*) - 1;
+            aligned &= ~(sizeof(struct protoent_data*) - 1);
+            buflen -= (aligned - (PRUptrdiff)buffer);
+            buffer = (char*)aligned;
+        }
+    }
+#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */
+
+    if (PR_NETDB_BUF_SIZE > buflen)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+#if defined(_PR_HAVE_GETPROTO_R_POINTER)
+    if (NULL == getprotobynumber_r(number, res, buffer, buflen))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+
+#elif defined(_PR_HAVE_GETPROTO_R_INT)
+    /*
+    ** The buffer needs to be zero'd for these OS's.
+    */
+    memset(buffer, 0, buflen);
+	if (-1 == getprotobynumber_r(number, res, (struct protoent_data*)buffer))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#elif defined(_PR_HAVE_5_ARG_GETPROTO_R)
+    /* The 5th argument for getprotobynumber_r() cannot be NULL */
+    if (-1 == getprotobynumber_r(number, res, buffer, buflen, &res))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#else  /* do it the hard way */
+	{
+		struct protoent *staticBuf;
+		PR_Lock(_getproto_lock);
+		staticBuf = getprotobynumber_r(number);
+		if (NULL == staticBuf)
+		{
+		    rv = PR_FAILURE;
+		    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        }
+		else
+		{
+#if defined(SYMBIAN)
+			char* aliases[2];
+			AssignAliases(staticBuf, aliases);
+#endif
+			rv = CopyProtoent(staticBuf, buffer, buflen, result);
+			if (PR_FAILURE == rv)
+			    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        }
+		PR_Unlock(_getproto_lock);
+	}
+#endif  /* all that crap */
+    return rv;
+
+}
+
+PRUintn _PR_NetAddrSize(const PRNetAddr* addr)
+{
+    PRUintn addrsize;
+
+    /*
+     * RFC 2553 added a new field (sin6_scope_id) to
+     * 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)
+        addrsize = sizeof(struct sockaddr_in6);
+#else
+        addrsize = sizeof(addr->ipv6);
+#endif
+#if defined(XP_UNIX) || defined(XP_OS2)
+    else if (AF_UNIX == addr->raw.family)
+        addrsize = sizeof(addr->local);
+#endif
+    else addrsize = 0;
+
+    return addrsize;
+}  /* _PR_NetAddrSize */
+
+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 (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
+        {
+            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 (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet));
+	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();
+
+    if (af == PR_AF_INET6)
+    {
+        if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->ipv6));
+        addr->ipv6.family = af;
+        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 = _pr_in6addr_any;
+            break;
+        case PR_IpAddrLoopback:
+            addr->ipv6.ip = _pr_in6addr_loopback;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = PR_FAILURE;
+        }
+    }
+    else
+    {
+        if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet));
+        addr->inet.family = af;
+        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_SetNetAddr */
+
+PR_IMPLEMENT(PRBool)
+PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
+{
+    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 {
+        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;
+}
+
+extern int pr_inet_aton(const char *cp, PRUint32 *addr);
+
+#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)
+{
+    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 */
+    }
+    return 1;
+}
+#undef XX
+
+#ifndef _PR_HAVE_INET_NTOP
+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;
+
+    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_HAVE_INET_NTOP */
+
+/*
+ * 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)
+{
+#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, lo);
+    LL_SHL(n, n, 32);
+    LL_UI2L(tmp, hi);
+    LL_ADD(n, n, tmp);
+    return n;
+#endif
+}  /* ntohll */
+
+PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
+{
+#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, lo);
+    LL_SHL(n, n, 32);
+    LL_UI2L(tmp, hi);
+    LL_ADD(n, n, tmp);
+    return n;
+#endif
+}  /* htonll */
+
+
+/*
+ * Implementation of PR_GetAddrInfoByName and friends
+ *
+ * Compile-time options:
+ *
+ *  _PR_HAVE_GETADDRINFO  Define this macro if the target system provides
+ *                        getaddrinfo. With this defined, NSPR will require
+ *                        getaddrinfo at run time. If this if not defined,
+ *                        then NSPR will attempt to dynamically resolve
+ *                        getaddrinfo, falling back to PR_GetHostByName if
+ *                        getaddrinfo does not exist on the target system.
+ *
+ * Since getaddrinfo is a relatively new system call on many systems,
+ * we are forced to dynamically resolve it at run time in most cases.
+ * The exception includes any system (such as Mac OS X) that is known to
+ * provide getaddrinfo in all versions that NSPR cares to support.
+ */
+
+#if defined(_PR_HAVE_GETADDRINFO)
+
+#if defined(_PR_INET6)
+
+typedef struct addrinfo PRADDRINFO;
+#define GETADDRINFO getaddrinfo
+#define FREEADDRINFO freeaddrinfo
+#define GETNAMEINFO getnameinfo
+
+#elif defined(_PR_INET6_PROBE)
+
+typedef struct addrinfo PRADDRINFO;
+
+/* getaddrinfo/freeaddrinfo/getnameinfo prototypes */ 
+#if defined(WIN32)
+#define FUNC_MODIFIER __stdcall
+#else
+#define FUNC_MODIFIER
+#endif
+typedef int (FUNC_MODIFIER * FN_GETADDRINFO)
+    (const char *nodename,
+     const char *servname,
+     const PRADDRINFO *hints,
+     PRADDRINFO **res);
+typedef int (FUNC_MODIFIER * FN_FREEADDRINFO)
+    (PRADDRINFO *ai);
+typedef int (FUNC_MODIFIER * FN_GETNAMEINFO)
+    (const struct sockaddr *addr, int addrlen,
+     char *host, int hostlen,
+     char *serv, int servlen, int flags);
+
+/* global state */
+static FN_GETADDRINFO   _pr_getaddrinfo   = NULL;
+static FN_FREEADDRINFO  _pr_freeaddrinfo  = NULL;
+static FN_GETNAMEINFO   _pr_getnameinfo   = NULL;
+
+#define GETADDRINFO_SYMBOL "getaddrinfo"
+#define FREEADDRINFO_SYMBOL "freeaddrinfo"
+#define GETNAMEINFO_SYMBOL "getnameinfo"
+
+PRStatus
+_pr_find_getaddrinfo(void)
+{
+    PRLibrary *lib;
+#ifdef WIN32
+    /*
+     * On windows, we need to search ws2_32.dll or wship6.dll
+     * (Microsoft IPv6 Technology Preview for Windows 2000) for
+     * getaddrinfo and freeaddrinfo.  These libraries might not
+     * be loaded yet.
+     */
+    const char *libname[] = { "ws2_32.dll", "wship6.dll" };
+    int i;
+
+    for (i = 0; i < sizeof(libname)/sizeof(libname[0]); i++) {
+        lib = PR_LoadLibrary(libname[i]);
+        if (!lib) {
+            continue;
+        }
+        _pr_getaddrinfo = (FN_GETADDRINFO)
+            PR_FindFunctionSymbol(lib, GETADDRINFO_SYMBOL);
+        if (!_pr_getaddrinfo) {
+            PR_UnloadLibrary(lib);
+            continue;
+        }
+        _pr_freeaddrinfo = (FN_FREEADDRINFO)
+            PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL);
+        _pr_getnameinfo = (FN_GETNAMEINFO)
+            PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL);
+        if (!_pr_freeaddrinfo || !_pr_getnameinfo) {
+            PR_UnloadLibrary(lib);
+            continue;
+        }
+        /* Keep the library loaded. */
+        return PR_SUCCESS;
+    }
+    return PR_FAILURE;
+#else
+    /*
+     * Resolve getaddrinfo by searching all loaded libraries.  Then
+     * search library containing getaddrinfo for freeaddrinfo.
+     */
+    _pr_getaddrinfo = (FN_GETADDRINFO)
+        PR_FindFunctionSymbolAndLibrary(GETADDRINFO_SYMBOL, &lib);
+    if (!_pr_getaddrinfo) {
+        return PR_FAILURE;
+    }
+    _pr_freeaddrinfo = (FN_FREEADDRINFO)
+        PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL);
+    _pr_getnameinfo = (FN_GETNAMEINFO)
+        PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL);
+    PR_UnloadLibrary(lib);
+    if (!_pr_freeaddrinfo || !_pr_getnameinfo) {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+#endif
+}
+
+#define GETADDRINFO (*_pr_getaddrinfo)
+#define FREEADDRINFO (*_pr_freeaddrinfo)
+#define GETNAMEINFO (*_pr_getnameinfo)
+
+#endif /* _PR_INET6 */
+
+#endif /* _PR_HAVE_GETADDRINFO */
+
+#if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE)
+/*
+ * If getaddrinfo does not exist, then we will fall back on
+ * PR_GetHostByName, which requires that we allocate a buffer for the 
+ * PRHostEnt data structure and its members.
+ */
+typedef struct PRAddrInfoFB {
+    char      buf[PR_NETDB_BUF_SIZE];
+    PRHostEnt hostent;
+    PRBool    has_cname;
+} PRAddrInfoFB;
+
+static PRAddrInfo *
+pr_GetAddrInfoByNameFB(const char  *hostname,
+                       PRUint16     af,
+                       PRIntn       flags)
+{
+    PRStatus rv;
+    PRAddrInfoFB *ai;
+    /* fallback on PR_GetHostByName */
+    ai = PR_NEW(PRAddrInfoFB);
+    if (!ai) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    rv = PR_GetHostByName(hostname, ai->buf, sizeof ai->buf, &ai->hostent);
+    if (rv == PR_FAILURE) {
+        PR_Free(ai);
+        return NULL;
+    }
+    ai->has_cname = !(flags & PR_AI_NOCANONNAME);
+
+    return (PRAddrInfo *) ai;
+}
+#endif /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */
+
+PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char  *hostname,
+                                                PRUint16     af,
+                                                PRIntn       flags)
+{
+    /* restrict input to supported values */
+    if ((af != PR_AF_INET && af != PR_AF_UNSPEC) ||
+        (flags & ~ PR_AI_NOCANONNAME) != PR_AI_ADDRCONFIG) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return NULL;
+    }
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if !defined(_PR_HAVE_GETADDRINFO)
+    return pr_GetAddrInfoByNameFB(hostname, af, flags);
+#else
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present()) {
+        return pr_GetAddrInfoByNameFB(hostname, af, flags);
+    }
+#endif
+    {
+        PRADDRINFO *res, hints;
+        PRStatus rv;
+
+        /*
+         * we assume a RFC 2553 compliant getaddrinfo.  this may at some
+         * point need to be customized as platforms begin to adopt the
+         * RFC 3493.
+         */
+
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_flags = (flags & PR_AI_NOCANONNAME) ? 0: AI_CANONNAME;
+        hints.ai_family = (af == PR_AF_INET) ? AF_INET : AF_UNSPEC;
+
+        /*
+         * it is important to select a socket type in the hints, otherwise we
+         * will get back repetitive entries: one for each socket type.  since
+         * we do not expose ai_socktype through our API, it is okay to do this
+         * here.  the application may still choose to create a socket of some
+         * other type.
+         */
+        hints.ai_socktype = SOCK_STREAM;
+
+        rv = GETADDRINFO(hostname, NULL, &hints, &res);
+        if (rv == 0)
+            return (PRAddrInfo *) res;
+
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv);
+    }
+    return NULL;
+#endif
+}
+
+PR_IMPLEMENT(void) PR_FreeAddrInfo(PRAddrInfo *ai)
+{
+#if defined(_PR_HAVE_GETADDRINFO)
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present())
+        PR_Free((PRAddrInfoFB *) ai);
+    else
+#endif
+        FREEADDRINFO((PRADDRINFO *) ai);
+#else
+    PR_Free((PRAddrInfoFB *) ai);
+#endif
+}
+
+PR_IMPLEMENT(void *) PR_EnumerateAddrInfo(void             *iterPtr,
+                                          const PRAddrInfo *base,
+                                          PRUint16          port,
+                                          PRNetAddr        *result)
+{
+#if defined(_PR_HAVE_GETADDRINFO)
+    PRADDRINFO *ai;
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present()) {
+        /* using PRAddrInfoFB */
+        PRIntn iter = (PRIntn)(PRPtrdiff) iterPtr;
+        iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result);
+        if (iter < 0)
+            iter = 0;
+        return (void *)(PRPtrdiff) iter;
+    }
+#endif
+
+    if (iterPtr)
+        ai = ((PRADDRINFO *) iterPtr)->ai_next;
+    else
+        ai = (PRADDRINFO *) base;
+
+    while (ai && ai->ai_addrlen > sizeof(PRNetAddr))
+        ai = ai->ai_next;
+
+    if (ai) {
+        /* copy sockaddr to PRNetAddr */
+        memcpy(result, ai->ai_addr, ai->ai_addrlen);
+        result->raw.family = ai->ai_addr->sa_family;
+#ifdef _PR_INET6
+        if (AF_INET6 == result->raw.family)
+            result->raw.family = PR_AF_INET6;
+#endif
+        if (ai->ai_addrlen < sizeof(PRNetAddr))
+            memset(((char*)result)+ai->ai_addrlen, 0, sizeof(PRNetAddr) - ai->ai_addrlen);
+
+        if (result->raw.family == PR_AF_INET)
+            result->inet.port = htons(port);
+        else
+            result->ipv6.port = htons(port);
+    }
+
+    return ai;
+#else
+    /* using PRAddrInfoFB */
+    PRIntn iter = (PRIntn) iterPtr;
+    iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result);
+    if (iter < 0)
+        iter = 0;
+    return (void *) iter;
+#endif
+}
+
+PR_IMPLEMENT(const char *) PR_GetCanonNameFromAddrInfo(const PRAddrInfo *ai)
+{
+#if defined(_PR_HAVE_GETADDRINFO)
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present()) {
+        const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai;
+        return fb->has_cname ? fb->hostent.h_name : NULL;
+    } 
+#endif
+    return ((const PRADDRINFO *) ai)->ai_canonname;
+#else
+    const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai;
+    return fb->has_cname ? fb->hostent.h_name : NULL;
+#endif
+}
+
+#if defined(_PR_HAVE_GETADDRINFO)
+static PRStatus pr_StringToNetAddrGAI(const char *string, PRNetAddr *addr)
+{
+    PRADDRINFO *res, hints;
+    int rv;  /* 0 for success, or the error code EAI_xxx */
+    PRNetAddr laddr;
+    PRStatus status = PR_SUCCESS;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_flags = AI_NUMERICHOST;
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+    rv = GETADDRINFO(string, NULL, &hints, &res);
+    if (rv != 0)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv);
+        return PR_FAILURE;
+    }
+
+    /* pick up the first addr */
+    memcpy(&laddr, res->ai_addr, res->ai_addrlen);
+    if (AF_INET6 == res->ai_addr->sa_family)
+    {
+        addr->ipv6.family = PR_AF_INET6;
+        addr->ipv6.ip = laddr.ipv6.ip;
+        addr->ipv6.scope_id = laddr.ipv6.scope_id;
+    }
+    else if (AF_INET == res->ai_addr->sa_family)
+    {
+        addr->inet.family = PR_AF_INET;
+        addr->inet.ip = laddr.inet.ip;
+    }
+    else
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        status = PR_FAILURE;
+    }
+
+    FREEADDRINFO(res);
+    return status;
+}
+#endif  /* _PR_HAVE_GETADDRINFO */
+
+static PRStatus pr_StringToNetAddrFB(const char *string, PRNetAddr *addr)
+{
+    PRIntn rv;
+
+    rv = pr_inet_aton(string, &addr->inet.ip);
+    if (1 == rv)
+    {
+        addr->raw.family = AF_INET;
+        return PR_SUCCESS;
+    }
+
+    PR_ASSERT(0 == rv);
+    /* clean up after the failed call */
+    memset(&addr->inet.ip, 0, sizeof(addr->inet.ip));
+
+    rv = StringToV6Addr(string, &addr->ipv6.ip);
+    if (1 == rv)
+    {
+        addr->raw.family = PR_AF_INET6;
+        return PR_SUCCESS;
+    }
+
+    PR_ASSERT(0 == rv);
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (!addr || !string || !*string)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+#if !defined(_PR_HAVE_GETADDRINFO)
+    return pr_StringToNetAddrFB(string, addr);
+#else
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present())
+        return pr_StringToNetAddrFB(string, addr);
+#endif
+    /*
+     * getaddrinfo with AI_NUMERICHOST is much slower than pr_inet_aton on some
+     * platforms, such as Mac OS X (bug 404399), Linux glibc 2.10 (bug 344809),
+     * and most likely others. So we only use it to convert literal IP addresses
+     * that contain IPv6 scope IDs, which pr_inet_aton cannot convert.
+     */
+    if (!strchr(string, '%'))
+        return pr_StringToNetAddrFB(string, addr);
+
+    return pr_StringToNetAddrGAI(string, addr);
+#endif
+}
+
+#if defined(_PR_HAVE_GETADDRINFO)
+static PRStatus pr_NetAddrToStringGNI(
+    const PRNetAddr *addr, char *string, PRUint32 size)
+{
+    int addrlen;
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+    PRUint16 md_af = addr->raw.family;
+    PRNetAddr addrcopy;
+#endif
+    int rv;  /* 0 for success, or the error code EAI_xxx */
+
+#ifdef _PR_INET6
+    if (addr->raw.family == PR_AF_INET6)
+    {
+        md_af = AF_INET6;
+#ifndef _PR_HAVE_SOCKADDR_LEN
+        addrcopy = *addr;
+        addrcopy.raw.family = AF_INET6;
+        addrp = &addrcopy;
+#endif
+    }
+#endif
+
+    addrlen = PR_NETADDR_SIZE(addr);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    addrcopy = *addr;
+    ((struct sockaddr*)&addrcopy)->sa_len = addrlen;
+    ((struct sockaddr*)&addrcopy)->sa_family = md_af;
+    addrp = &addrcopy;
+#endif
+    rv = GETNAMEINFO((const struct sockaddr *)addrp, addrlen,
+        string, size, NULL, 0, NI_NUMERICHOST);
+    if (rv != 0)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+#endif  /* _PR_HAVE_GETADDRINFO */
+
+#if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE)
+static PRStatus pr_NetAddrToStringFB(
+    const PRNetAddr *addr, char *string, PRUint32 size)
+{
+    if (PR_AF_INET6 == addr->raw.family)
+    {
+#if defined(_PR_HAVE_INET_NTOP)
+        if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))
+#else
+        if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))
+#endif
+        {
+            /* the size of the result buffer is inadequate */
+            PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+            return PR_FAILURE;
+        }
+    }
+    else
+    {
+        if (size < 16) goto failed;
+        if (AF_INET != addr->raw.family) goto failed;
+        else
+        {
+            unsigned char *byte = (unsigned char*)&addr->inet.ip;
+            PR_snprintf(string, size, "%u.%u.%u.%u",
+                byte[0], byte[1], byte[2], byte[3]);
+        }
+    }
+
+    return PR_SUCCESS;
+
+failed:
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+
+}  /* pr_NetAddrToStringFB */
+#endif  /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */
+
+PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
+    const PRNetAddr *addr, char *string, PRUint32 size)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if !defined(_PR_HAVE_GETADDRINFO)
+    return pr_NetAddrToStringFB(addr, string, size);
+#else
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present())
+        return pr_NetAddrToStringFB(addr, string, size);
+#endif
+    return pr_NetAddrToStringGNI(addr, string, size);
+#endif
+}  /* PR_NetAddrToString */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prolock.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prolock.c
new file mode 100644
index 0000000..a1d8a0f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prolock.c
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+**  prolock.c -- NSPR Ordered Lock
+** 
+**  Implement the API defined in prolock.h
+** 
+*/
+#include "prolock.h"
+#include "prlog.h"
+#include "prerror.h"
+
+PR_IMPLEMENT(PROrderedLock *) 
+    PR_CreateOrderedLock( 
+        PRInt32 order,
+        const char *name
+)
+{
+    PR_ASSERT(!"Not implemented"); /* Not implemented yet */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+} /*  end PR_CreateOrderedLock() */
+
+
+PR_IMPLEMENT(void) 
+    PR_DestroyOrderedLock( 
+        PROrderedLock *lock 
+)
+{
+    PR_ASSERT(!"Not implemented"); /* Not implemented yet */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+} /*  end PR_DestroyOrderedLock() */
+
+
+PR_IMPLEMENT(void) 
+    PR_LockOrderedLock( 
+        PROrderedLock *lock 
+)
+{
+    PR_ASSERT(!"Not implemented"); /* Not implemented yet */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+} /*  end PR_LockOrderedLock() */
+
+
+PR_IMPLEMENT(PRStatus) 
+    PR_UnlockOrderedLock( 
+        PROrderedLock *lock 
+)
+{
+    PR_ASSERT(!"Not implemented"); /* Not implemented yet */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+} /*  end PR_UnlockOrderedLock() */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prrng.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prrng.c
new file mode 100644
index 0000000..6cd7e23
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prrng.c
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+/*
+ * We were not including <string.h> in optimized builds.  On AIX this
+ * caused libnspr4.so to export memcpy and some binaries linked with
+ * libnspr4.so resolved their memcpy references with libnspr4.so.  To
+ * be backward compatible with old libnspr4.so binaries, we do not
+ * include <string.h> in optimized builds for AIX.  (bug 200561)
+ */
+#if !(defined(AIX) && !defined(DEBUG))
+#include <string.h>
+#endif
+
+PRSize _pr_CopyLowBits( 
+    void *dst, 
+    PRSize dstlen, 
+    void *src, 
+    PRSize srclen )
+{
+    if (srclen <= dstlen) {
+    	memcpy(dst, src, srclen);
+	    return srclen;
+    }
+#if defined IS_BIG_ENDIAN
+    memcpy(dst, (char*)src + (srclen - dstlen), dstlen);
+#else
+    memcpy(dst, src, dstlen);
+#endif
+    return dstlen;
+}    
+
+PR_IMPLEMENT(PRSize) PR_GetRandomNoise( 
+    void    *buf,
+    PRSize  size
+)
+{
+    return( _PR_MD_GET_RANDOM_NOISE( buf, size ));
+} /* end PR_GetRandomNoise() */
+/* end prrng.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prsystem.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prsystem.c
new file mode 100644
index 0000000..098de02
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prsystem.c
@@ -0,0 +1,374 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include "prsystem.h"
+#include "prprf.h"
+#include "prlong.h"
+
+#if defined(BEOS)
+#include <kernel/OS.h>
+#endif
+
+#if defined(OS2)
+#define INCL_DOS
+#define INCL_DOSMISC
+#include <os2.h>
+/* define the required constant if it is not already defined in the headers */
+#ifndef QSV_NUMPROCESSORS
+#define QSV_NUMPROCESSORS 26
+#endif
+#endif
+
+/* BSD-derived systems use sysctl() to get the number of processors */
+#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \
+    || defined(OPENBSD) || defined(DARWIN)
+#define _PR_HAVE_SYSCTL
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+
+#if defined(DARWIN)
+#include <mach/mach_init.h>
+#include <mach/mach_host.h>
+#endif
+
+#if defined(HPUX)
+#include <sys/mpctl.h>
+#include <sys/pstat.h>
+#endif
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#include <sys/utsname.h>
+#endif
+
+#if defined(AIX)
+#include <cf.h>
+#include <sys/cfgodm.h>
+#endif
+
+#if defined(WIN32)
+/* This struct is not present in VC6 headers, so declare it here */
+typedef struct {
+    DWORD dwLength;
+    DWORD dwMemoryLoad;
+    DWORDLONG ullTotalPhys;
+    DWORDLONG ullAvailPhys;
+    DWORDLONG ullToalPageFile;
+    DWORDLONG ullAvailPageFile;
+    DWORDLONG ullTotalVirtual;
+    DWORDLONG ullAvailVirtual;
+    DWORDLONG ullAvailExtendedVirtual;
+} PR_MEMORYSTATUSEX;
+
+/* Typedef for dynamic lookup of GlobalMemoryStatusEx(). */
+typedef BOOL (WINAPI *GlobalMemoryStatusExFn)(PR_MEMORYSTATUSEX *);
+#endif
+
+PR_IMPLEMENT(char) PR_GetDirectorySeparator(void)
+{
+    return PR_DIRECTORY_SEPARATOR;
+}  /* PR_GetDirectorySeparator */
+
+/*
+** OBSOLETE -- the function name is misspelled.
+*/
+PR_IMPLEMENT(char) PR_GetDirectorySepartor(void)
+{
+#if defined(DEBUG)
+    static PRBool warn = PR_TRUE;
+    if (warn) {
+        warn = _PR_Obsolete("PR_GetDirectorySepartor()",
+                "PR_GetDirectorySeparator()");
+    }
+#endif
+    return PR_GetDirectorySeparator();
+}  /* PR_GetDirectorySepartor */
+
+PR_IMPLEMENT(char) PR_GetPathSeparator(void)
+{
+    return PR_PATH_SEPARATOR;
+}  /* PR_GetPathSeparator */
+
+PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen)
+{
+    PRUintn len = 0;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    switch(cmd)
+    {
+      case PR_SI_HOSTNAME:
+      case PR_SI_HOSTNAME_UNTRUNCATED:
+        if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen))
+            return PR_FAILURE;
+
+        if (cmd == PR_SI_HOSTNAME_UNTRUNCATED)
+            break;
+        /*
+         * On some platforms a system does not have a hostname and
+         * its IP address is returned instead.   The following code
+         * should be skipped on those platforms.
+         */
+#ifndef _PR_GET_HOST_ADDR_AS_NAME
+        /* Return the unqualified hostname */
+            while (buf[len] && (len < buflen)) {
+                if (buf[len] == '.') {
+                    buf[len] = '\0';
+                    break;
+                }
+                len += 1;
+            }    
+#endif
+         break;
+
+      case PR_SI_SYSNAME:
+        /* Return the operating system name */
+#if defined(XP_UNIX) || defined(WIN32)
+        if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen))
+            return PR_FAILURE;
+#else
+        (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME);
+#endif
+        break;
+
+      case PR_SI_RELEASE:
+        /* Return the version of the operating system */
+#if defined(XP_UNIX) || defined(WIN32)
+        if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen))
+            return PR_FAILURE;
+#endif
+#if defined(XP_OS2)
+        {
+            ULONG os2ver[2] = {0};
+            DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION,
+                            &os2ver, sizeof(os2ver));
+            /* Formatting for normal usage (2.11, 3.0, 4.0, 4.5); officially,
+               Warp 4 is version 2.40.00, WSeB 2.45.00 */
+            if (os2ver[0] < 30)
+              (void)PR_snprintf(buf, buflen, "%s%lu",
+                                "2.", os2ver[0]);
+            else if (os2ver[0] < 45)
+              (void)PR_snprintf(buf, buflen, "%lu%s%lu",
+                                os2ver[0]/10, ".", os2ver[1]);
+            else
+              (void)PR_snprintf(buf, buflen, "%.1f",
+                                os2ver[0]/10.0);
+        }
+#endif /* OS2 */
+        break;
+
+      case PR_SI_ARCHITECTURE:
+        /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/
+        (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE);
+        break;
+	  default:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+			return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+/*
+** PR_GetNumberOfProcessors()
+** 
+** Implementation notes:
+**   Every platform does it a bit different.
+**     numCpus is the returned value.
+**   for each platform's "if defined" section
+**     declare your local variable
+**     do your thing, assign to numCpus
+**   order of the if defined()s may be important,
+**     especially for unix variants. Do platform
+**     specific implementations before XP_UNIX.
+** 
+*/
+PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void )
+{
+    PRInt32     numCpus;
+#if defined(WIN32)
+    SYSTEM_INFO     info;
+
+    GetSystemInfo( &info );
+    numCpus = info.dwNumberOfProcessors;
+#elif defined(BEOS)
+    system_info sysInfo;
+
+    get_system_info(&sysInfo);
+    numCpus = sysInfo.cpu_count;
+#elif defined(OS2)
+    DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus));
+#elif defined(_PR_HAVE_SYSCTL)
+    int mib[2];
+    int rc;
+    size_t len = sizeof(numCpus);
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_NCPU;
+    rc = sysctl( mib, 2, &numCpus, &len, NULL, 0 );
+    if ( -1 == rc )  {
+        numCpus = -1; /* set to -1 for return value on error */
+        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
+    }
+#elif defined(HPUX)
+    numCpus = mpctl( MPC_GETNUMSPUS, 0, 0 );
+    if ( numCpus < 1 )  {
+        numCpus = -1; /* set to -1 for return value on error */
+        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
+    }
+#elif defined(IRIX)
+    numCpus = sysconf( _SC_NPROC_ONLN );
+#elif defined(RISCOS) || defined(SYMBIAN)
+    numCpus = 1;
+#elif defined(XP_UNIX)
+    numCpus = sysconf( _SC_NPROCESSORS_ONLN );
+#else
+#error "An implementation is required"
+#endif
+    return(numCpus);
+} /* end PR_GetNumberOfProcessors() */
+
+/*
+** PR_GetPhysicalMemorySize()
+** 
+** Implementation notes:
+**   Every platform does it a bit different.
+**     bytes is the returned value.
+**   for each platform's "if defined" section
+**     declare your local variable
+**     do your thing, assign to bytes.
+** 
+*/
+PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void)
+{
+    PRUint64 bytes = 0;
+
+#if defined(LINUX) || defined(SOLARIS)
+
+    long pageSize = sysconf(_SC_PAGESIZE);
+    long pageCount = sysconf(_SC_PHYS_PAGES);
+    bytes = (PRUint64) pageSize * pageCount;
+
+#elif defined(NETBSD)
+
+    int mib[2];
+    int rc;
+    uint64_t memSize;
+    size_t len = sizeof(memSize);
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_PHYSMEM64;
+    rc = sysctl(mib, 2, &memSize, &len, NULL, 0);
+    if (-1 != rc)  {
+        bytes = memSize;
+    }
+
+#elif defined(HPUX)
+
+    struct pst_static info;
+    int result = pstat_getstatic(&info, sizeof(info), 1, 0);
+    if (result == 1)
+        bytes = (PRUint64) info.physical_memory * info.page_size;
+
+#elif defined(DARWIN)
+
+    struct host_basic_info hInfo;
+    mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
+
+    int result = host_info(mach_host_self(),
+                           HOST_BASIC_INFO,
+                           (host_info_t) &hInfo,
+                           &count);
+    if (result == KERN_SUCCESS)
+        bytes = hInfo.max_mem;
+
+#elif defined(WIN32)
+
+    /* Try to use the newer GlobalMemoryStatusEx API for Windows 2000+. */
+    GlobalMemoryStatusExFn globalMemory = (GlobalMemoryStatusExFn) NULL;
+    HMODULE module = GetModuleHandleW(L"kernel32.dll");
+
+    if (module) {
+        globalMemory = (GlobalMemoryStatusExFn)GetProcAddress(module, "GlobalMemoryStatusEx");
+
+        if (globalMemory) {
+            PR_MEMORYSTATUSEX memStat;
+            memStat.dwLength = sizeof(memStat);
+
+            if (globalMemory(&memStat))
+                bytes = memStat.ullTotalPhys;
+        }
+    }
+
+    if (!bytes) {
+        /* Fall back to the older API. */
+        MEMORYSTATUS memStat;
+        memset(&memStat, 0, sizeof(memStat));
+        GlobalMemoryStatus(&memStat);
+        bytes = memStat.dwTotalPhys;
+    }
+
+#elif defined(OS2)
+
+    ULONG ulPhysMem;
+    DosQuerySysInfo(QSV_TOTPHYSMEM,
+                    QSV_TOTPHYSMEM,
+                    &ulPhysMem,
+                    sizeof(ulPhysMem));
+    bytes = ulPhysMem;
+
+#elif defined(AIX)
+
+    if (odm_initialize() == 0) {
+        int how_many;
+        struct CuAt *obj = getattr("sys0", "realmem", 0, &how_many);
+        if (obj != NULL) {
+            bytes = (PRUint64) atoi(obj->value) * 1024;
+            free(obj);
+        }
+        odm_terminate();
+    }
+
+#else
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+
+#endif
+
+    return bytes;
+} /* end PR_GetPhysicalMemorySize() */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prthinfo.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prthinfo.c
new file mode 100644
index 0000000..6dcf9c6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prthinfo.c
@@ -0,0 +1,240 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prlog.h"
+#include "prthread.h"
+#include "private/pprthred.h"
+#include "primpl.h"
+
+PR_IMPLEMENT(PRWord *)
+PR_GetGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    return _MD_HomeGCRegisters(t, isCurrent, np);
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ThreadScanStackPointers(PRThread* t,
+                           PRScanStackFun scanFun, void* scanClosure)
+{
+    PRThread* current = PR_GetCurrentThread();
+    PRWord *sp, *esp, *p0;
+    int n;
+    void **ptd;
+    PRStatus status;
+    PRUint32 index;
+    int stack_end;
+
+    /*
+    ** Store the thread's registers in the thread structure so the GC
+    ** can scan them. Then scan them.
+    */
+    p0 = _MD_HomeGCRegisters(t, t == current, &n);
+    status = scanFun(t, (void**)p0, n, scanClosure);
+    if (status != PR_SUCCESS)
+        return status;
+
+    /* Scan the C stack for pointers into the GC heap */
+#if defined(XP_PC) && defined(WIN16)
+    /*
+    ** Under WIN16, the stack of the current thread is always mapped into
+    ** the "task stack" (at SS:xxxx).  So, if t is the current thread, scan
+    ** the "task stack".  Otherwise, scan the "cached stack" of the inactive
+    ** thread...
+    */
+    if (t == current) {
+        sp  = (PRWord*) &stack_end;
+        esp = (PRWord*) _pr_top_of_task_stack;
+
+        PR_ASSERT(sp <= esp);
+    } else {
+        sp  = (PRWord*) PR_GetSP(t);
+        esp = (PRWord*) t->stack->stackTop;
+
+        PR_ASSERT((t->stack->stackSize == 0) ||
+                  ((sp >  (PRWord*)t->stack->stackBottom) &&
+                   (sp <= (PRWord*)t->stack->stackTop)));
+    }
+#else   /* ! WIN16 */
+#ifdef HAVE_STACK_GROWING_UP
+    if (t == current) {
+        esp = (PRWord*) &stack_end;
+    } else {
+        esp = (PRWord*) PR_GetSP(t);
+    }
+    sp = (PRWord*) t->stack->stackTop;
+    if (t->stack->stackSize) {
+        PR_ASSERT((esp > (PRWord*)t->stack->stackTop) &&
+                  (esp < (PRWord*)t->stack->stackBottom));
+    }
+#else   /* ! HAVE_STACK_GROWING_UP */
+    if (t == current) {
+        sp = (PRWord*) &stack_end;
+    } else {
+        sp = (PRWord*) PR_GetSP(t);
+    }
+    esp = (PRWord*) t->stack->stackTop;
+    if (t->stack->stackSize) {
+        PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) &&
+                  (sp < (PRWord*)t->stack->stackTop));
+    }
+#endif  /* ! HAVE_STACK_GROWING_UP */
+#endif  /* ! WIN16 */
+
+#if defined(WIN16)
+    {
+        prword_t scan;
+        prword_t limit;
+        
+        scan = (prword_t) sp;
+        limit = (prword_t) esp;
+        while (scan < limit) {
+            prword_t *test;
+
+            test = *((prword_t **)scan);
+            status = scanFun(t, (void**)&test, 1, scanClosure);
+            if (status != PR_SUCCESS)
+                return status;
+            scan += sizeof(char);
+        }
+    }
+#else
+    if (sp < esp) {
+        status = scanFun(t, (void**)sp, esp - sp, scanClosure);
+        if (status != PR_SUCCESS)
+            return status;
+    }
+#endif
+
+    /*
+    ** Mark all of the per-thread-data items attached to this thread
+    **
+    ** The execution environment better be accounted for otherwise it
+    ** will be collected
+    */
+    status = scanFun(t, (void**)&t->environment, 1, scanClosure);
+    if (status != PR_SUCCESS)
+        return status;
+
+#ifndef GC_LEAK_DETECTOR
+    /* if thread is not allocated on stack, this is redundant. */
+    ptd = t->privateData;
+    for (index = 0; index < t->tpdLength; index++, ptd++) {
+        status = scanFun(t, (void**)ptd, 1, scanClosure);
+        if (status != PR_SUCCESS)
+            return status;
+    }
+#endif
+    
+    return PR_SUCCESS;
+}
+
+/* transducer for PR_EnumerateThreads */
+typedef struct PRScanStackData {
+    PRScanStackFun      scanFun;
+    void*               scanClosure;
+} PRScanStackData;
+
+static PRStatus PR_CALLBACK
+pr_ScanStack(PRThread* t, int i, void* arg)
+{
+    PRScanStackData* data = (PRScanStackData*)arg;
+    return PR_ThreadScanStackPointers(t, data->scanFun, data->scanClosure);
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure)
+{
+    PRScanStackData data;
+    data.scanFun = scanFun;
+    data.scanClosure = scanClosure;
+    return PR_EnumerateThreads(pr_ScanStack, &data);
+}
+
+PR_IMPLEMENT(PRUword)
+PR_GetStackSpaceLeft(PRThread* t)
+{
+    PRThread *current = PR_GetCurrentThread();
+    PRWord *sp, *esp;
+    int stack_end;
+
+#if defined(WIN16)
+    /*
+    ** Under WIN16, the stack of the current thread is always mapped into
+    ** the "task stack" (at SS:xxxx).  So, if t is the current thread, scan
+    ** the "task stack".  Otherwise, scan the "cached stack" of the inactive
+    ** thread...
+    */
+    if (t == current) {
+        sp  = (PRWord*) &stack_end;
+        esp = (PRWord*) _pr_top_of_task_stack;
+
+        PR_ASSERT(sp <= esp);
+    } else {
+        sp  = (PRWord*) PR_GetSP(t);
+        esp = (PRWord*) t->stack->stackTop;
+
+	PR_ASSERT((t->stack->stackSize == 0) ||
+                 ((sp >  (PRWord*)t->stack->stackBottom) &&
+		  (sp <= (PRWord*)t->stack->stackTop)));
+    }
+#else   /* ! WIN16 */
+#ifdef HAVE_STACK_GROWING_UP
+    if (t == current) {
+        esp = (PRWord*) &stack_end;
+    } else {
+        esp = (PRWord*) PR_GetSP(t);
+    }
+    sp = (PRWord*) t->stack->stackTop;
+    if (t->stack->stackSize) {
+        PR_ASSERT((esp > (PRWord*)t->stack->stackTop) &&
+                  (esp < (PRWord*)t->stack->stackBottom));
+    }
+#else   /* ! HAVE_STACK_GROWING_UP */
+    if (t == current) {
+        sp = (PRWord*) &stack_end;
+    } else {
+        sp = (PRWord*) PR_GetSP(t);
+    }
+    esp = (PRWord*) t->stack->stackTop;
+    if (t->stack->stackSize) {
+	PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) &&
+		  (sp < (PRWord*)t->stack->stackTop));
+    }
+#endif  /* ! HAVE_STACK_GROWING_UP */
+#endif  /* ! WIN16 */
+    return (PRUword)t->stack->stackSize - ((PRWord)esp - (PRWord)sp);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c
new file mode 100644
index 0000000..b48b41c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c
@@ -0,0 +1,2228 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * prtime.c --
+ *
+ *     NSPR date and time functions
+ *
+ */
+
+#include "prinit.h"
+#include "prtime.h"
+#include "prlock.h"
+#include "prprf.h"
+#include "prlog.h"
+
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>  /* for EINVAL */
+#include <time.h>
+
+/* 
+ * The COUNT_LEAPS macro counts the number of leap years passed by
+ * till the start of the given year Y.  At the start of the year 4
+ * A.D. the number of leap years passed by is 0, while at the start of
+ * the year 5 A.D. this count is 1. The number of years divisible by
+ * 100 but not divisible by 400 (the non-leap years) is deducted from
+ * the count to get the correct number of leap years.
+ *
+ * The COUNT_DAYS macro counts the number of days since 01/01/01 till the
+ * start of the given year Y. The number of days at the start of the year
+ * 1 is 0 while the number of days at the start of the year 2 is 365
+ * (which is ((2)-1) * 365) and so on. The reference point is 01/01/01
+ * midnight 00:00:00.
+ */
+
+#define COUNT_LEAPS(Y)   ( ((Y)-1)/4 - ((Y)-1)/100 + ((Y)-1)/400 )
+#define COUNT_DAYS(Y)  ( ((Y)-1)*365 + COUNT_LEAPS(Y) )
+#define DAYS_BETWEEN_YEARS(A, B)  (COUNT_DAYS(B) - COUNT_DAYS(A))
+
+/*
+ * Static variables used by functions in this file
+ */
+
+/*
+ * The following array contains the day of year for the last day of
+ * each month, where index 1 is January, and day 0 is January 1.
+ */
+
+static const int lastDayOfMonth[2][13] = {
+    {-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364},
+    {-1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}
+};
+
+/*
+ * The number of days in a month
+ */
+
+static const PRInt8 nDays[2][12] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+};
+
+/*
+ * Declarations for internal functions defined later in this file.
+ */
+
+static void        ComputeGMT(PRTime time, PRExplodedTime *gmt);
+static int         IsLeapYear(PRInt16 year);
+static void        ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset);
+static void        AdjustDSTGMTOffsets(PRTime time, PRExplodedTime *exploded);
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ComputeGMT --
+ *
+ *     Caveats:
+ *     - we ignore leap seconds
+ *
+ *------------------------------------------------------------------------
+ */
+
+static void
+ComputeGMT(PRTime time, PRExplodedTime *gmt)
+{
+    PRInt32 tmp, rem;
+    PRInt32 numDays;
+    PRInt64 numDays64, rem64;
+    int isLeap;
+    PRInt64 sec;
+    PRInt64 usec;
+    PRInt64 usecPerSec;
+    PRInt64 secPerDay;
+
+    /*
+     * We first do the usec, sec, min, hour thing so that we do not
+     * have to do LL arithmetic.
+     */
+
+    LL_I2L(usecPerSec, 1000000L);
+    LL_DIV(sec, time, usecPerSec);
+    LL_MOD(usec, time, usecPerSec);
+    LL_L2I(gmt->tm_usec, usec);
+    /* Correct for weird mod semantics so the remainder is always positive */
+    if (gmt->tm_usec < 0) {
+        PRInt64 one;
+
+        LL_I2L(one, 1L);
+        LL_SUB(sec, sec, one);
+        gmt->tm_usec += 1000000L;
+    }
+
+    LL_I2L(secPerDay, 86400L);
+    LL_DIV(numDays64, sec, secPerDay);
+    LL_MOD(rem64, sec, secPerDay);
+    /* We are sure both of these numbers can fit into PRInt32 */
+    LL_L2I(numDays, numDays64);
+    LL_L2I(rem, rem64);
+    if (rem < 0) {
+        numDays--;
+        rem += 86400L;
+    }
+
+    /* Compute day of week.  Epoch started on a Thursday. */
+
+    gmt->tm_wday = (numDays + 4) % 7;
+    if (gmt->tm_wday < 0) {
+        gmt->tm_wday += 7;
+    }
+
+    /* Compute the time of day. */
+
+    gmt->tm_hour = rem / 3600;
+    rem %= 3600;
+    gmt->tm_min = rem / 60;
+    gmt->tm_sec = rem % 60;
+
+    /*
+     * Compute the year by finding the 400 year period, then working
+     * down from there.
+     *
+     * Since numDays is originally the number of days since January 1, 1970,
+     * we must change it to be the number of days from January 1, 0001.
+     */
+
+    numDays += 719162;       /* 719162 = days from year 1 up to 1970 */
+    tmp = numDays / 146097;  /* 146097 = days in 400 years */
+    rem = numDays % 146097;
+    gmt->tm_year = tmp * 400 + 1;
+
+    /* Compute the 100 year period. */
+
+    tmp = rem / 36524;    /* 36524 = days in 100 years */
+    rem %= 36524;
+    if (tmp == 4) {       /* the 400th year is a leap year */
+        tmp = 3;
+        rem = 36524;
+    }
+    gmt->tm_year += tmp * 100;
+
+    /* Compute the 4 year period. */
+
+    tmp = rem / 1461;     /* 1461 = days in 4 years */
+    rem %= 1461;
+    gmt->tm_year += tmp * 4;
+
+    /* Compute which year in the 4. */
+
+    tmp = rem / 365;
+    rem %= 365;
+    if (tmp == 4) {       /* the 4th year is a leap year */
+        tmp = 3;
+        rem = 365;
+    }
+
+    gmt->tm_year += tmp;
+    gmt->tm_yday = rem;
+    isLeap = IsLeapYear(gmt->tm_year);
+
+    /* Compute the month and day of month. */
+
+    for (tmp = 1; lastDayOfMonth[isLeap][tmp] < gmt->tm_yday; tmp++) {
+    }
+    gmt->tm_month = --tmp;
+    gmt->tm_mday = gmt->tm_yday - lastDayOfMonth[isLeap][tmp];
+
+    gmt->tm_params.tp_gmt_offset = 0;
+    gmt->tm_params.tp_dst_offset = 0;
+}
+
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * PR_ExplodeTime --
+ *
+ *     Cf. struct tm *gmtime(const time_t *tp) and
+ *         struct tm *localtime(const time_t *tp)
+ *
+ *------------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(void)
+PR_ExplodeTime(
+        PRTime usecs,
+        PRTimeParamFn params,
+        PRExplodedTime *exploded)
+{
+    ComputeGMT(usecs, exploded);
+    exploded->tm_params = params(exploded);
+    ApplySecOffset(exploded, exploded->tm_params.tp_gmt_offset
+            + exploded->tm_params.tp_dst_offset);
+    AdjustDSTGMTOffsets(usecs, exploded);
+}
+
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * PR_ImplodeTime --
+ *
+ *     Cf. time_t mktime(struct tm *tp)
+ *     Note that 1 year has < 2^25 seconds.  So an PRInt32 is large enough.
+ *
+ *------------------------------------------------------------------------
+ */
+PR_IMPLEMENT(PRTime)
+PR_ImplodeTime(const PRExplodedTime *exploded)
+{
+    PRExplodedTime copy;
+    PRTime retVal;
+    PRInt64 secPerDay, usecPerSec;
+    PRInt64 temp;
+    PRInt64 numSecs64;
+    PRInt32 numDays;
+    PRInt32 numSecs;
+
+    /* Normalize first.  Do this on our copy */
+    copy = *exploded;
+    PR_NormalizeTime_NoDSTAdjust(&copy, PR_GMTParameters);
+
+    numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year);
+    
+    numSecs = copy.tm_yday * 86400 + copy.tm_hour * 3600
+            + copy.tm_min * 60 + copy.tm_sec;
+
+    LL_I2L(temp, numDays);
+    LL_I2L(secPerDay, 86400);
+    LL_MUL(temp, temp, secPerDay);
+    LL_I2L(numSecs64, numSecs);
+    LL_ADD(numSecs64, numSecs64, temp);
+
+    /* apply the GMT and DST offsets */
+    LL_I2L(temp,  copy.tm_params.tp_gmt_offset);
+    LL_SUB(numSecs64, numSecs64, temp);
+    LL_I2L(temp,  copy.tm_params.tp_dst_offset);
+    LL_SUB(numSecs64, numSecs64, temp);
+
+    LL_I2L(usecPerSec, 1000000L);
+    LL_MUL(temp, numSecs64, usecPerSec);
+    LL_I2L(retVal, copy.tm_usec);
+    LL_ADD(retVal, retVal, temp);
+
+    return retVal;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * IsLeapYear --
+ *
+ *     Returns 1 if the year is a leap year, 0 otherwise.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int IsLeapYear(PRInt16 year)
+{
+    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
+        return 1;
+    else
+        return 0;
+}
+
+/*
+ * 'secOffset' should be less than 86400 (i.e., a day).
+ * 'time' should point to a normalized PRExplodedTime.
+ */
+
+static void
+ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset)
+{
+    time->tm_sec += secOffset;
+
+    /* Note that in this implementation we do not count leap seconds */
+    if (time->tm_sec < 0 || time->tm_sec >= 60) {
+        time->tm_min += time->tm_sec / 60;
+        time->tm_sec %= 60;
+        if (time->tm_sec < 0) {
+            time->tm_sec += 60;
+            time->tm_min--;
+        }
+    }
+
+    if (time->tm_min < 0 || time->tm_min >= 60) {
+        time->tm_hour += time->tm_min / 60;
+        time->tm_min %= 60;
+        if (time->tm_min < 0) {
+            time->tm_min += 60;
+            time->tm_hour--;
+        }
+    }
+
+    if (time->tm_hour < 0) {
+        /* Decrement mday, yday, and wday */
+        time->tm_hour += 24;
+        time->tm_mday--;
+        time->tm_yday--;
+        if (time->tm_mday < 1) {
+            time->tm_month--;
+            if (time->tm_month < 0) {
+                time->tm_month = 11;
+                time->tm_year--;
+                if (IsLeapYear(time->tm_year))
+                    time->tm_yday = 365;
+                else
+                    time->tm_yday = 364;
+            }
+            time->tm_mday = nDays[IsLeapYear(time->tm_year)][time->tm_month];
+        }
+        time->tm_wday--;
+        if (time->tm_wday < 0)
+            time->tm_wday = 6;
+    } else if (time->tm_hour > 23) {
+        /* Increment mday, yday, and wday */
+        time->tm_hour -= 24;
+        time->tm_mday++;
+        time->tm_yday++;
+        if (time->tm_mday >
+                nDays[IsLeapYear(time->tm_year)][time->tm_month]) {
+            time->tm_mday = 1;
+            time->tm_month++;
+            if (time->tm_month > 11) {
+                time->tm_month = 0;
+                time->tm_year++;
+                time->tm_yday = 0;
+            }
+        }
+        time->tm_wday++;
+        if (time->tm_wday > 6)
+            time->tm_wday = 0;
+    }
+}
+
+NSPR_API(PRTime)
+PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params)
+{
+    PRTime resolvedtime;
+    PR_NormalizeTime_NoDSTAdjust(time, PR_LocalTimeParameters);
+
+    // Resolve DST shifts explicitly. Note that this will also update *time
+    // with the corrected time.
+    resolvedtime = PR_ImplodeTime(time);
+    PR_ExplodeTime(resolvedtime, params, time);
+
+    // Return the DST-resolved PRTime.
+    return resolvedtime;
+}
+
+// This function normalizes time, but does not always resolve Daylight Savings
+// Time correctly (see SAPPHIRE-10133 for an example). It is the original
+// built-in PR_NormalizeTime function in NSPR, but should not be used outside
+// of the functions in this file - users should continue to utilize the newer
+// PR_NormalizeTime function below (see SAPPHIRE-10152).
+PR_IMPLEMENT(void)
+PR_NormalizeTime_NoDSTAdjust(PRExplodedTime *time, PRTimeParamFn params)
+{
+    int daysInMonth;
+    PRInt32 numDays;
+
+    /* Get back to GMT */
+    time->tm_sec -= time->tm_params.tp_gmt_offset
+            + time->tm_params.tp_dst_offset;
+    time->tm_params.tp_gmt_offset = 0;
+    time->tm_params.tp_dst_offset = 0;
+
+    /* Now normalize GMT */
+
+    if (time->tm_usec < 0 || time->tm_usec >= 1000000) {
+        time->tm_sec +=  time->tm_usec / 1000000;
+        time->tm_usec %= 1000000;
+        if (time->tm_usec < 0) {
+            time->tm_usec += 1000000;
+            time->tm_sec--;
+        }
+    }
+
+    /* Note that we do not count leap seconds in this implementation */
+    if (time->tm_sec < 0 || time->tm_sec >= 60) {
+        time->tm_min += time->tm_sec / 60;
+        time->tm_sec %= 60;
+        if (time->tm_sec < 0) {
+            time->tm_sec += 60;
+            time->tm_min--;
+        }
+    }
+
+    if (time->tm_min < 0 || time->tm_min >= 60) {
+        time->tm_hour += time->tm_min / 60;
+        time->tm_min %= 60;
+        if (time->tm_min < 0) {
+            time->tm_min += 60;
+            time->tm_hour--;
+        }
+    }
+
+    if (time->tm_hour < 0 || time->tm_hour >= 24) {
+        time->tm_mday += time->tm_hour / 24;
+        time->tm_hour %= 24;
+        if (time->tm_hour < 0) {
+            time->tm_hour += 24;
+            time->tm_mday--;
+        }
+    }
+
+    /* Normalize month and year before mday */
+    if (time->tm_month < 0 || time->tm_month >= 12) {
+        time->tm_year += time->tm_month / 12;
+        time->tm_month %= 12;
+        if (time->tm_month < 0) {
+            time->tm_month += 12;
+            time->tm_year--;
+        }
+    }
+
+    /* Now that month and year are in proper range, normalize mday */
+
+    if (time->tm_mday < 1) {
+        /* mday too small */
+        do {
+            /* the previous month */
+            time->tm_month--;
+            if (time->tm_month < 0) {
+                time->tm_month = 11;
+                time->tm_year--;
+            }
+            time->tm_mday += nDays[IsLeapYear(time->tm_year)][time->tm_month];
+        } while (time->tm_mday < 1);
+    } else {
+        daysInMonth = nDays[IsLeapYear(time->tm_year)][time->tm_month];
+        while (time->tm_mday > daysInMonth) {
+            /* mday too large */
+            time->tm_mday -= daysInMonth;
+            time->tm_month++;
+            if (time->tm_month > 11) {
+                time->tm_month = 0;
+                time->tm_year++;
+            }
+            daysInMonth = nDays[IsLeapYear(time->tm_year)][time->tm_month];
+        }
+    }
+
+    /* Recompute yday and wday */
+    time->tm_yday = time->tm_mday +
+            lastDayOfMonth[IsLeapYear(time->tm_year)][time->tm_month];
+	    
+    numDays = DAYS_BETWEEN_YEARS(1970, time->tm_year) + time->tm_yday;
+    time->tm_wday = (numDays + 4) % 7;
+    if (time->tm_wday < 0) {
+        time->tm_wday += 7;
+    }
+
+    /* Recompute time parameters */
+
+    time->tm_params = params(time);
+
+    ApplySecOffset(time, time->tm_params.tp_gmt_offset
+            + time->tm_params.tp_dst_offset);
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * PR_LocalTimeParameters --
+ * 
+ *     returns the time parameters for the local time zone
+ *
+ *     The following uses localtime() from the standard C library.
+ *     (time.h)  This is our fallback implementation.  Unix, PC, and BeOS
+ *     use this version.  A platform may have its own machine-dependent
+ *     implementation of this function.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#if defined(HAVE_INT_LOCALTIME_R)
+
+/*
+ * In this case we could define the macro as
+ *     #define MT_safe_localtime(timer, result) \
+ *             (localtime_r(timer, result) == 0 ? result : NULL)
+ * I chose to compare the return value of localtime_r with -1 so 
+ * that I can catch the cases where localtime_r returns a pointer
+ * to struct tm.  The macro definition above would not be able to
+ * detect such mistakes because it is legal to compare a pointer
+ * with 0.
+ */
+
+#define MT_safe_localtime(timer, result) \
+        (localtime_r(timer, result) == -1 ? NULL: result)
+
+#elif defined(HAVE_POINTER_LOCALTIME_R)
+
+#define MT_safe_localtime localtime_r
+
+#else
+
+#define HAVE_LOCALTIME_MONITOR 1  /* We use 'monitor' to serialize our calls
+                                   * to localtime(). */
+static PRLock *monitor = NULL;
+
+static struct tm *MT_safe_localtime(const time_t *clock, struct tm *result)
+{
+    struct tm *tmPtr;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) PR_Lock(monitor);
+
+    /*
+     * Microsoft (all flavors) localtime() returns a NULL pointer if 'clock'
+     * represents a time before midnight January 1, 1970.  In
+     * that case, we also return a NULL pointer and the struct tm
+     * object pointed to by 'result' is not modified.
+     *
+     * Watcom C/C++ 11.0 localtime() treats time_t as unsigned long
+     * hence, does not recognize negative values of clock as pre-1/1/70.
+     * We have to manually check (WIN16 only) for negative value of
+     * clock and return NULL.
+     *
+     * With negative values of clock, OS/2 returns the struct tm for
+     * clock plus ULONG_MAX. So we also have to check for the invalid
+     * structs returned for timezones west of Greenwich when clock == 0.
+     */
+    
+    tmPtr = localtime(clock);
+
+#if defined(WIN16) || defined(XP_OS2)
+    if ( (PRInt32) *clock < 0 ||
+         ( (PRInt32) *clock == 0 && tmPtr->tm_year != 70))
+        result = NULL;
+    else
+        *result = *tmPtr;
+#else
+    if (tmPtr) {
+        *result = *tmPtr;
+    } else {
+        result = NULL;
+    }
+#endif /* WIN16 */
+
+    if (needLock) PR_Unlock(monitor);
+
+    return result;
+}
+
+#endif  /* definition of MT_safe_localtime() */
+
+static PRBool ComputeLocalTime(time_t local, struct tm *ptm)
+{
+#ifdef HAVE_LOCALTIME_R
+    return localtime_r(&local, ptm);
+
+#elif HAVE_LOCALTIME_MONITOR
+
+    if (MT_safe_localtime(&local, ptm) != NULL)
+        return PR_TRUE;
+    else
+        return PR_FALSE;
+#else
+
+    #error no ComputeLocalTime()
+
+#endif /* definition of ComputeLocalTime() */
+}
+
+#ifndef HAVE_GMTIME_R
+
+#define HAVE_GMT_MONITOR 1  /* We use 'monitorgmt' to serialize our calls
+                             * to gmtime(). */
+
+static PRLock *monitorgmt = NULL;
+#endif
+
+static PRBool ComputeUTCTime(time_t t, struct tm *ptm)
+{
+#ifdef HAVE_GMTIME_R
+    return gmtime_r(&t, ptm);
+#else
+    PRBool retval = PR_TRUE;
+    struct tm *otm = NULL;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+    if (needLock) PR_Lock(monitorgmt);
+
+    otm = gmtime(&t);
+
+    if (!otm)
+        retval = PR_FALSE;
+    else
+    {
+        *ptm = *otm;
+        retval = PR_TRUE;
+    }
+
+    if (needLock) PR_Unlock(monitorgmt);
+
+    return retval;
+#endif /* definition of ComputeUTCTime() */
+}
+
+void _PR_InitTime(void)
+{
+#ifdef HAVE_LOCALTIME_MONITOR
+    monitor = PR_NewLock();
+#endif
+#ifdef HAVE_GMT_MONITOR
+    monitorgmt = PR_NewLock();
+#endif
+#ifdef WINCE
+    _MD_InitTime();
+#endif
+}
+
+void _PR_CleanupTime(void)
+{
+#ifdef HAVE_LOCALTIME_MONITOR
+    if (monitor) {
+        PR_DestroyLock(monitor);
+        monitor = NULL;
+    }
+#endif
+#ifdef HAVE_GMT_MONITOR
+    if (monitorgmt) {
+        PR_DestroyLock(monitorgmt);
+        monitorgmt = NULL;
+    }
+#endif
+#ifdef WINCE
+    _MD_CleanupTime();
+#endif
+}
+
+/*
+ * from https://mxr.mozilla.org/mozilla-central/source/js/src/vm/DateTime.cpp?rev=699228670afb
+ * but slightly adjusted as the modzilla has an issue during the hours close to the dst-std change
+ * Compute the offset in seconds from the current UTC time to the current local
+ * time
+ *
+ * Examples:
+ *
+ * Suppose we are in California, USA on January 1, 2013 at 04:00 PST (UTC-8, no
+ * DST in effect), corresponding to 12:00 UTC.  This function would then return
+ * -8 * SecondsPerHour, or -28800.
+ *
+ * Or suppose we are in Berlin, Germany on July 1, 2013 at 17:00 CEST (UTC+2,
+ * DST in effect), corresponding to 15:00 UTC.  This function would then return
+ * +2 * SecondsPerHour, or +7200.
+ */
+static PRInt32
+UTCToLocalTimeOffsetSeconds(time_t time)
+{
+    PRInt32 SecondsPerDay = 86400;
+    PRInt32 SecondsPerHour = 3600;
+    PRInt32 SecondsPerMinute = 60;
+    struct tm local;
+    struct tm utc;
+
+    memset(&local, 0, sizeof(local));
+    memset(&utc, 0, sizeof(utc));
+
+
+#if defined(XP_WIN)
+    // Windows doesn't follow POSIX: updates to the TZ environment variable are
+    // not reflected immediately on that platform as they are on other systems
+    // without this call.
+    _tzset();
+#endif
+
+    // Break down the current time into its components.
+    if (!ComputeLocalTime(time, &local))
+        return 0;
+
+    // Break down the local time into UTC-based components.
+    memset(&utc, 0, sizeof(utc));
+    if (!ComputeUTCTime(time, &utc))
+        return 0;
+
+    // Finally, compare the seconds-based components of the local
+    // representation and the UTC representation to determine the actual
+    // difference.
+    PRInt32 utc_secs = utc.tm_hour * SecondsPerHour + utc.tm_min * SecondsPerMinute;
+    PRInt32 local_secs = local.tm_hour * SecondsPerHour + local.tm_min * SecondsPerMinute;
+
+    // Same-day?  Just subtract the seconds counts.
+    if (utc.tm_mday == local.tm_mday)
+        return local_secs - utc_secs;
+
+    // If we have more UTC seconds, move local seconds into the UTC seconds'
+    // frame of reference and then subtract.
+    if (utc_secs > local_secs)
+        return (SecondsPerDay + local_secs) - utc_secs;
+
+    // Otherwise we have more local seconds, so move the UTC seconds into the
+    // local seconds' frame of reference and then subtract.
+    return local_secs - (utc_secs + SecondsPerDay);
+}
+
+static void
+AdjustDSTGMTOffsets(PRTime time, PRExplodedTime *exploded)
+{
+    PRInt64 sec64;
+    PRInt64 usecPerSec;
+    PRInt32 overallOffsetFromUTC;
+    PRInt32 dstoffset = 3600;
+    struct tm localTime;
+    time_t timetsecs;
+
+    LL_I2L(usecPerSec, 1000000L);
+    LL_DIV(sec64, time, usecPerSec);
+
+    timetsecs = sec64;
+
+    /*
+     *  overall_offset = gmt_offset + dst_offset
+     */
+    overallOffsetFromUTC = UTCToLocalTimeOffsetSeconds(timetsecs);
+
+    /*
+     *  used the passed time to calculate the right offsets based on
+     *  linux call to localtime
+     */
+    (void) MT_safe_localtime(&timetsecs, &localTime);
+
+    if (localTime.tm_isdst <= 0) {
+        /* DST is not in effect */
+        exploded->tm_params.tp_gmt_offset = overallOffsetFromUTC;
+        exploded->tm_params.tp_dst_offset = 0;
+    } else {
+        exploded->tm_params.tp_gmt_offset = overallOffsetFromUTC - dstoffset;
+        exploded->tm_params.tp_dst_offset = dstoffset;
+    }
+}
+
+#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS)
+
+PR_IMPLEMENT(PRTimeParameters)
+PR_LocalTimeParameters(const PRExplodedTime *gmt)
+{
+
+    PRTimeParameters retVal;
+    struct tm localTime;
+    time_t secs;
+    PRTime secs64;
+    PRInt64 usecPerSec;
+    PRInt64 usecPerSec_1;
+    PRInt64 maxInt32;
+    PRInt64 minInt32;
+    PRInt32 dayOffset;
+    PRInt32 offset2Jan1970;
+    PRInt32 offsetNew;
+    int isdst2Jan1970;
+
+    /*
+     * Calculate the GMT offset.  First, figure out what is
+     * 00:00:00 Jan. 2, 1970 GMT (which is exactly a day, or 86400
+     * seconds, since the epoch) in local time.  Then we calculate
+     * the difference between local time and GMT in seconds:
+     *     gmt_offset = local_time - GMT
+     *
+     * Caveat: the validity of this calculation depends on two
+     * assumptions:
+     * 1. Daylight saving time was not in effect on Jan. 2, 1970.
+     * 2. The time zone of the geographic location has not changed
+     *    since Jan. 2, 1970.
+     */
+
+    secs = 86400L;
+    (void) MT_safe_localtime(&secs, &localTime);
+
+    /* GMT is 00:00:00, 2nd of Jan. */
+
+    offset2Jan1970 = (PRInt32)localTime.tm_sec
+            + 60L * (PRInt32)localTime.tm_min
+            + 3600L * (PRInt32)localTime.tm_hour
+            + 86400L * (PRInt32)((PRInt32)localTime.tm_mday - 2L);
+
+    isdst2Jan1970 = localTime.tm_isdst;
+
+    /*
+     * Now compute DST offset.  We calculate the overall offset
+     * of local time from GMT, similar to above.  The overall
+     * offset has two components: gmt offset and dst offset.
+     * We subtract gmt offset from the overall offset to get
+     * the dst offset.
+     *     overall_offset = local_time - GMT
+     *     overall_offset = gmt_offset + dst_offset
+     * ==> dst_offset = local_time - GMT - gmt_offset
+     */
+
+    secs64 = PR_ImplodeTime(gmt);    /* This is still in microseconds */
+    LL_I2L(usecPerSec, PR_USEC_PER_SEC);
+    LL_I2L(usecPerSec_1, PR_USEC_PER_SEC - 1);
+    /* Convert to seconds, truncating down (3.1 -> 3 and -3.1 -> -4) */
+    if (LL_GE_ZERO(secs64)) {
+        LL_DIV(secs64, secs64, usecPerSec);
+    } else {
+        LL_NEG(secs64, secs64);
+        LL_ADD(secs64, secs64, usecPerSec_1);
+        LL_DIV(secs64, secs64, usecPerSec);
+        LL_NEG(secs64, secs64);
+    }
+    LL_I2L(maxInt32, PR_INT32_MAX);
+    LL_I2L(minInt32, PR_INT32_MIN);
+    if (LL_CMP(secs64, >, maxInt32) || LL_CMP(secs64, <, minInt32)) {
+        /* secs64 is too large or too small for time_t (32-bit integer) */
+        retVal.tp_gmt_offset = offset2Jan1970;
+        retVal.tp_dst_offset = 0;
+        return retVal;
+    }
+    LL_L2I(secs, secs64);
+
+    /*
+     * On Windows, localtime() (and our MT_safe_localtime() too)
+     * returns a NULL pointer for time before midnight January 1,
+     * 1970 GMT.  In that case, we just use the GMT offset for
+     * Jan 2, 1970 and assume that DST was not in effect.
+     */
+
+    if (MT_safe_localtime(&secs, &localTime) == NULL) {
+        retVal.tp_gmt_offset = offset2Jan1970;
+        retVal.tp_dst_offset = 0;
+        return retVal;
+    }
+
+    /*
+     * dayOffset is the offset between local time and GMT in
+     * the day component, which can only be -1, 0, or 1.  We
+     * use the day of the week to compute dayOffset.
+     */
+
+    dayOffset = (PRInt32) localTime.tm_wday - gmt->tm_wday;
+
+    /*
+     * Need to adjust for wrapping around of day of the week from
+     * 6 back to 0.
+     */
+
+    if (dayOffset == -6) {
+        /* Local time is Sunday (0) and GMT is Saturday (6) */
+        dayOffset = 1;
+    } else if (dayOffset == 6) {
+        /* Local time is Saturday (6) and GMT is Sunday (0) */
+        dayOffset = -1;
+    }
+
+    offsetNew = (PRInt32)localTime.tm_sec - gmt->tm_sec
+            + 60L * ((PRInt32)localTime.tm_min - gmt->tm_min)
+            + 3600L * ((PRInt32)localTime.tm_hour - gmt->tm_hour)
+            + 86400L * (PRInt32)dayOffset;
+
+    if (localTime.tm_isdst <= 0) {
+        /* DST is not in effect */
+        retVal.tp_gmt_offset = offsetNew;
+        retVal.tp_dst_offset = 0;
+    } else {
+        /* DST is in effect */
+        if (isdst2Jan1970 <=0) {
+            /*
+             * DST was not in effect back in 2 Jan. 1970.
+             * Use the offset back then as the GMT offset,
+             * assuming the time zone has not changed since then.
+             */
+            retVal.tp_gmt_offset = offset2Jan1970;
+            retVal.tp_dst_offset = offsetNew - offset2Jan1970;
+        } else {
+            /*
+             * DST was also in effect back in 2 Jan. 1970.
+             * Then our clever trick (or rather, ugly hack) fails.
+             * We will just assume DST offset is an hour.
+             */
+            retVal.tp_gmt_offset = offsetNew - 3600;
+            retVal.tp_dst_offset = 3600;
+        }
+    }
+
+    return retVal;
+}
+
+#endif    /* defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS) */
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * PR_USPacificTimeParameters --
+ *
+ *     The time parameters function for the US Pacific Time Zone.
+ *
+ *------------------------------------------------------------------------
+ */
+
+/*
+ * Returns the mday of the first sunday of the month, where
+ * mday and wday are for a given day in the month.
+ * mdays start with 1 (e.g. 1..31).  
+ * wdays start with 0 and are in the range 0..6.  0 = Sunday.
+ */
+#define firstSunday(mday, wday) (((mday - wday + 7 - 1) % 7) + 1)
+
+/*
+ * Returns the mday for the N'th Sunday of the month, where 
+ * mday and wday are for a given day in the month.
+ * mdays start with 1 (e.g. 1..31).  
+ * wdays start with 0 and are in the range 0..6.  0 = Sunday.
+ * N has the following values: 0 = first, 1 = second (etc), -1 = last.
+ * ndays is the number of days in that month, the same value as the 
+ * mday of the last day of the month.
+ */
+static PRInt32 
+NthSunday(PRInt32 mday, PRInt32 wday, PRInt32 N, PRInt32 ndays) 
+{
+    PRInt32 firstSun = firstSunday(mday, wday);
+
+    if (N < 0) 
+        N = (ndays - firstSun) / 7;
+    return firstSun + (7 * N);
+}
+
+typedef struct DSTParams {
+    PRInt8 dst_start_month;       /* 0 = January */
+    PRInt8 dst_start_Nth_Sunday;  /* N as defined above */
+    PRInt8 dst_start_month_ndays; /* ndays as defined above */
+    PRInt8 dst_end_month;         /* 0 = January */
+    PRInt8 dst_end_Nth_Sunday;    /* N as defined above */
+    PRInt8 dst_end_month_ndays;   /* ndays as defined above */
+} DSTParams;
+
+static const DSTParams dstParams[2] = {
+    /* year < 2007:  First April Sunday - Last October Sunday */
+    { 3, 0, 30, 9, -1, 31 },
+    /* year >= 2007: Second March Sunday - First November Sunday */
+    { 2, 1, 31, 10, 0, 30 }
+};
+
+PR_IMPLEMENT(PRTimeParameters)
+PR_USPacificTimeParameters(const PRExplodedTime *gmt)
+{
+    const DSTParams *dst;
+    PRTimeParameters retVal;
+    PRExplodedTime st;
+
+    /*
+     * Based on geographic location and GMT, figure out offset of
+     * standard time from GMT.  In this example implementation, we
+     * assume the local time zone is US Pacific Time.
+     */
+
+    retVal.tp_gmt_offset = -8L * 3600L;
+
+    /*
+     * Make a copy of GMT.  Note that the tm_params field of this copy
+     * is ignored.
+     */
+
+    st.tm_usec = gmt->tm_usec;
+    st.tm_sec = gmt->tm_sec;
+    st.tm_min = gmt->tm_min;
+    st.tm_hour = gmt->tm_hour;
+    st.tm_mday = gmt->tm_mday;
+    st.tm_month = gmt->tm_month;
+    st.tm_year = gmt->tm_year;
+    st.tm_wday = gmt->tm_wday;
+    st.tm_yday = gmt->tm_yday;
+
+    /* Apply the offset to GMT to obtain the local standard time */
+    ApplySecOffset(&st, retVal.tp_gmt_offset);
+
+    if (st.tm_year < 2007) { /* first April Sunday - Last October Sunday */
+	dst = &dstParams[0];
+    } else {                 /* Second March Sunday - First November Sunday */
+	dst = &dstParams[1];
+    }
+
+    /*
+     * Apply the rules on standard time or GMT to obtain daylight saving
+     * time offset.  In this implementation, we use the US DST rule.
+     */
+    if (st.tm_month < dst->dst_start_month) {
+        retVal.tp_dst_offset = 0L;
+    } else if (st.tm_month == dst->dst_start_month) {
+	int NthSun = NthSunday(st.tm_mday, st.tm_wday, 
+			       dst->dst_start_Nth_Sunday, 
+			       dst->dst_start_month_ndays);
+	if (st.tm_mday < NthSun) {              /* Before starting Sunday */
+	    retVal.tp_dst_offset = 0L;
+        } else if (st.tm_mday == NthSun) {      /* Starting Sunday */
+	    /* 01:59:59 PST -> 03:00:00 PDT */
+	    if (st.tm_hour < 2) {
+		retVal.tp_dst_offset = 0L;
+	    } else {
+		retVal.tp_dst_offset = 3600L;
+	    }
+	} else {                                /* After starting Sunday */
+	    retVal.tp_dst_offset = 3600L;
+        }
+    } else if (st.tm_month < dst->dst_end_month) {
+        retVal.tp_dst_offset = 3600L;
+    } else if (st.tm_month == dst->dst_end_month) {
+	int NthSun = NthSunday(st.tm_mday, st.tm_wday, 
+			       dst->dst_end_Nth_Sunday, 
+			       dst->dst_end_month_ndays);
+	if (st.tm_mday < NthSun) {              /* Before ending Sunday */
+	    retVal.tp_dst_offset = 3600L;
+        } else if (st.tm_mday == NthSun) {      /* Ending Sunday */
+	    /* 01:59:59 PDT -> 01:00:00 PST */
+	    if (st.tm_hour < 1) {
+		retVal.tp_dst_offset = 3600L;
+	    } else {
+		retVal.tp_dst_offset = 0L;
+	    }
+	} else {                                /* After ending Sunday */
+	    retVal.tp_dst_offset = 0L;
+        }
+    } else {
+        retVal.tp_dst_offset = 0L;
+    }
+    return retVal;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * PR_GMTParameters --
+ *
+ *     Returns the PRTimeParameters for Greenwich Mean Time.
+ *     Trivially, both the tp_gmt_offset and tp_dst_offset fields are 0.
+ *
+ *------------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTimeParameters)
+PR_GMTParameters(const PRExplodedTime *gmt)
+{
+    PRTimeParameters retVal = { 0, 0 };
+    return retVal;
+}
+
+/*
+ * The following code implements PR_ParseTimeString().  It is based on
+ * ns/lib/xp/xp_time.c, revision 1.25, by Jamie Zawinski <jwz@netscape.com>.
+ */
+
+/*
+ * We only recognize the abbreviations of a small subset of time zones
+ * in North America, Europe, and Japan.
+ *
+ * PST/PDT: Pacific Standard/Daylight Time
+ * MST/MDT: Mountain Standard/Daylight Time
+ * CST/CDT: Central Standard/Daylight Time
+ * EST/EDT: Eastern Standard/Daylight Time
+ * AST: Atlantic Standard Time
+ * NST: Newfoundland Standard Time
+ * GMT: Greenwich Mean Time
+ * BST: British Summer Time
+ * MET: Middle Europe Time
+ * EET: Eastern Europe Time
+ * JST: Japan Standard Time
+ */
+
+typedef enum
+{
+  TT_UNKNOWN,
+
+  TT_SUN, TT_MON, TT_TUE, TT_WED, TT_THU, TT_FRI, TT_SAT,
+
+  TT_JAN, TT_FEB, TT_MAR, TT_APR, TT_MAY, TT_JUN,
+  TT_JUL, TT_AUG, TT_SEP, TT_OCT, TT_NOV, TT_DEC,
+
+  TT_PST, TT_PDT, TT_MST, TT_MDT, TT_CST, TT_CDT, TT_EST, TT_EDT,
+  TT_AST, TT_NST, TT_GMT, TT_BST, TT_MET, TT_EET, TT_JST
+} TIME_TOKEN;
+
+/*
+ * This parses a time/date string into a PRTime
+ * (microseconds after "1-Jan-1970 00:00:00 GMT").
+ * It returns PR_SUCCESS on success, and PR_FAILURE
+ * if the time/date string can't be parsed.
+ *
+ * Many formats are handled, including:
+ *
+ *   14 Apr 89 03:20:12
+ *   14 Apr 89 03:20 GMT
+ *   Fri, 17 Mar 89 4:01:33
+ *   Fri, 17 Mar 89 4:01 GMT
+ *   Mon Jan 16 16:12 PDT 1989
+ *   Mon Jan 16 16:12 +0130 1989
+ *   6 May 1992 16:41-JST (Wednesday)
+ *   22-AUG-1993 10:59:12.82
+ *   22-AUG-1993 10:59pm
+ *   22-AUG-1993 12:59am
+ *   22-AUG-1993 12:59 PM
+ *   Friday, August 04, 1995 3:54 PM
+ *   06/21/95 04:24:34 PM
+ *   20/06/95 21:07
+ *   95-06-08 19:32:48 EDT
+ *
+ * If the input string doesn't contain a description of the timezone,
+ * we consult the `default_to_gmt' to decide whether the string should
+ * be interpreted relative to the local time zone (PR_FALSE) or GMT (PR_TRUE).
+ * The correct value for this argument depends on what standard specified
+ * the time string which you are parsing.
+ */
+
+PR_IMPLEMENT(PRStatus)
+PR_ParseTimeStringToExplodedTime(
+        const char *string,
+        PRBool default_to_gmt,
+        PRExplodedTime *result)
+{
+  TIME_TOKEN dotw = TT_UNKNOWN;
+  TIME_TOKEN month = TT_UNKNOWN;
+  TIME_TOKEN zone = TT_UNKNOWN;
+  int zone_offset = -1;
+  int dst_offset = 0;
+  int date = -1;
+  PRInt32 year = -1;
+  int hour = -1;
+  int min = -1;
+  int sec = -1;
+
+  const char *rest = string;
+
+  int iterations = 0;
+
+  PR_ASSERT(string && result);
+  if (!string || !result) return PR_FAILURE;
+
+  while (*rest)
+        {
+
+          if (iterations++ > 1000)
+                {
+                  return PR_FAILURE;
+                }
+
+          switch (*rest)
+                {
+                case 'a': case 'A':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'p' || rest[1] == 'P') &&
+                          (rest[2] == 'r' || rest[2] == 'R'))
+                        month = TT_APR;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_AST;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'g' || rest[2] == 'G'))
+                        month = TT_AUG;
+                  break;
+                case 'b': case 'B':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 's' || rest[1] == 'S') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_BST;
+                  break;
+                case 'c': case 'C':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 'd' || rest[1] == 'D') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_CDT;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_CST;
+                  break;
+                case 'd': case 'D':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'e' || rest[1] == 'E') &&
+                          (rest[2] == 'c' || rest[2] == 'C'))
+                        month = TT_DEC;
+                  break;
+                case 'e': case 'E':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 'd' || rest[1] == 'D') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_EDT;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 'e' || rest[1] == 'E') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_EET;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_EST;
+                  break;
+                case 'f': case 'F':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'e' || rest[1] == 'E') &&
+                          (rest[2] == 'b' || rest[2] == 'B'))
+                        month = TT_FEB;
+                  else if (dotw == TT_UNKNOWN &&
+                                   (rest[1] == 'r' || rest[1] == 'R') &&
+                                   (rest[2] == 'i' || rest[2] == 'I'))
+                        dotw = TT_FRI;
+                  break;
+                case 'g': case 'G':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 'm' || rest[1] == 'M') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_GMT;
+                  break;
+                case 'j': case 'J':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'a' || rest[1] == 'A') &&
+                          (rest[2] == 'n' || rest[2] == 'N'))
+                        month = TT_JAN;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_JST;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'l' || rest[2] == 'L'))
+                        month = TT_JUL;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'n' || rest[2] == 'N'))
+                        month = TT_JUN;
+                  break;
+                case 'm': case 'M':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'a' || rest[1] == 'A') &&
+                          (rest[2] == 'r' || rest[2] == 'R'))
+                        month = TT_MAR;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'a' || rest[1] == 'A') &&
+                                   (rest[2] == 'y' || rest[2] == 'Y'))
+                        month = TT_MAY;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 'd' || rest[1] == 'D') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_MDT;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 'e' || rest[1] == 'E') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_MET;
+                  else if (dotw == TT_UNKNOWN &&
+                                   (rest[1] == 'o' || rest[1] == 'O') &&
+                                   (rest[2] == 'n' || rest[2] == 'N'))
+                        dotw = TT_MON;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_MST;
+                  break;
+                case 'n': case 'N':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'o' || rest[1] == 'O') &&
+                          (rest[2] == 'v' || rest[2] == 'V'))
+                        month = TT_NOV;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_NST;
+                  break;
+                case 'o': case 'O':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'c' || rest[1] == 'C') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        month = TT_OCT;
+                  break;
+                case 'p': case 'P':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 'd' || rest[1] == 'D') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_PDT;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_PST;
+                  break;
+                case 's': case 'S':
+                  if (dotw == TT_UNKNOWN &&
+                          (rest[1] == 'a' || rest[1] == 'A') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        dotw = TT_SAT;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'e' || rest[1] == 'E') &&
+                                   (rest[2] == 'p' || rest[2] == 'P'))
+                        month = TT_SEP;
+                  else if (dotw == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'n' || rest[2] == 'N'))
+                        dotw = TT_SUN;
+                  break;
+                case 't': case 'T':
+                  if (dotw == TT_UNKNOWN &&
+                          (rest[1] == 'h' || rest[1] == 'H') &&
+                          (rest[2] == 'u' || rest[2] == 'U'))
+                        dotw = TT_THU;
+                  else if (dotw == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'e' || rest[2] == 'E'))
+                        dotw = TT_TUE;
+                  break;
+                case 'u': case 'U':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 't' || rest[1] == 'T') &&
+                          !(rest[2] >= 'A' && rest[2] <= 'Z') &&
+                          !(rest[2] >= 'a' && rest[2] <= 'z'))
+                        /* UT is the same as GMT but UTx is not. */
+                        zone = TT_GMT;
+                  break;
+                case 'w': case 'W':
+                  if (dotw == TT_UNKNOWN &&
+                          (rest[1] == 'e' || rest[1] == 'E') &&
+                          (rest[2] == 'd' || rest[2] == 'D'))
+                        dotw = TT_WED;
+                  break;
+
+                case '+': case '-':
+                  {
+                        const char *end;
+                        int sign;
+                        if (zone_offset != -1)
+                          {
+                                /* already got one... */
+                                rest++;
+                                break;
+                          }
+                        if (zone != TT_UNKNOWN && zone != TT_GMT)
+                          {
+                                /* GMT+0300 is legal, but PST+0300 is not. */
+                                rest++;
+                                break;
+                          }
+
+                        sign = ((*rest == '+') ? 1 : -1);
+                        rest++; /* move over sign */
+                        end = rest;
+                        while (*end >= '0' && *end <= '9')
+                          end++;
+                        if (rest == end) /* no digits here */
+                          break;
+
+                        if ((end - rest) == 4)
+                          /* offset in HHMM */
+                          zone_offset = (((((rest[0]-'0')*10) + (rest[1]-'0')) * 60) +
+                                                         (((rest[2]-'0')*10) + (rest[3]-'0')));
+                        else if ((end - rest) == 2)
+                          /* offset in hours */
+                          zone_offset = (((rest[0]-'0')*10) + (rest[1]-'0')) * 60;
+                        else if ((end - rest) == 1)
+                          /* offset in hours */
+                          zone_offset = (rest[0]-'0') * 60;
+                        else
+                          /* 3 or >4 */
+                          break;
+
+                        zone_offset *= sign;
+                        zone = TT_GMT;
+                        break;
+                  }
+
+                case '0': case '1': case '2': case '3': case '4':
+                case '5': case '6': case '7': case '8': case '9':
+                  {
+                        int tmp_hour = -1;
+                        int tmp_min = -1;
+                        int tmp_sec = -1;
+                        const char *end = rest + 1;
+                        while (*end >= '0' && *end <= '9')
+                          end++;
+
+                        /* end is now the first character after a range of digits. */
+
+                        if (*end == ':')
+                          {
+                                if (hour >= 0 && min >= 0) /* already got it */
+                                  break;
+
+                                /* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */
+                                if ((end - rest) > 2)
+                                  /* it is [0-9][0-9][0-9]+: */
+                                  break;
+                                else if ((end - rest) == 2)
+                                  tmp_hour = ((rest[0]-'0')*10 +
+                                                          (rest[1]-'0'));
+                                else
+                                  tmp_hour = (rest[0]-'0');
+
+                                /* move over the colon, and parse minutes */
+
+                                rest = ++end;
+                                while (*end >= '0' && *end <= '9')
+                                  end++;
+
+                                if (end == rest)
+                                  /* no digits after first colon? */
+                                  break;
+                                else if ((end - rest) > 2)
+                                  /* it is [0-9][0-9][0-9]+: */
+                                  break;
+                                else if ((end - rest) == 2)
+                                  tmp_min = ((rest[0]-'0')*10 +
+                                                         (rest[1]-'0'));
+                                else
+                                  tmp_min = (rest[0]-'0');
+
+                                /* now go for seconds */
+                                rest = end;
+                                if (*rest == ':')
+                                  rest++;
+                                end = rest;
+                                while (*end >= '0' && *end <= '9')
+                                  end++;
+
+                                if (end == rest)
+                                  /* no digits after second colon - that's ok. */
+                                  ;
+                                else if ((end - rest) > 2)
+                                  /* it is [0-9][0-9][0-9]+: */
+                                  break;
+                                else if ((end - rest) == 2)
+                                  tmp_sec = ((rest[0]-'0')*10 +
+                                                         (rest[1]-'0'));
+                                else
+                                  tmp_sec = (rest[0]-'0');
+
+                                /* If we made it here, we've parsed hour and min,
+                                   and possibly sec, so it worked as a unit. */
+
+                                /* skip over whitespace and see if there's an AM or PM
+                                   directly following the time.
+                                 */
+                                if (tmp_hour <= 12)
+                                  {
+                                        const char *s = end;
+                                        while (*s && (*s == ' ' || *s == '\t'))
+                                          s++;
+                                        if ((s[0] == 'p' || s[0] == 'P') &&
+                                                (s[1] == 'm' || s[1] == 'M'))
+                                          /* 10:05pm == 22:05, and 12:05pm == 12:05 */
+                                          tmp_hour = (tmp_hour == 12 ? 12 : tmp_hour + 12);
+                                        else if (tmp_hour == 12 &&
+                                                         (s[0] == 'a' || s[0] == 'A') &&
+                                                         (s[1] == 'm' || s[1] == 'M'))
+                                          /* 12:05am == 00:05 */
+                                          tmp_hour = 0;
+                                  }
+
+                                hour = tmp_hour;
+                                min = tmp_min;
+                                sec = tmp_sec;
+                                rest = end;
+                                break;
+                          }
+                        else if ((*end == '/' || *end == '-') &&
+                                         end[1] >= '0' && end[1] <= '9')
+                          {
+                                /* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95
+                                   or even 95-06-05...
+                                   #### But it doesn't handle 1995-06-22.
+                                 */
+                                int n1, n2, n3;
+                                const char *s;
+
+                                if (month != TT_UNKNOWN)
+                                  /* if we saw a month name, this can't be. */
+                                  break;
+
+                                s = rest;
+
+                                n1 = (*s++ - '0');                                /* first 1 or 2 digits */
+                                if (*s >= '0' && *s <= '9')
+                                  n1 = n1*10 + (*s++ - '0');
+
+                                if (*s != '/' && *s != '-')                /* slash */
+                                  break;
+                                s++;
+
+                                if (*s < '0' || *s > '9')                /* second 1 or 2 digits */
+                                  break;
+                                n2 = (*s++ - '0');
+                                if (*s >= '0' && *s <= '9')
+                                  n2 = n2*10 + (*s++ - '0');
+
+                                if (*s != '/' && *s != '-')                /* slash */
+                                  break;
+                                s++;
+
+                                if (*s < '0' || *s > '9')                /* third 1, 2, 4, or 5 digits */
+                                  break;
+                                n3 = (*s++ - '0');
+                                if (*s >= '0' && *s <= '9')
+                                  n3 = n3*10 + (*s++ - '0');
+
+                                if (*s >= '0' && *s <= '9')            /* optional digits 3, 4, and 5 */
+                                  {
+                                        n3 = n3*10 + (*s++ - '0');
+                                        if (*s < '0' || *s > '9')
+                                          break;
+                                        n3 = n3*10 + (*s++ - '0');
+                                        if (*s >= '0' && *s <= '9')
+                                          n3 = n3*10 + (*s++ - '0');
+                                  }
+
+                                if ((*s >= '0' && *s <= '9') ||        /* followed by non-alphanum */
+                                        (*s >= 'A' && *s <= 'Z') ||
+                                        (*s >= 'a' && *s <= 'z'))
+                                  break;
+
+                                /* Ok, we parsed three 1-2 digit numbers, with / or -
+                                   between them.  Now decide what the hell they are
+                                   (DD/MM/YY or MM/DD/YY or YY/MM/DD.)
+                                 */
+
+                                if (n1 > 31 || n1 == 0)  /* must be YY/MM/DD */
+                                  {
+                                        if (n2 > 12) break;
+                                        if (n3 > 31) break;
+                                        year = n1;
+                                        if (year < 70)
+                                            year += 2000;
+                                        else if (year < 100)
+                                            year += 1900;
+                                        month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1);
+                                        date = n3;
+                                        rest = s;
+                                        break;
+                                  }
+
+                                if (n1 > 12 && n2 > 12)  /* illegal */
+                                  {
+                                        rest = s;
+                                        break;
+                                  }
+
+                                if (n3 < 70)
+                                    n3 += 2000;
+                                else if (n3 < 100)
+                                    n3 += 1900;
+
+                                if (n1 > 12)  /* must be DD/MM/YY */
+                                  {
+                                        date = n1;
+                                        month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1);
+                                        year = n3;
+                                  }
+                                else                  /* assume MM/DD/YY */
+                                  {
+                                        /* #### In the ambiguous case, should we consult the
+                                           locale to find out the local default? */
+                                        month = (TIME_TOKEN)(n1 + ((int)TT_JAN) - 1);
+                                        date = n2;
+                                        year = n3;
+                                  }
+                                rest = s;
+                          }
+                        else if ((*end >= 'A' && *end <= 'Z') ||
+                                         (*end >= 'a' && *end <= 'z'))
+                          /* Digits followed by non-punctuation - what's that? */
+                          ;
+                        else if ((end - rest) == 5)                /* five digits is a year */
+                          year = (year < 0
+                                          ? ((rest[0]-'0')*10000L +
+                                                 (rest[1]-'0')*1000L +
+                                                 (rest[2]-'0')*100L +
+                                                 (rest[3]-'0')*10L +
+                                                 (rest[4]-'0'))
+                                          : year);
+                        else if ((end - rest) == 4)                /* four digits is a year */
+                          year = (year < 0
+                                          ? ((rest[0]-'0')*1000L +
+                                                 (rest[1]-'0')*100L +
+                                                 (rest[2]-'0')*10L +
+                                                 (rest[3]-'0'))
+                                          : year);
+                        else if ((end - rest) == 2)                /* two digits - date or year */
+                          {
+                                int n = ((rest[0]-'0')*10 +
+                                                 (rest[1]-'0'));
+                                /* If we don't have a date (day of the month) and we see a number
+                                     less than 32, then assume that is the date.
+
+                                         Otherwise, if we have a date and not a year, assume this is the
+                                         year.  If it is less than 70, then assume it refers to the 21st
+                                         century.  If it is two digits (>= 70), assume it refers to this
+                                         century.  Otherwise, assume it refers to an unambiguous year.
+
+                                         The world will surely end soon.
+                                   */
+                                if (date < 0 && n < 32)
+                                  date = n;
+                                else if (year < 0)
+                                  {
+                                        if (n < 70)
+                                          year = 2000 + n;
+                                        else if (n < 100)
+                                          year = 1900 + n;
+                                        else
+                                          year = n;
+                                  }
+                                /* else what the hell is this. */
+                          }
+                        else if ((end - rest) == 1)                /* one digit - date */
+                          date = (date < 0 ? (rest[0]-'0') : date);
+                        /* else, three or more than five digits - what's that? */
+
+                        break;
+                  }
+                }
+
+          /* Skip to the end of this token, whether we parsed it or not.
+                 Tokens are delimited by whitespace, or ,;-/
+                 But explicitly not :+-.
+           */
+          while (*rest &&
+                         *rest != ' ' && *rest != '\t' &&
+                         *rest != ',' && *rest != ';' &&
+                         *rest != '-' && *rest != '+' &&
+                         *rest != '/' &&
+                         *rest != '(' && *rest != ')' && *rest != '[' && *rest != ']')
+                rest++;
+          /* skip over uninteresting chars. */
+        SKIP_MORE:
+          while (*rest &&
+                         (*rest == ' ' || *rest == '\t' ||
+                          *rest == ',' || *rest == ';' || *rest == '/' ||
+                          *rest == '(' || *rest == ')' || *rest == '[' || *rest == ']'))
+                rest++;
+
+          /* "-" is ignored at the beginning of a token if we have not yet
+                 parsed a year (e.g., the second "-" in "30-AUG-1966"), or if
+                 the character after the dash is not a digit. */         
+          if (*rest == '-' && ((rest > string && isalpha(rest[-1]) && year < 0)
+              || rest[1] < '0' || rest[1] > '9'))
+                {
+                  rest++;
+                  goto SKIP_MORE;
+                }
+
+        }
+
+  if (zone != TT_UNKNOWN && zone_offset == -1)
+        {
+          switch (zone)
+                {
+                case TT_PST: zone_offset = -8 * 60; break;
+                case TT_PDT: zone_offset = -8 * 60; dst_offset = 1 * 60; break;
+                case TT_MST: zone_offset = -7 * 60; break;
+                case TT_MDT: zone_offset = -7 * 60; dst_offset = 1 * 60; break;
+                case TT_CST: zone_offset = -6 * 60; break;
+                case TT_CDT: zone_offset = -6 * 60; dst_offset = 1 * 60; break;
+                case TT_EST: zone_offset = -5 * 60; break;
+                case TT_EDT: zone_offset = -5 * 60; dst_offset = 1 * 60; break;
+                case TT_AST: zone_offset = -4 * 60; break;
+                case TT_NST: zone_offset = -3 * 60 - 30; break;
+                case TT_GMT: zone_offset =  0 * 60; break;
+                case TT_BST: zone_offset =  0 * 60; dst_offset = 1 * 60; break;
+                case TT_MET: zone_offset =  1 * 60; break;
+                case TT_EET: zone_offset =  2 * 60; break;
+                case TT_JST: zone_offset =  9 * 60; break;
+                default:
+                  PR_ASSERT (0);
+                  break;
+                }
+        }
+
+  /* If we didn't find a year, month, or day-of-the-month, we can't
+         possibly parse this, and in fact, mktime() will do something random
+         (I'm seeing it return "Tue Feb  5 06:28:16 2036", which is no doubt
+         a numerologically significant date... */
+  if (month == TT_UNKNOWN || date == -1 || year == -1 || year > PR_INT16_MAX)
+      return PR_FAILURE;
+
+  memset(result, 0, sizeof(*result));
+  if (sec != -1)
+        result->tm_sec = sec;
+  if (min != -1)
+        result->tm_min = min;
+  if (hour != -1)
+        result->tm_hour = hour;
+  if (date != -1)
+        result->tm_mday = date;
+  if (month != TT_UNKNOWN)
+        result->tm_month = (((int)month) - ((int)TT_JAN));
+  if (year != -1)
+        result->tm_year = year;
+  if (dotw != TT_UNKNOWN)
+        result->tm_wday = (((int)dotw) - ((int)TT_SUN));
+  /*
+   * Mainly to compute wday and yday, but normalized time is also required
+   * by the check below that works around a Visual C++ 2005 mktime problem.
+   */
+  PR_NormalizeTime_NoDSTAdjust(result, PR_GMTParameters);
+  /* The remaining work is to set the gmt and dst offsets in tm_params. */
+
+  if (zone == TT_UNKNOWN && default_to_gmt)
+        {
+          /* No zone was specified, so pretend the zone was GMT. */
+          zone = TT_GMT;
+          zone_offset = 0;
+        }
+
+  if (zone_offset == -1)
+         {
+           /* no zone was specified, and we're to assume that everything
+             is local. */
+          struct tm localTime;
+          time_t secs;
+
+          PR_ASSERT(result->tm_month > -1 &&
+                    result->tm_mday > 0 &&
+                    result->tm_hour > -1 &&
+                    result->tm_min > -1 &&
+                    result->tm_sec > -1);
+
+            /*
+             * To obtain time_t from a tm structure representing the local
+             * time, we call mktime().  However, we need to see if we are
+             * on 1-Jan-1970 or before.  If we are, we can't call mktime()
+             * because mktime() will crash on win16. In that case, we
+             * calculate zone_offset based on the zone offset at 
+             * 00:00:00, 2 Jan 1970 GMT, and subtract zone_offset from the
+             * date we are parsing to transform the date to GMT.  We also
+             * do so if mktime() returns (time_t) -1 (time out of range).
+           */
+
+          /* month, day, hours, mins and secs are always non-negative
+             so we dont need to worry about them. */  
+          if(result->tm_year >= 1970)
+                {
+                  PRInt64 usec_per_sec;
+
+                  localTime.tm_sec = result->tm_sec;
+                  localTime.tm_min = result->tm_min;
+                  localTime.tm_hour = result->tm_hour;
+                  localTime.tm_mday = result->tm_mday;
+                  localTime.tm_mon = result->tm_month;
+                  localTime.tm_year = result->tm_year - 1900;
+                  /* Set this to -1 to tell mktime "I don't care".  If you set
+                     it to 0 or 1, you are making assertions about whether the
+                     date you are handing it is in daylight savings mode or not;
+                     and if you're wrong, it will "fix" it for you. */
+                  localTime.tm_isdst = -1;
+
+#if _MSC_VER == 1400  /* 1400 = Visual C++ 2005 (8.0) */
+                  /*
+                   * mktime will return (time_t) -1 if the input is a date
+                   * after 23:59:59, December 31, 3000, US Pacific Time (not
+                   * UTC as documented): 
+                   * http://msdn.microsoft.com/en-us/library/d1y53h2a(VS.80).aspx
+                   * But if the year is 3001, mktime also invokes the invalid
+                   * parameter handler, causing the application to crash.  This
+                   * problem has been reported in
+                   * http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=266036.
+                   * We avoid this crash by not calling mktime if the date is
+                   * out of range.  To use a simple test that works in any time
+                   * zone, we consider year 3000 out of range as well.  (See
+                   * bug 480740.)
+                   */
+                  if (result->tm_year >= 3000) {
+                      /* Emulate what mktime would have done. */
+                      errno = EINVAL;
+                      secs = (time_t) -1;
+                  } else {
+                      secs = mktime(&localTime);
+                  }
+#else
+                  secs = mktime(&localTime);
+#endif
+                  if (secs != (time_t) -1)
+                    {
+                      PRTime usecs64;
+                      LL_I2L(usecs64, secs);
+                      LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
+                      LL_MUL(usecs64, usecs64, usec_per_sec);
+                      PR_ExplodeTime(usecs64, PR_LocalTimeParameters, result);
+                      return PR_SUCCESS;
+                    }
+                }
+                
+                /* So mktime() can't handle this case.  We assume the
+                   zone_offset for the date we are parsing is the same as
+                   the zone offset on 00:00:00 2 Jan 1970 GMT. */
+                secs = 86400;
+                (void) MT_safe_localtime(&secs, &localTime);
+                zone_offset = localTime.tm_min
+                              + 60 * localTime.tm_hour
+                              + 1440 * (localTime.tm_mday - 2);
+        }
+
+  result->tm_params.tp_gmt_offset = zone_offset * 60;
+  result->tm_params.tp_dst_offset = dst_offset * 60;
+
+  return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ParseTimeString(
+        const char *string,
+        PRBool default_to_gmt,
+        PRTime *result)
+{
+  PRExplodedTime tm;
+  PRStatus rv;
+
+  rv = PR_ParseTimeStringToExplodedTime(string,
+                                        default_to_gmt,
+                                        &tm);
+  if (rv != PR_SUCCESS)
+        return rv;
+
+  *result = PR_ImplodeTime(&tm);
+
+  return PR_SUCCESS;
+}
+
+/*
+ *******************************************************************
+ *******************************************************************
+ **
+ **    OLD COMPATIBILITY FUNCTIONS
+ **
+ *******************************************************************
+ *******************************************************************
+ */
+
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_FormatTime --
+ *
+ *     Format a time value into a buffer. Same semantics as strftime().
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRUint32)
+PR_FormatTime(char *buf, int buflen, const char *fmt, const PRExplodedTime *tm)
+{
+    size_t rv;
+    struct tm a;
+    struct tm *ap;
+
+    if (tm) {
+        ap = &a;
+        a.tm_sec = tm->tm_sec;
+        a.tm_min = tm->tm_min;
+        a.tm_hour = tm->tm_hour;
+        a.tm_mday = tm->tm_mday;
+        a.tm_mon = tm->tm_month;
+        a.tm_wday = tm->tm_wday;
+        a.tm_year = tm->tm_year - 1900;
+        a.tm_yday = tm->tm_yday;
+        a.tm_isdst = tm->tm_params.tp_dst_offset ? 1 : 0;
+
+        /*
+         * On some platforms, for example SunOS 4, struct tm has two
+         * additional fields: tm_zone and tm_gmtoff.
+         */
+
+#if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) \
+        || defined(NETBSD) || defined(OPENBSD) || defined(FREEBSD) \
+        || defined(DARWIN) || defined(SYMBIAN) || defined(ANDROID)
+        a.tm_zone = NULL;
+        a.tm_gmtoff = tm->tm_params.tp_gmt_offset +
+                      tm->tm_params.tp_dst_offset;
+#endif
+    } else {
+        ap = NULL;
+    }
+
+    rv = strftime(buf, buflen, fmt, ap);
+    if (!rv && buf && buflen > 0) {
+        /*
+         * When strftime fails, the contents of buf are indeterminate.
+         * Some callers don't check the return value from this function,
+         * so store an empty string in buf in case they try to print it.
+         */
+        buf[0] = '\0';
+    }
+    return rv;
+}
+
+
+/*
+ * The following string arrays and macros are used by PR_FormatTimeUSEnglish().
+ */
+
+static const char* abbrevDays[] =
+{
+   "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
+};
+
+static const char* days[] =
+{
+   "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
+};
+
+static const char* abbrevMonths[] =
+{
+   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static const char* months[] =
+{ 
+    "January", "February", "March", "April", "May", "June",
+    "July", "August", "September", "October", "November", "December"
+};
+
+
+/*
+ * Add a single character to the given buffer, incrementing the buffer pointer
+ * and decrementing the buffer size. Return 0 on error.
+ */
+#define ADDCHAR( buf, bufSize, ch )             \
+do                                              \
+{                                               \
+   if( bufSize < 1 )                            \
+   {                                            \
+      *(--buf) = '\0';                          \
+      return 0;                                 \
+   }                                            \
+   *buf++ = ch;                                 \
+   bufSize--;                                   \
+}                                               \
+while(0)
+
+
+/*
+ * Add a string to the given buffer, incrementing the buffer pointer
+ * and decrementing the buffer size appropriately.  Return 0 on error.
+ */
+#define ADDSTR( buf, bufSize, str )             \
+do                                              \
+{                                               \
+   PRUint32 strSize = strlen( str );              \
+   if( strSize > bufSize )                      \
+   {                                            \
+      if( bufSize==0 )                          \
+         *(--buf) = '\0';                       \
+      else                                      \
+         *buf = '\0';                           \
+      return 0;                                 \
+   }                                            \
+   memcpy(buf, str, strSize);                   \
+   buf += strSize;                              \
+   bufSize -= strSize;                          \
+}                                               \
+while(0)
+
+/* Needed by PR_FormatTimeUSEnglish() */
+static unsigned int  pr_WeekOfYear(const PRExplodedTime* time,
+        unsigned int firstDayOfWeek);
+
+
+/***********************************************************************************
+ *
+ * Description:
+ *  This is a dumbed down version of strftime that will format the date in US
+ *  English regardless of the setting of the global locale.  This functionality is
+ *  needed to write things like MIME headers which must always be in US English.
+ *
+ **********************************************************************************/
+             
+PR_IMPLEMENT(PRUint32)
+PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize,
+                        const char* format, const PRExplodedTime* time )
+{
+   char*         bufPtr = buf;
+   const char*   fmtPtr;
+   char          tmpBuf[ 40 ];        
+   const int     tmpBufSize = sizeof( tmpBuf );
+
+   
+   for( fmtPtr=format; *fmtPtr != '\0'; fmtPtr++ )
+   {
+      if( *fmtPtr != '%' )
+      {
+         ADDCHAR( bufPtr, bufSize, *fmtPtr );
+      }
+      else
+      {
+         switch( *(++fmtPtr) )
+         {
+         case '%':
+            /* escaped '%' character */
+            ADDCHAR( bufPtr, bufSize, '%' );
+            break;
+            
+         case 'a':
+            /* abbreviated weekday name */
+            ADDSTR( bufPtr, bufSize, abbrevDays[ time->tm_wday ] );
+            break;
+               
+         case 'A':
+            /* full weekday name */
+            ADDSTR( bufPtr, bufSize, days[ time->tm_wday ] );
+            break;
+        
+         case 'b':
+            /* abbreviated month name */
+            ADDSTR( bufPtr, bufSize, abbrevMonths[ time->tm_month ] );
+            break;
+        
+         case 'B':
+            /* full month name */
+            ADDSTR(bufPtr, bufSize,  months[ time->tm_month ] );
+            break;
+        
+         case 'c':
+            /* Date and time. */
+            PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%a %b %d %H:%M:%S %Y", time );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'd':
+            /* day of month ( 01 - 31 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_mday );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+
+         case 'H':
+            /* hour ( 00 - 23 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_hour );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'I':
+            /* hour ( 01 - 12 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",
+                        (time->tm_hour%12) ? time->tm_hour%12 : (PRInt32) 12 );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'j':
+            /* day number of year ( 001 - 366 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.3d",time->tm_yday + 1);
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'm':
+            /* month number ( 01 - 12 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_month+1);
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'M':
+            /* minute ( 00 - 59 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_min );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+       
+         case 'p':
+            /* locale's equivalent of either AM or PM */
+            ADDSTR( bufPtr, bufSize, (time->tm_hour<12)?"AM":"PM" ); 
+            break;
+        
+         case 'S':
+            /* seconds ( 00 - 61 ), allows for leap seconds */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_sec );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+     
+         case 'U':
+            /* week number of year ( 00 - 53  ),  Sunday  is  the first day of week 1 */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 0 ) );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'w':
+            /* weekday number ( 0 - 6 ), Sunday = 0 */
+            PR_snprintf(tmpBuf,tmpBufSize,"%d",time->tm_wday );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'W':
+            /* Week number of year ( 00 - 53  ),  Monday  is  the first day of week 1 */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 1 ) );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'x':
+            /* Date representation */
+            PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%m/%d/%y", time );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'X':
+            /* Time representation. */
+            PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%H:%M:%S", time );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'y':
+            /* year within century ( 00 - 99 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2d",time->tm_year % 100 );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'Y':
+            /* year as ccyy ( for example 1986 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.4d",time->tm_year );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'Z':
+            /* Time zone name or no characters if  no  time  zone exists.
+             * Since time zone name is supposed to be independant of locale, we
+             * defer to PR_FormatTime() for this option.
+             */
+            PR_FormatTime( tmpBuf, tmpBufSize, "%Z", time );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+
+         default:
+            /* Unknown format.  Simply copy format into output buffer. */
+            ADDCHAR( bufPtr, bufSize, '%' );
+            ADDCHAR( bufPtr, bufSize, *fmtPtr );
+            break;
+            
+         }
+      }
+   }
+
+   ADDCHAR( bufPtr, bufSize, '\0' );
+   return (PRUint32)(bufPtr - buf - 1);
+}
+
+
+
+/***********************************************************************************
+ *
+ * Description:
+ *  Returns the week number of the year (0-53) for the given time.  firstDayOfWeek
+ *  is the day on which the week is considered to start (0=Sun, 1=Mon, ...).
+ *  Week 1 starts the first time firstDayOfWeek occurs in the year.  In other words,
+ *  a partial week at the start of the year is considered week 0.  
+ *
+ **********************************************************************************/
+
+static unsigned int
+pr_WeekOfYear(const PRExplodedTime* time, unsigned int firstDayOfWeek)
+{
+   int dayOfWeek;
+   int dayOfYear;
+
+  /* Get the day of the year for the given time then adjust it to represent the
+   * first day of the week containing the given time.
+   */
+  dayOfWeek = time->tm_wday - firstDayOfWeek;
+  if (dayOfWeek < 0)
+    dayOfWeek += 7;
+  
+  dayOfYear = time->tm_yday - dayOfWeek;
+
+
+  if( dayOfYear <= 0 )
+  {
+     /* If dayOfYear is <= 0, it is in the first partial week of the year. */
+     return 0;
+  }
+  else
+  {
+     /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there
+      * are any days left over ( dayOfYear % 7 ).  Because we are only counting to
+      * the first day of the week containing the given time, rather than to the
+      * actual day representing the given time, any days in week 0 will be "absorbed"
+      * as extra days in the given week.
+      */
+     return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 );
+  }
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtpool.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtpool.c
new file mode 100644
index 0000000..e23bb9d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtpool.c
@@ -0,0 +1,1219 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+
+/*
+ * Thread pools
+ *	Thread pools create and manage threads to provide support for
+ *	scheduling jobs onto one or more threads.
+ *
+ */
+#ifdef OPT_WINNT
+#include <windows.h>
+#endif
+
+/*
+ * worker thread
+ */
+typedef struct wthread {
+	PRCList		links;
+	PRThread	*thread;
+} wthread;
+
+/*
+ * queue of timer jobs
+ */
+typedef struct timer_jobq {
+	PRCList		list;
+	PRLock		*lock;
+	PRCondVar	*cv;
+	PRInt32		cnt;
+	PRCList 	wthreads;
+} timer_jobq;
+
+/*
+ * queue of jobs
+ */
+typedef struct tp_jobq {
+	PRCList		list;
+	PRInt32		cnt;
+	PRLock		*lock;
+	PRCondVar	*cv;
+	PRCList 	wthreads;
+#ifdef OPT_WINNT
+	HANDLE		nt_completion_port;
+#endif
+} tp_jobq;
+
+/*
+ * queue of IO jobs
+ */
+typedef struct io_jobq {
+	PRCList		list;
+	PRPollDesc  *pollfds;
+	PRInt32  	npollfds;
+	PRJob		**polljobs;
+	PRLock		*lock;
+	PRInt32		cnt;
+	PRFileDesc	*notify_fd;
+	PRCList 	wthreads;
+} io_jobq;
+
+/*
+ * Threadpool
+ */
+struct PRThreadPool {
+	PRInt32		init_threads;
+	PRInt32		max_threads;
+	PRInt32		current_threads;
+	PRInt32		idle_threads;
+	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;
+
+#ifdef OPT_WINNT
+typedef struct NT_notifier {
+	OVERLAPPED overlapped;		/* must be first */
+	PRJob	*jobp;
+} NT_notifier;
+#endif
+
+struct PRJob {
+	PRCList			links;		/* 	for linking jobs */
+	PRBool			on_ioq;		/* job on ioq */
+	PRBool			on_timerq;	/* job on timerq */
+	PRJobFn			job_func;
+	void 			*job_arg;
+	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
+	NT_notifier		nt_notifier;	
+#endif
+};
+
+#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(void);
+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;
+
+	/*
+	 * execute jobs until shutdown
+	 */
+	while (!tp->shutdown) {
+		PRJob *jobp;
+#ifdef OPT_WINNT
+		BOOL rv;
+		DWORD unused, shutdown;
+		LPOVERLAPPED olp;
+
+		PR_Lock(tp->jobq.lock);
+		tp->idle_threads++;
+		PR_Unlock(tp->jobq.lock);
+		rv = GetQueuedCompletionStatus(tp->jobq.nt_completion_port,
+					&unused, &shutdown, &olp, INFINITE);
+		
+		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);
+#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--;
+		}	
+		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_Unlock(tp->jobq.lock);
+#endif
+
+		jobp->job_func(jobp->job_arg);
+		if (!JOINABLE_JOB(jobp)) {
+			delete_job(jobp);
+		} else {
+			JOIN_NOTIFY(jobp);
+		}
+	}
+	PR_Lock(tp->jobq.lock);
+	tp->current_threads--;
+	PR_Unlock(tp->jobq.lock);
+}
+
+/*
+ * add a job to the work queue
+ */
+static void
+add_to_jobq(PRThreadPool *tp, PRJob *jobp)
+{
+	/*
+	 * add to jobq
+	 */
+#ifdef OPT_WINNT
+	PR_Lock(tp->jobq.lock);
+	tp->jobq.cnt++;
+	PR_Unlock(tp->jobq.lock);
+	/*
+	 * 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);
+	tp->jobq.cnt++;
+	if ((tp->idle_threads < tp->jobq.cnt) &&
+					(tp->current_threads < tp->max_threads)) {
+		wthread *wthrp;
+		/*
+		 * increment thread count and unlock the jobq lock
+		 */
+		tp->current_threads++;
+		PR_Unlock(tp->jobq.lock);
+		/* create new worker thread */
+		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 == wthrp) {
+			tp->current_threads--;
+		} else {
+			PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads);
+		}
+	}
+	/*
+	 * wakeup a worker thread
+	 */
+	PR_NotifyCondVar(tp->jobq.cv);
+	PR_Unlock(tp->jobq.lock);
+#endif
+}
+
+/*
+ * io worker thread function
+ */
+static void io_wstart(void *arg)
+{
+PRThreadPool *tp = (PRThreadPool *) arg;
+int pollfd_cnt, pollfds_used;
+int rv;
+PRCList *qp, *nextqp;
+PRPollDesc *pollfds;
+PRJob **polljobs;
+int poll_timeout;
+PRIntervalTime now;
+
+	/*
+	 * scan io_jobq
+	 * construct poll list
+	 * call PR_Poll
+	 * for all fds, for which poll returns true, move the job to
+	 * jobq and wakeup worker thread.
+	 */
+	while (!tp->shutdown) {
+		PRJob *jobp;
+
+		pollfd_cnt = tp->ioq.cnt + 10;
+		if (pollfd_cnt > tp->ioq.npollfds) {
+
+			/*
+			 * re-allocate pollfd array if the current one is not large
+			 * enough
+			 */
+			if (NULL != tp->ioq.pollfds)
+				PR_Free(tp->ioq.pollfds);
+			tp->ioq.pollfds = (PRPollDesc *) PR_Malloc(pollfd_cnt *
+						(sizeof(PRPollDesc) + sizeof(PRJob *)));
+			PR_ASSERT(NULL != tp->ioq.pollfds);
+			/*
+			 * array of pollfds
+			 */
+			pollfds = tp->ioq.pollfds;
+			tp->ioq.polljobs = (PRJob **) (&tp->ioq.pollfds[pollfd_cnt]);
+			/*
+			 * parallel array of jobs
+			 */
+			polljobs = tp->ioq.polljobs;
+			tp->ioq.npollfds = pollfd_cnt;
+		}
+
+		pollfds_used = 0;
+		/*
+		 * add the notify fd; used for unblocking io thread(s)
+		 */
+		pollfds[pollfds_used].fd = tp->ioq.notify_fd;
+		pollfds[pollfds_used].in_flags = PR_POLL_READ;
+		pollfds[pollfds_used].out_flags = 0;
+		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 = nextqp) {
+			nextqp = 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++;
+		}
+		if (!PR_CLIST_IS_EMPTY(&tp->ioq.list)) {
+			qp = tp->ioq.list.next;
+			jobp = JOB_LINKS_PTR(qp);
+			if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout)
+				poll_timeout = PR_INTERVAL_NO_TIMEOUT;
+			else if (PR_INTERVAL_NO_WAIT == jobp->timeout)
+				poll_timeout = PR_INTERVAL_NO_WAIT;
+			else {
+				poll_timeout = jobp->absolute - PR_IntervalNow();
+				if (poll_timeout <= 0) /* already timed out */
+					poll_timeout = PR_INTERVAL_NO_WAIT;
+			}
+		} else {
+			poll_timeout = PR_INTERVAL_NO_TIMEOUT;
+		}
+		PR_Unlock(tp->ioq.lock);
+
+		/*
+		 * XXXX
+		 * should retry if more jobs have been added to the queue?
+		 *
+		 */
+		PR_ASSERT(pollfds_used <= pollfd_cnt);
+		rv = PR_Poll(tp->ioq.pollfds, pollfds_used, poll_timeout);
+
+		if (tp->shutdown) {
+			break;
+		}
+
+		if (rv > 0) {
+			/*
+			 * at least one io event is set
+			 */
+			PRStatus rval_status;
+			PRInt32 index;
+
+			PR_ASSERT(pollfds[0].fd == tp->ioq.notify_fd);
+			/*
+			 * reset the pollable event, if notified
+			 */
+			if (pollfds[0].out_flags & PR_POLL_READ) {
+				rval_status = PR_WaitForPollableEvent(tp->ioq.notify_fd);
+				PR_ASSERT(PR_SUCCESS == rval_status);
+			}
+
+			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) {
+					/*
+					 * 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);
+
+					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 = nextqp) {
+			nextqp = 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);
+	}
+}
+
+/*
+ * timer worker thread function
+ */
+static void timer_wstart(void *arg)
+{
+PRThreadPool *tp = (PRThreadPool *) arg;
+PRCList *qp;
+PRIntervalTime timeout;
+PRIntervalTime now;
+
+	/*
+	 * call PR_WaitCondVar with minimum value of all timeouts
+	 */
+	while (!tp->shutdown) {
+		PRJob *jobp;
+
+		PR_Lock(tp->timerq.lock);
+		if (PR_CLIST_IS_EMPTY(&tp->timerq.list)) {
+			timeout = PR_INTERVAL_NO_TIMEOUT;
+		} else {
+			PRCList *qp;
+
+			qp = tp->timerq.list.next;
+			jobp = JOB_LINKS_PTR(qp);
+
+			timeout = jobp->absolute - PR_IntervalNow();
+            if (timeout <= 0)
+				timeout = PR_INTERVAL_NO_WAIT;  /* already timed out */
+		}
+		if (PR_INTERVAL_NO_WAIT != timeout)
+			PR_WaitCondVar(tp->timerq.cv, timeout);
+		if (tp->shutdown) {
+			PR_Unlock(tp->timerq.lock);
+			break;
+		}
+		/*
+		 * move expired-timer jobs to jobq
+		 */
+		now = PR_IntervalNow();	
+		while (!PR_CLIST_IS_EMPTY(&tp->timerq.list)) {
+			qp = tp->timerq.list.next;
+			jobp = JOB_LINKS_PTR(qp);
+
+			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)
+			PR_DestroyLock(tp->timerq.lock);
+
+		if (NULL != tp->ioq.lock)
+			PR_DestroyLock(tp->ioq.lock);
+		if (NULL != tp->ioq.pollfds)
+			PR_Free(tp->ioq.pollfds);
+		if (NULL != tp->ioq.notify_fd)
+			PR_DestroyPollableEvent(tp->ioq.notify_fd);
+		PR_Free(tp);
+	}
+	return;
+}
+
+static PRThreadPool *
+alloc_threadpool(void)
+{
+PRThreadPool *tp;
+
+	tp = (PRThreadPool *) PR_CALLOC(sizeof(*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();
+	if (NULL == tp->ioq.lock)
+		goto failed;
+
+	/* Timer queue */
+
+	tp->timerq.lock = PR_NewLock();
+	if (NULL == tp->timerq.lock)
+		goto failed;
+	tp->timerq.cv = PR_NewCondVar(tp->timerq.lock);
+	if (NULL == tp->timerq.cv)
+		goto failed;
+
+	tp->shutdown_cv = PR_NewCondVar(tp->jobq.lock);
+	if (NULL == tp->shutdown_cv)
+		goto failed;
+	tp->ioq.notify_fd = PR_NewPollableEvent();
+	if (NULL == tp->ioq.notify_fd)
+		goto failed;
+	return tp;
+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,
+                                PRUint32 stacksize)
+{
+PRThreadPool *tp;
+PRThread *thr;
+int i;
+wthread *wthrp;
+
+	tp = alloc_threadpool();
+	if (NULL == tp)
+		return NULL;
+
+	tp->init_threads = initial_threads;
+	tp->max_threads = max_threads;
+	tp->stacksize = stacksize;
+	PR_INIT_CLIST(&tp->jobq.list);
+	PR_INIT_CLIST(&tp->ioq.list);
+	PR_INIT_CLIST(&tp->timerq.list);
+	PR_INIT_CLIST(&tp->jobq.wthreads);
+	PR_INIT_CLIST(&tp->ioq.wthreads);
+	PR_INIT_CLIST(&tp->timerq.wthreads);
+	tp->shutdown = PR_FALSE;
+
+	PR_Lock(tp->jobq.lock);
+	for(i=0; i < initial_threads; ++i) {
+
+		thr = PR_CreateThread(PR_USER_THREAD, wstart,
+						tp, PR_PRIORITY_NORMAL,
+						PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,stacksize);
+		PR_ASSERT(thr);
+		wthrp = PR_NEWZAP(wthread);
+		PR_ASSERT(wthrp);
+		wthrp->thread = thr;
+		PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads);
+	}
+	tp->current_threads = initial_threads;
+
+	thr = PR_CreateThread(PR_USER_THREAD, io_wstart,
+					tp, PR_PRIORITY_NORMAL,
+					PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize);
+	PR_ASSERT(thr);
+	wthrp = PR_NEWZAP(wthread);
+	PR_ASSERT(wthrp);
+	wthrp->thread = thr;
+	PR_APPEND_LINK(&wthrp->links, &tp->ioq.wthreads);
+
+	thr = PR_CreateThread(PR_USER_THREAD, timer_wstart,
+					tp, PR_PRIORITY_NORMAL,
+					PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize);
+	PR_ASSERT(thr);
+	wthrp = PR_NEWZAP(wthread);
+	PR_ASSERT(wthrp);
+	wthrp->thread = thr;
+	PR_APPEND_LINK(&wthrp->links, &tp->timerq.wthreads);
+
+	PR_Unlock(tp->jobq.lock);
+	return tp;
+}
+
+static void
+delete_job(PRJob *jobp)
+{
+	if (NULL != jobp) {
+		if (NULL != jobp->join_cv) {
+			PR_DestroyCondVar(jobp->join_cv);
+			jobp->join_cv = NULL;
+		}
+		if (NULL != jobp->cancel_cv) {
+			PR_DestroyCondVar(jobp->cancel_cv);
+			jobp->cancel_cv = NULL;
+		}
+		PR_DELETE(jobp);
+	}
+}
+
+static PRJob *
+alloc_job(PRBool joinable, PRThreadPool *tp)
+{
+	PRJob *jobp;
+
+	jobp = PR_NEWZAP(PRJob);
+	if (NULL == jobp) 
+		goto failed;
+	if (joinable) {
+		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
+	return jobp;
+failed:
+	delete_job(jobp);
+	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	return NULL;
+}
+
+/* queue a job */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable)
+{
+	PRJob *jobp;
+
+	jobp = alloc_job(joinable, tpool);
+	if (NULL == jobp)
+		return NULL;
+
+	jobp->job_func = fn;
+	jobp->job_arg = arg;
+	jobp->tpool = tpool;
+
+	add_to_jobq(tpool, jobp);
+	return jobp;
+}
+
+/* queue a job, when a socket is readable or writeable */
+static PRJob *
+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, 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->tpool = tpool;
+	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|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) ||
+			(PR_INTERVAL_NO_WAIT == iod->timeout)) {
+		jobp->absolute = iod->timeout;
+	} else {
+		now = PR_IntervalNow();
+		jobp->absolute = now + iod->timeout;
+	}
+
+
+	PR_Lock(tpool->ioq.lock);
+
+	if (PR_CLIST_IS_EMPTY(&tpool->ioq.list) ||
+			(PR_INTERVAL_NO_TIMEOUT == iod->timeout)) {
+		PR_APPEND_LINK(&jobp->links,&tpool->ioq.list);
+	} else if (PR_INTERVAL_NO_WAIT == iod->timeout) {
+		PR_INSERT_LINK(&jobp->links,&tpool->ioq.list);
+	} else {
+		PRCList *qp;
+		PRJob *tmp_jobp;
+		/*
+		 * insert into the timeout-sorted ioq
+		 */
+		for (qp = tpool->ioq.list.prev; qp != &tpool->ioq.list;
+							qp = qp->prev) {
+			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, 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, PRJobFn fn,void * arg,
+										PRBool joinable)
+{
+	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE));
+}
+
+
+/* queue a job, when a socket has a pending connection */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,
+								void * arg, PRBool joinable)
+{
+	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_ACCEPT));
+}
+
+/* queue a job, when a socket can be connected */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
+			const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable)
+{
+	PRStatus rv;
+	PRErrorCode err;
+
+	rv = PR_Connect(iod->socket, addr, PR_INTERVAL_NO_WAIT);
+	if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){
+		/* connection pending */
+		return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT));
+	} else {
+		/*
+		 * connection succeeded or failed; add to jobq right away
+		 */
+		if (rv == PR_FAILURE)
+			iod->error = err;
+		else
+			iod->error = 0;
+		return(PR_QueueJob(tpool, fn, arg, joinable));
+	}
+}
+
+/* queue a job, when a timer expires */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
+							PRJobFn fn, void * arg, PRBool joinable)
+{
+	PRIntervalTime now;
+	PRJob *jobp;
+
+	if (PR_INTERVAL_NO_TIMEOUT == timeout) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return NULL;
+	}
+	if (PR_INTERVAL_NO_WAIT == timeout) {
+		/*
+		 * no waiting; add to jobq right away
+		 */
+		return(PR_QueueJob(tpool, fn, arg, joinable));
+	}
+	jobp = alloc_job(joinable, tpool);
+	if (NULL == jobp) {
+		return NULL;
+	}
+
+	/*
+	 * Add a new job to timer_jobq
+	 * wakeup timer worker thread
+	 */
+
+	jobp->job_func = fn;
+	jobp->job_arg = arg;
+	jobp->tpool = tpool;
+	jobp->timeout = timeout;
+
+	now = PR_IntervalNow();
+	jobp->absolute = now + timeout;
+
+
+	PR_Lock(tpool->timerq.lock);
+	jobp->on_timerq = PR_TRUE;
+	if (PR_CLIST_IS_EMPTY(&tpool->timerq.list))
+		PR_APPEND_LINK(&jobp->links,&tpool->timerq.list);
+	else {
+		PRCList *qp;
+		PRJob *tmp_jobp;
+		/*
+		 * insert into the sorted timer jobq
+		 */
+		for (qp = tpool->timerq.list.prev; qp != &tpool->timerq.list;
+							qp = qp->prev) {
+			tmp_jobp = JOB_LINKS_PTR(qp);
+			if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) {
+				break;
+			}
+		}
+		PR_INSERT_AFTER(&jobp->links,qp);
+	}
+	tpool->timerq.cnt++;
+	/*
+	 * notify timer worker thread(s)
+	 */
+	notify_timerq(tpool);
+	PR_Unlock(tpool->timerq.lock);
+	return jobp;
+}
+
+static void
+notify_timerq(PRThreadPool *tp)
+{
+	/*
+	 * wakeup the timer thread(s)
+	 */
+	PR_NotifyCondVar(tp->timerq.cv);
+}
+
+static void
+notify_ioq(PRThreadPool *tp)
+{
+PRStatus rval_status;
+
+	/*
+	 * wakeup the io thread(s)
+	 */
+	rval_status = PR_SetPollableEvent(tp->ioq.notify_fd);
+	PR_ASSERT(PR_SUCCESS == rval_status);
+}
+
+/*
+ * cancel a job
+ *
+ *	XXXX: is this needed? likely to be removed
+ */
+PR_IMPLEMENT(PRStatus)
+PR_CancelJob(PRJob *jobp) {
+
+	PRStatus rval = PR_FAILURE;
+	PRThreadPool *tp;
+
+	if (jobp->on_timerq) {
+		/*
+		 * now, check again while holding the timerq lock
+		 */
+		tp = jobp->tpool;
+		PR_Lock(tp->timerq.lock);
+		if (jobp->on_timerq) {
+			jobp->on_timerq = PR_FALSE;
+			PR_REMOVE_AND_INIT_LINK(&jobp->links);
+			tp->timerq.cnt--;
+			PR_Unlock(tp->timerq.lock);
+			if (!JOINABLE_JOB(jobp)) {
+				delete_job(jobp);
+			} else {
+				JOIN_NOTIFY(jobp);
+			}
+			rval = PR_SUCCESS;
+		} else
+			PR_Unlock(tp->timerq.lock);
+	} else if (jobp->on_ioq) {
+		/*
+		 * now, check again while holding the ioq lock
+		 */
+		tp = jobp->tpool;
+		PR_Lock(tp->ioq.lock);
+		if (jobp->on_ioq) {
+			jobp->cancel_cv = PR_NewCondVar(tp->ioq.lock);
+			if (NULL == jobp->cancel_cv) {
+				PR_Unlock(tp->ioq.lock);
+				PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+				return PR_FAILURE;
+			}
+			/*
+			 * mark job 'cancelled' and notify io thread(s)
+			 * XXXX:
+			 *		this assumes there is only one io thread; when there
+			 * 		are multiple threads, the io thread processing this job
+			 * 		must be notified.
+			 */
+			jobp->cancel_io = PR_TRUE;
+			PR_Unlock(tp->ioq.lock);	/* release, reacquire ioq lock */
+			notify_ioq(tp);
+			PR_Lock(tp->ioq.lock);
+			while (jobp->cancel_io)
+				PR_WaitCondVar(jobp->cancel_cv, PR_INTERVAL_NO_TIMEOUT);
+			PR_Unlock(tp->ioq.lock);
+			PR_ASSERT(!jobp->on_ioq);
+			if (!JOINABLE_JOB(jobp)) {
+				delete_job(jobp);
+			} else {
+				JOIN_NOTIFY(jobp);
+			}
+			rval = PR_SUCCESS;
+		} else
+			PR_Unlock(tp->ioq.lock);
+	}
+	if (PR_FAILURE == rval)
+		PR_SetError(PR_INVALID_STATE_ERROR, 0);
+	return rval;
+}
+
+/* join a job, wait until completion */
+PR_IMPLEMENT(PRStatus)
+PR_JoinJob(PRJob *jobp)
+{
+	if (!JOINABLE_JOB(jobp)) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return PR_FAILURE;
+	}
+	PR_Lock(jobp->tpool->join_lock);
+	while(jobp->join_wait)
+		PR_WaitCondVar(jobp->join_cv, PR_INTERVAL_NO_TIMEOUT);
+	PR_Unlock(jobp->tpool->join_lock);
+	delete_job(jobp);
+	return PR_SUCCESS;
+}
+
+/* shutdown threadpool */
+PR_IMPLEMENT(PRStatus)
+PR_ShutdownThreadPool(PRThreadPool *tpool)
+{
+PRStatus rval = PR_SUCCESS;
+
+	PR_Lock(tpool->jobq.lock);
+	tpool->shutdown = PR_TRUE;
+	PR_NotifyAllCondVar(tpool->shutdown_cv);
+	PR_Unlock(tpool->jobq.lock);
+
+	return rval;
+}
+
+/*
+ * join thread pool
+ * 	wait for termination of worker threads
+ *	reclaim threadpool resources
+ */
+PR_IMPLEMENT(PRStatus)
+PR_JoinThreadPool(PRThreadPool *tpool)
+{
+PRStatus rval = PR_SUCCESS;
+PRCList *head;
+PRStatus rval_status;
+
+	PR_Lock(tpool->jobq.lock);
+	while (!tpool->shutdown)
+		PR_WaitCondVar(tpool->shutdown_cv, PR_INTERVAL_NO_TIMEOUT);
+
+	/*
+	 * wakeup worker threads
+	 */
+#ifdef OPT_WINNT
+	/*
+	 * post shutdown notification for all threads
+	 */
+	{
+		int i;
+		for(i=0; i < tpool->current_threads; i++) {
+			PostQueuedCompletionStatus(tpool->jobq.nt_completion_port, 0,
+												TRUE, NULL);
+		}
+	}
+#else
+	PR_NotifyAllCondVar(tpool->jobq.cv);
+#endif
+
+	/*
+	 * wakeup io thread(s)
+	 */
+	notify_ioq(tpool);
+
+	/*
+	 * wakeup timer thread(s)
+	 */
+	PR_Lock(tpool->timerq.lock);
+	notify_timerq(tpool);
+	PR_Unlock(tpool->timerq.lock);
+
+	while (!PR_CLIST_IS_EMPTY(&tpool->jobq.wthreads)) {
+		wthread *wthrp;
+
+		head = PR_LIST_HEAD(&tpool->jobq.wthreads);
+		PR_REMOVE_AND_INIT_LINK(head);
+		PR_Unlock(tpool->jobq.lock);
+		wthrp = WTHREAD_LINKS_PTR(head);
+		rval_status = PR_JoinThread(wthrp->thread);
+		PR_ASSERT(PR_SUCCESS == rval_status);
+		PR_DELETE(wthrp);
+		PR_Lock(tpool->jobq.lock);
+	}
+	PR_Unlock(tpool->jobq.lock);
+	while (!PR_CLIST_IS_EMPTY(&tpool->ioq.wthreads)) {
+		wthread *wthrp;
+
+		head = PR_LIST_HEAD(&tpool->ioq.wthreads);
+		PR_REMOVE_AND_INIT_LINK(head);
+		wthrp = WTHREAD_LINKS_PTR(head);
+		rval_status = PR_JoinThread(wthrp->thread);
+		PR_ASSERT(PR_SUCCESS == rval_status);
+		PR_DELETE(wthrp);
+	}
+
+	while (!PR_CLIST_IS_EMPTY(&tpool->timerq.wthreads)) {
+		wthread *wthrp;
+
+		head = PR_LIST_HEAD(&tpool->timerq.wthreads);
+		PR_REMOVE_AND_INIT_LINK(head);
+		wthrp = WTHREAD_LINKS_PTR(head);
+		rval_status = PR_JoinThread(wthrp->thread);
+		PR_ASSERT(PR_SUCCESS == rval_status);
+		PR_DELETE(wthrp);
+	}
+
+	/*
+	 * Delete queued jobs
+	 */
+	while (!PR_CLIST_IS_EMPTY(&tpool->jobq.list)) {
+		PRJob *jobp;
+
+		head = PR_LIST_HEAD(&tpool->jobq.list);
+		PR_REMOVE_AND_INIT_LINK(head);
+		jobp = JOB_LINKS_PTR(head);
+		tpool->jobq.cnt--;
+		delete_job(jobp);
+	}
+
+	/* delete io jobs */
+	while (!PR_CLIST_IS_EMPTY(&tpool->ioq.list)) {
+		PRJob *jobp;
+
+		head = PR_LIST_HEAD(&tpool->ioq.list);
+		PR_REMOVE_AND_INIT_LINK(head);
+		tpool->ioq.cnt--;
+		jobp = JOB_LINKS_PTR(head);
+		delete_job(jobp);
+	}
+
+	/* delete timer jobs */
+	while (!PR_CLIST_IS_EMPTY(&tpool->timerq.list)) {
+		PRJob *jobp;
+
+		head = PR_LIST_HEAD(&tpool->timerq.list);
+		PR_REMOVE_AND_INIT_LINK(head);
+		tpool->timerq.cnt--;
+		jobp = JOB_LINKS_PTR(head);
+		delete_job(jobp);
+	}
+
+	PR_ASSERT(0 == tpool->jobq.cnt);
+	PR_ASSERT(0 == tpool->ioq.cnt);
+	PR_ASSERT(0 == tpool->timerq.cnt);
+
+	delete_threadpool(tpool);
+	return rval;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtrace.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtrace.c
new file mode 100644
index 0000000..762dd82
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtrace.c
@@ -0,0 +1,920 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** prtrace.c -- NSPR Trace Instrumentation
+**
+** Implement the API defined in prtrace.h
+**
+**
+**
+*/
+
+#include <string.h>
+#include "primpl.h"
+
+
+#define DEFAULT_TRACE_BUFSIZE ( 1024 * 1024 )
+#define DEFAULT_BUFFER_SEGMENTS    2
+
+/*
+** Enumerate states in a RName structure
+*/
+typedef enum TraceState
+{
+    Running = 1,
+    Suspended = 2
+} TraceState;
+
+/*
+** Define QName structure
+*/
+typedef struct QName
+{
+    PRCList link;
+    PRCList rNameList;
+    char    name[PRTRACE_NAME_MAX+1];
+} QName;
+
+/*
+** Define RName structure
+*/
+typedef struct RName
+{
+    PRCList link;
+    PRLock  *lock;
+    QName   *qName;
+    TraceState state;
+    char    name[PRTRACE_NAME_MAX+1];
+    char    desc[PRTRACE_DESC_MAX+1];
+} RName;
+
+
+/*
+** The Trace Facility database
+**
+*/
+static PRLogModuleInfo *lm;
+
+static PRLock      *traceLock;      /* Facility Lock */
+static PRCList     qNameList;       /* anchor to all QName structures */
+static TraceState traceState = Running;
+
+/*
+** in-memory trace buffer controls
+*/
+static  PRTraceEntry    *tBuf;      /* pointer to buffer */
+static  PRInt32         bufSize;    /* size of buffer, in bytes, rounded up to sizeof(PRTraceEntry) */
+static  volatile PRInt32  next;     /* index to next PRTraceEntry */
+static  PRInt32         last;       /* index of highest numbered trace entry */
+
+/*
+** Real-time buffer capture controls
+*/
+static PRInt32 fetchLastSeen = 0;
+static PRBool  fetchLostData = PR_FALSE;
+
+/*
+** Buffer write-to-file controls
+*/
+static  PRLock      *logLock;               /* Sync lock */
+static  PRCondVar   *logCVar;               /* Sync Condidtion Variable */
+/*
+** Inter-thread state communication.
+** Controling thread writes to logOrder under protection of logCVar
+** the logging thread reads logOrder and sets logState on Notify.
+** 
+** logSegments, logCount, logLostData must be read and written under
+** protection of logLock, logCVar.
+** 
+*/
+static  enum LogState
+{
+    LogNotRunning,  /* Initial state */
+    LogReset,       /* Causes logger to re-calc controls */
+    LogActive,      /* Logging in progress, set only by log thread */
+    LogSuspend,     /* Suspend Logging */ 
+    LogResume,      /* Resume Logging => LogActive */ 
+    LogStop         /* Stop the log thread */
+}   logOrder, logState, localState;         /* controlling state variables */
+static  PRInt32     logSegments;            /* Number of buffer segments */
+static  PRInt32     logEntries;             /* number of Trace Entries in the buffer */
+static  PRInt32     logEntriesPerSegment;   /* number of PRTraceEntries per buffer segment */
+static  PRInt32     logSegSize;             /* size of buffer segment */
+static  PRInt32     logCount;               /* number of segments pending output */
+static  PRInt32     logLostData;            /* number of lost log buffer segments */
+
+/*
+** end Trace Database
+**
+*/
+
+/*
+** _PR_InitializeTrace() -- Initialize the trace facility
+*/
+static void NewTraceBuffer( PRInt32 size )
+{
+    /*
+    ** calculate the size of the buffer
+    ** round down so that each segment has the same number of
+    ** trace entries
+    */
+    logSegments = DEFAULT_BUFFER_SEGMENTS;
+    logEntries = size / sizeof(PRTraceEntry);
+    logEntriesPerSegment = logEntries / logSegments;
+    logEntries = logSegments * logEntriesPerSegment;
+    bufSize = logEntries * sizeof(PRTraceEntry);
+    logSegSize = logEntriesPerSegment * sizeof(PRTraceEntry);
+    PR_ASSERT( bufSize != 0);
+    PR_LOG( lm, PR_LOG_ERROR,
+        ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegment: %ld, logSegSize: %ld",
+            logSegments, logEntries, logEntriesPerSegment, logSegSize ));
+
+
+    tBuf = PR_Malloc( bufSize );
+    if ( tBuf == NULL )
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("PRTrace: Failed to get trace buffer"));
+        PR_ASSERT( 0 );
+    } 
+    else
+    {
+        PR_LOG( lm, PR_LOG_NOTICE,
+            ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf));
+    }
+
+    next = 0;
+    last = logEntries -1;
+    logCount = 0;
+    logLostData = PR_TRUE; /* not really on first call */
+    logOrder = LogReset;
+
+} /* end NewTraceBuffer() */
+
+/*
+** _PR_InitializeTrace() -- Initialize the trace facility
+*/
+static void _PR_InitializeTrace( void )
+{
+    /* The lock pointer better be null on this call */
+    PR_ASSERT( traceLock == NULL );
+
+    traceLock = PR_NewLock();
+    PR_ASSERT( traceLock != NULL );
+
+    PR_Lock( traceLock );
+    
+    PR_INIT_CLIST( &qNameList );
+
+    lm = PR_NewLogModule("trace");
+
+    bufSize = DEFAULT_TRACE_BUFSIZE;
+    NewTraceBuffer( bufSize );
+
+    /* Initialize logging controls */
+    logLock = PR_NewLock();
+    logCVar = PR_NewCondVar( logLock );
+
+    PR_Unlock( traceLock );
+    return;    
+} /* end _PR_InitializeTrace() */
+
+/*
+** Create a Trace Handle
+*/
+PR_IMPLEMENT(PRTraceHandle)
+	PR_CreateTrace( 
+    	const char *qName,          /* QName for this trace handle */
+	    const char *rName,          /* RName for this trace handle */
+	    const char *description     /* description for this trace handle */
+)
+{
+    QName   *qnp;
+    RName   *rnp;
+    PRBool  matchQname = PR_FALSE;
+
+    /* Self initialize, if necessary */
+    if ( traceLock == NULL )
+        _PR_InitializeTrace();
+
+    /* Validate input arguments */
+    PR_ASSERT( strlen(qName) <= PRTRACE_NAME_MAX );
+    PR_ASSERT( strlen(rName) <= PRTRACE_NAME_MAX );
+    PR_ASSERT( strlen(description) <= PRTRACE_DESC_MAX );
+
+    PR_LOG( lm, PR_LOG_DEBUG,
+            ("PRTRACE: CreateTrace: Qname: %s, RName: %s", qName, rName));
+
+    /* Lock the Facility */
+    PR_Lock( traceLock );
+
+    /* Do we already have a matching QName? */
+    if (!PR_CLIST_IS_EMPTY( &qNameList ))
+    {
+        qnp = (QName *) PR_LIST_HEAD( &qNameList );
+        do {
+            if ( strcmp(qnp->name, qName) == 0)
+            {
+                matchQname = PR_TRUE;
+                break;
+            }
+            qnp = (QName *)PR_NEXT_LINK( &qnp->link );
+        } while( qnp != (QName *)PR_LIST_HEAD( &qNameList ));
+    }
+    /*
+    ** If we did not find a matching QName,
+    **    allocate one and initialize it.
+    **    link it onto the qNameList.
+    **
+    */
+    if ( matchQname != PR_TRUE )
+    {
+        qnp = PR_NEWZAP( QName );
+        PR_ASSERT( qnp != NULL );
+        PR_INIT_CLIST( &qnp->link ); 
+        PR_INIT_CLIST( &qnp->rNameList ); 
+        strcpy( qnp->name, qName );
+        PR_APPEND_LINK( &qnp->link, &qNameList ); 
+    }
+
+    /* Do we already have a matching RName? */
+    if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
+    {
+        rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
+        do {
+            /*
+            ** No duplicate RNames are allowed within a QName
+            **
+            */
+            PR_ASSERT( strcmp(rnp->name, rName));
+            rnp = (RName *)PR_NEXT_LINK( &rnp->link );
+        } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList ));
+    }
+
+    /* Get a new RName structure; initialize its members */
+    rnp = PR_NEWZAP( RName );
+    PR_ASSERT( rnp != NULL );
+    PR_INIT_CLIST( &rnp->link );
+    strcpy( rnp->name, rName );
+    strcpy( rnp->desc, description );
+    rnp->lock = PR_NewLock();
+    rnp->state = Running;
+    if ( rnp->lock == NULL )
+    {
+        PR_ASSERT(0);
+    }
+
+    PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */    
+    rnp->qName = qnp;                       /* point the RName to the QName */
+
+    /* Unlock the Facility */
+    PR_Unlock( traceLock );
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Create: QName: %s %p, RName: %s %p\n\t",
+        qName, qnp, rName, rnp ));
+
+    return((PRTraceHandle)rnp);
+} /* end  PR_CreateTrace() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_DestroyTrace( 
+		PRTraceHandle handle    /* Handle to be destroyed */
+)
+{
+    RName   *rnp = (RName *)handle;
+    QName   *qnp = rnp->qName;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s", 
+        qnp->name, rnp->name));
+
+    /* Lock the Facility */
+    PR_Lock( traceLock );
+
+    /*
+    ** Remove RName from the list of RNames in QName
+    ** and free RName
+    */
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p", 
+        rnp->name, rnp));
+    PR_REMOVE_LINK( &rnp->link );
+    PR_Free( rnp->lock );
+    PR_DELETE( rnp );
+
+    /*
+    ** If this is the last RName within QName
+    **   remove QName from the qNameList and free it
+    */
+    if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
+    {
+        PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p", 
+            qnp->name, qnp));
+        PR_REMOVE_LINK( &qnp->link );
+        PR_DELETE( qnp );
+    } 
+
+    /* Unlock the Facility */
+    PR_Unlock( traceLock );
+    return;
+} /* end PR_DestroyTrace()  */
+
+/*
+** Create a TraceEntry in the trace buffer
+*/
+PR_IMPLEMENT(void) 
+	PR_Trace( 
+    	PRTraceHandle handle,       /* use this trace handle */
+	    PRUint32    userData0,      /* User supplied data word 0 */
+	    PRUint32    userData1,      /* User supplied data word 1 */
+	    PRUint32    userData2,      /* User supplied data word 2 */
+	    PRUint32    userData3,      /* User supplied data word 3 */
+	    PRUint32    userData4,      /* User supplied data word 4 */
+	    PRUint32    userData5,      /* User supplied data word 5 */
+	    PRUint32    userData6,      /* User supplied data word 6 */
+	    PRUint32    userData7       /* User supplied data word 7 */
+)
+{
+    PRTraceEntry   *tep;
+    PRInt32         mark;
+
+    if ( (traceState == Suspended ) 
+        || ( ((RName *)handle)->state == Suspended )) 
+        return;
+
+    /*
+    ** Get the next trace entry slot w/ minimum delay
+    */
+    PR_Lock( traceLock );
+
+    tep = &tBuf[next++]; 
+    if ( next > last )
+        next = 0;
+    if ( fetchLostData == PR_FALSE && next == fetchLastSeen )
+        fetchLostData = PR_TRUE;
+    
+    mark = next;
+        
+    PR_Unlock( traceLock );
+
+    /*
+    ** We have a trace entry. Fill it in.
+    */
+    tep->thread = PR_GetCurrentThread();
+    tep->handle = handle;
+    tep->time   = PR_Now();
+    tep->userData[0] = userData0;
+    tep->userData[1] = userData1;
+    tep->userData[2] = userData2;
+    tep->userData[3] = userData3;
+    tep->userData[4] = userData4;
+    tep->userData[5] = userData5;
+    tep->userData[6] = userData6;
+    tep->userData[7] = userData7;
+
+    /* When buffer segment is full, signal trace log thread to run */
+    if (( mark % logEntriesPerSegment) == 0 )
+    {
+        PR_Lock( logLock );
+        logCount++;
+        PR_NotifyCondVar( logCVar );
+        PR_Unlock( logLock );
+        /*
+        ** Gh0D! This is awful!
+        ** Anyway, to minimize lost trace data segments,
+        ** I inserted the PR_Sleep(0) to cause a context switch
+        ** so that the log thread could run.
+        ** I know, it perturbs the universe and may cause
+        ** funny things to happen in the optimized builds.
+        ** Take it out, lose data; leave it in risk Heisenberg.
+        */
+        /* PR_Sleep(0); */
+    }
+
+    return;
+} /* end PR_Trace() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_SetTraceOption( 
+	    PRTraceOption command,  /* One of the enumerated values */
+	    void *value             /* command value or NULL */
+)
+{
+    RName * rnp;
+
+    switch ( command )
+    {
+        case PRTraceBufSize :
+            PR_Lock( traceLock );
+            PR_Free( tBuf );
+            bufSize = *(PRInt32 *)value;
+            NewTraceBuffer( bufSize );
+            PR_Unlock( traceLock );
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize));
+            break;
+        
+        case PRTraceEnable :
+            rnp = *(RName **)value;
+            rnp->state = Running;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceEnable: %p", rnp));
+            break;
+        
+        case PRTraceDisable :
+            rnp = *(RName **)value;
+            rnp->state = Suspended;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceDisable: %p", rnp));
+            break;
+        
+        case PRTraceSuspend :
+            traceState = Suspended;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceSuspend"));
+            break;
+        
+        case PRTraceResume :
+            traceState = Running;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceResume"));
+            break;
+        
+        case PRTraceSuspendRecording :
+            PR_Lock( logLock );
+            logOrder = LogSuspend;
+            PR_NotifyCondVar( logCVar );
+            PR_Unlock( logLock );
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceSuspendRecording"));
+            break;
+        
+        case PRTraceResumeRecording :
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceResumeRecording"));
+            if ( logState != LogSuspend )
+                break;
+            PR_Lock( logLock );
+            logOrder = LogResume;
+            PR_NotifyCondVar( logCVar );
+            PR_Unlock( logLock );
+            break;
+        
+        case PRTraceStopRecording :
+            PR_Lock( logLock );
+            logOrder = LogStop;
+            PR_NotifyCondVar( logCVar );
+            PR_Unlock( logLock );
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceStopRecording"));
+            break;
+
+        case PRTraceLockHandles :
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceLockTraceHandles"));
+            PR_Lock( traceLock );
+            break;
+        
+        case PRTraceUnLockHandles :
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceUnLockHandles"));
+            PR_Unlock( traceLock );
+            break;
+
+        default:
+            PR_LOG( lm, PR_LOG_ERROR,
+                ("PRSetTraceOption: Invalid command %ld", command ));
+            PR_ASSERT( 0 );
+            break;
+    } /* end switch() */
+    return;
+} /* end  PR_SetTraceOption() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_GetTraceOption( 
+    	PRTraceOption command,  /* One of the enumerated values */
+	    void *value             /* command value or NULL */
+)
+{
+    switch ( command )
+    {
+        case PRTraceBufSize :
+            *((PRInt32 *)value) = bufSize;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize ));
+            break;
+        
+        default:
+            PR_LOG( lm, PR_LOG_ERROR,
+                ("PRGetTraceOption: Invalid command %ld", command ));
+            PR_ASSERT( 0 );
+            break;
+    } /* end switch() */
+    return;
+} /* end PR_GetTraceOption() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRTraceHandle) 
+	PR_GetTraceHandleFromName( 
+    	const char *qName,      /* QName search argument */
+        const char *rName       /* RName search argument */
+)
+{
+    const char    *qn, *rn, *desc;
+    PRTraceHandle     qh, rh = NULL;
+    RName   *rnp = NULL;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetTraceHandleFromName:\n\t"
+        "QName: %s, RName: %s", qName, rName ));
+
+    qh = PR_FindNextTraceQname( NULL );
+    while (qh != NULL)
+    {
+        rh = PR_FindNextTraceRname( NULL, qh );
+        while ( rh != NULL )
+        {
+            PR_GetTraceNameFromHandle( rh, &qn, &rn, &desc );
+            if ( (strcmp( qName, qn ) == 0)
+                && (strcmp( rName, rn ) == 0 ))
+            {
+                rnp = (RName *)rh;
+                goto foundIt;
+            }
+            rh = PR_FindNextTraceRname( rh, qh );
+        }
+        qh = PR_FindNextTraceQname( NULL );
+    }
+
+foundIt:
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp ));
+    return(rh);
+} /* end PR_GetTraceHandleFromName() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_GetTraceNameFromHandle( 
+    	PRTraceHandle handle,       /* handle as search argument */
+	    const char **qName,         /* pointer to associated QName */
+	    const char **rName,         /* pointer to associated RName */
+    	const char **description    /* pointer to associated description */
+)
+{
+    RName   *rnp = (RName *)handle;
+    QName   *qnp = rnp->qName;
+
+    *qName = qnp->name;
+    *rName = rnp->name;
+    *description = rnp->desc;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetConterNameFromHandle: "
+        "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", 
+        qnp, rnp, qnp->name, rnp->name, rnp->desc ));
+
+    return;
+} /* end PR_GetTraceNameFromHandle() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRTraceHandle) 
+	PR_FindNextTraceQname( 
+        PRTraceHandle handle
+)
+{
+    QName *qnp = (QName *)handle;
+
+    if ( PR_CLIST_IS_EMPTY( &qNameList ))
+            qnp = NULL;
+    else if ( qnp == NULL )
+        qnp = (QName *)PR_LIST_HEAD( &qNameList );
+    else if ( PR_NEXT_LINK( &qnp->link ) ==  &qNameList )
+        qnp = NULL;
+    else  
+        qnp = (QName *)PR_NEXT_LINK( &qnp->link );
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p", 
+        handle, qnp ));
+
+    return((PRTraceHandle)qnp);
+} /* end PR_FindNextTraceQname() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRTraceHandle) 
+	PR_FindNextTraceRname( 
+        PRTraceHandle rhandle,
+        PRTraceHandle qhandle
+)
+{
+    RName *rnp = (RName *)rhandle;
+    QName *qnp = (QName *)qhandle;
+
+
+    if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
+        rnp = NULL;
+    else if ( rnp == NULL )
+        rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
+    else if ( PR_NEXT_LINK( &rnp->link ) ==  &qnp->rNameList )
+        rnp = NULL;
+    else
+        rnp = (RName *)PR_NEXT_LINK( &rnp->link );
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", 
+        rhandle, qhandle, rnp ));
+
+    return((PRTraceHandle)rnp);
+} /* end PR_FindNextTraceRname() */
+    
+/*
+**
+*/
+static PRFileDesc * InitializeRecording( void )
+{
+    char    *logFileName;
+    PRFileDesc  *logFile;
+
+    /* Self initialize, if necessary */
+    if ( traceLock == NULL )
+        _PR_InitializeTrace();
+
+    PR_LOG( lm, PR_LOG_DEBUG,
+        ("PR_RecordTraceEntries: begins"));
+
+    logLostData = 0; /* reset at entry */
+    logState = LogReset;
+
+#ifdef XP_UNIX
+    if ((getuid() != geteuid()) || (getgid() != getegid())) {
+        return NULL;
+    }
+#endif /* XP_UNIX */
+
+    /* Get the filename for the logfile from the environment */
+    logFileName = PR_GetEnv( "NSPR_TRACE_LOG" );
+    if ( logFileName == NULL )
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: Environment variable not defined. Exiting"));
+        return NULL;
+    }
+    
+    /* Open the logfile */
+    logFile = PR_Open( logFileName, PR_WRONLY | PR_CREATE_FILE, 0666 );
+    if ( logFile == NULL )
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %ld", 
+		logFileName, PR_GetOSError()));
+        return NULL;
+    }
+    return logFile;
+} /* end InitializeRecording() */
+
+/*
+**
+*/
+static void ProcessOrders( void )
+{
+    switch ( logOrder )
+    {
+    case LogReset :
+        logOrder = logState = localState;
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: LogReset"));
+        break;
+
+    case LogSuspend :
+        localState = logOrder = logState = LogSuspend;
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: LogSuspend"));
+        break;
+
+    case LogResume :
+        localState = logOrder = logState = LogActive;
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: LogResume"));
+        break;
+
+    case LogStop :
+        logOrder = logState = LogStop;
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: LogStop"));
+        break;
+
+    default :
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: Invalid logOrder: %ld", logOrder ));
+        PR_ASSERT( 0 );
+        break;
+    } /* end switch() */
+    return ;
+} /* end ProcessOrders() */
+
+/*
+**
+*/
+static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount )
+{
+    PRInt32 rc;
+
+
+    PR_LOG( lm, PR_LOG_ERROR,
+        ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount));
+    rc = PR_Write( logFile, buf , amount );
+    if ( rc == -1 )
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() ));
+    else if ( rc != amount )
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", amount, rc));
+    else 
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amount));
+
+    return;
+} /* end WriteTraceSegment() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void)
+	PR_RecordTraceEntries(
+        void 
+)
+{
+    PRFileDesc  *logFile;
+    PRInt32     lostSegments;
+    PRInt32     currentSegment = 0;
+    void        *buf;
+    PRBool      doWrite;
+
+    logFile = InitializeRecording();
+    if ( logFile == NULL )
+    {
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("PR_RecordTraceEntries: Failed to initialize"));
+        return;
+    }
+
+    /* Do this until told to stop */
+    while ( logState != LogStop )
+    {
+
+        PR_Lock( logLock );
+
+        while ( (logCount == 0) && ( logOrder == logState ) )
+            PR_WaitCondVar( logCVar, PR_INTERVAL_NO_TIMEOUT );
+
+        /* Handle state transitions */
+        if ( logOrder != logState )
+            ProcessOrders();
+
+        /* recalculate local controls */
+        if ( logCount )
+        {
+            lostSegments = logCount - logSegments;
+            if ( lostSegments > 0 )
+            {
+                logLostData += ( logCount - logSegments );
+                logCount = (logCount % logSegments);
+                currentSegment = logCount;
+                PR_LOG( lm, PR_LOG_DEBUG,
+                    ("PR_RecordTraceEntries: LostData segments: %ld", logLostData));
+            }
+            else
+            {
+                logCount--;
+            }
+
+            buf = tBuf + ( logEntriesPerSegment * currentSegment );
+            if (++currentSegment >= logSegments )
+                currentSegment = 0;
+            doWrite = PR_TRUE;
+        }
+        else
+            doWrite = PR_FALSE;
+
+        PR_Unlock( logLock );
+
+        if ( doWrite == PR_TRUE )
+        {
+            if ( localState != LogSuspend )
+                WriteTraceSegment( logFile, buf, logSegSize );
+            else
+                PR_LOG( lm, PR_LOG_DEBUG,
+                    ("RecordTraceEntries: PR_Write(): is suspended" ));
+        }
+
+    } /* end while(logState...) */
+
+    PR_Close( logFile );
+    PR_LOG( lm, PR_LOG_DEBUG,
+        ("RecordTraceEntries: exiting"));
+    return;
+} /* end  PR_RecordTraceEntries() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRIntn)
+    PR_GetTraceEntries(
+        PRTraceEntry    *buffer,    /* where to write output */
+        PRInt32         count,      /* number to get */
+        PRInt32         *found      /* number you got */
+)
+{
+    PRInt32 rc; 
+    PRInt32 copied = 0;
+    
+    PR_Lock( traceLock );
+    
+    /*
+    ** Depending on where the LastSeen and Next indices are,
+    ** copy the trace buffer in one or two pieces. 
+    */
+    PR_LOG( lm, PR_LOG_ERROR,
+        ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen));
+
+    if ( fetchLastSeen <= next )
+    {
+        while (( count-- > 0 ) && (fetchLastSeen < next ))
+        {
+            *(buffer + copied++) = *(tBuf + fetchLastSeen++);
+        }
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
+    }
+    else /* copy in 2 parts */
+    {
+        while ( count-- > 0  && fetchLastSeen <= last )
+        {
+            *(buffer + copied++) = *(tBuf + fetchLastSeen++);
+        }
+        fetchLastSeen = 0;
+
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
+
+        while ( count-- > 0  && fetchLastSeen < next )
+        {
+            *(buffer + copied++) = *(tBuf + fetchLastSeen++);
+        }
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
+    }
+
+    *found = copied;
+    rc = ( fetchLostData == PR_TRUE )? 1 : 0;
+    fetchLostData = PR_FALSE;
+
+    PR_Unlock( traceLock );
+    return rc;
+} /* end PR_GetTraceEntries() */
+
+/* end prtrace.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/nspr.def b/nspr-4.8.6/mozilla/nsprpub/pr/src/nspr.def
new file mode 100644
index 0000000..14ffaef
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/nspr.def
@@ -0,0 +1,476 @@
+;+#
+;+# ***** BEGIN LICENSE BLOCK *****
+;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+;+#
+;+# The contents of this file are subject to the Mozilla Public License Version
+;+# 1.1 (the "License"); you may not use this file except in compliance with
+;+# the License. You may obtain a copy of the License at
+;+# http://www.mozilla.org/MPL/
+;+#
+;+# Software distributed under the License is distributed on an "AS IS" basis,
+;+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+;+# for the specific language governing rights and limitations under the
+;+# License.
+;+#
+;+# The Original Code is the Netscape Portable Runtime (NSPR).
+;+#
+;+# The Initial Developer of the Original Code is
+;+# Netscape Communications Corporation.
+;+# Portions created by the Initial Developer are Copyright (C) 2002-2003
+;+# the Initial Developer. All Rights Reserved.
+;+#
+;+# Contributor(s):
+;+#
+;+# Alternatively, the contents of this file may be used under the terms of
+;+# either the GNU General Public License Version 2 or later (the "GPL"), or
+;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+;+# in which case the provisions of the GPL or the LGPL are applicable instead
+;+# of those above. If you wish to allow use of your version of this file only
+;+# under the terms of either the GPL or the LGPL, and not to allow others to
+;+# use your version of this file under the terms of the MPL, indicate your
+;+# decision by deleting the provisions above and replace them with the notice
+;+# and other provisions required by the GPL or the LGPL. If you do not delete
+;+# the provisions above, a recipient may use your version of this file under
+;+# the terms of any one of the MPL, the GPL or the LGPL.
+;+#
+;+# ***** END LICENSE BLOCK *****
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS
+;+#   1. For all unix platforms, the string ";-"  means "remove this line"
+;+#   2. For all unix platforms, the string " DATA " will be removed from any 
+;+#     line on which it occurs.
+;+#   3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+#      On AIX, lines containing ";+" will be removed.
+;+#   4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+#   5. For all unix platforms, after the above processing has taken place,
+;+#    all characters after the first ";" on the line will be removed.
+;+#    And for AIX, the first ";" will also be removed.
+;+#  This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+#   directives are hidden behind ";", ";+", and ";-"
+;+#
+;+NSPR_4.0 {
+;+	global:
+LIBRARY nspr4 ;-
+EXPORTS ;-
+		LL_MaxInt;
+		LL_MinInt;
+		LL_Zero;
+		PR_Abort;
+		PR_AddToCounter;
+		PR_Accept;
+		PR_AcceptRead;
+		PR_Access;
+		PR_AddWaitFileDesc;
+		PR_AllocFileDesc;
+		PR_Assert;
+		PR_AtomicAdd;
+		PR_AtomicDecrement;
+		PR_AtomicIncrement;
+		PR_AtomicSet;
+		PR_AttachSharedMemory;
+		PR_AttachThread;
+		PR_Available;
+		PR_Available64;
+		PR_Bind;
+		PR_BlockClockInterrupts;
+		PR_BlockInterrupt;
+		PR_CEnterMonitor;
+		PR_CExitMonitor;
+		PR_CNotify;
+		PR_CNotifyAll;
+		PR_CSetOnMonitorRecycle;
+		PR_CWait;
+		PR_CallOnce;
+		PR_Calloc;
+		PR_CancelJob;
+		PR_CancelWaitFileDesc;
+		PR_CancelWaitGroup;
+		PR_CeilingLog2;
+		PR_ChangeFileDescNativeHandle;
+		PR_Cleanup;
+		PR_ClearInterrupt;
+		PR_ClearThreadGCAble;
+		PR_Close;
+		PR_CloseDir;
+		PR_CloseFileMap;
+		PR_CloseSemaphore;
+		PR_CloseSharedMemory;
+		PR_Connect;
+		PR_CreateCounter;
+		PR_ConvertIPv4AddrToIPv6;
+		PR_CreateAlarm;
+		PR_CreateFileMap;
+		PR_CreateIOLayerStub;
+		PR_CreateOrderedLock;
+		PR_CreateMWaitEnumerator;
+		PR_CreatePipe;
+		PR_CreateProcess;
+		PR_CreateProcessDetached;
+		PR_CreateSocketPollFd;
+		PR_CreateStack;
+		PR_CreateThread;
+		PR_CreateThreadGCAble;
+		PR_CreateTrace;
+		PR_CreateThreadPool;
+		PR_DecrementCounter;
+		PR_CreateWaitGroup;
+		PR_Delete;
+		PR_DeleteSemaphore;
+		PR_DeleteSharedMemory;
+		PR_DestroyAlarm;
+		PR_DestroyCounter;
+		PR_DestroyCondVar;
+		PR_DestroyLock;
+		PR_DestroyMWaitEnumerator;
+		PR_DestroyOrderedLock;
+		PR_DestroyMonitor;
+		PR_DestroyPollableEvent;
+		PR_DestroyProcessAttr;
+		PR_DestroyRWLock;
+		PR_DestroySem;
+		PR_DestroySocketPollFd;
+		PR_DestroyTrace;
+		PR_DestroyStack;
+		PR_DestroyWaitGroup;
+		PR_DetachProcess;
+		PR_DetachSharedMemory;
+		PR_DetachThread;
+		PR_DisableClockInterrupts;
+		PR_EnableClockInterrupts;
+		PR_EnterMonitor;
+		PR_EnumerateHostEnt;
+		PR_EnumerateThreads;
+		PR_EnumerateWaitGroup;
+		PR_ErrorInstallCallback;
+		PR_ErrorInstallTable;
+		PR_ErrorLanguages;
+		PR_ErrorToName;
+		PR_ErrorToString;
+		PR_ExitMonitor;
+		PR_ExplodeTime;
+		PR_ExportFileMapAsString;
+		PR_FD_CLR;
+		PR_FD_ISSET;
+		PR_FD_NCLR;
+		PR_FD_NISSET;
+		PR_FD_NSET;
+		PR_FD_SET;
+		PR_FD_ZERO;
+		PR_FileDesc2NativeHandle;
+		PR_FindSymbol;
+		PR_FindSymbolAndLibrary;
+		PR_FloorLog2;
+		PR_FormatTime;
+		PR_FindNextCounterQname;
+		PR_FindNextCounterRname;
+		PR_FindNextTraceQname;
+		PR_FindNextTraceRname;
+		PR_FormatTimeUSEnglish;
+		PR_Free;
+		PR_FreeLibraryName;
+		PR_GMTParameters;
+		PR_GetConnectStatus;
+		PR_GetCurrentThread;
+		PR_GetDefaultIOMethods;
+		PR_GetDescType;
+		PR_GetDirectorySeparator;
+		PR_GetCounter;
+		PR_GetCounterHandleFromName;
+		PR_GetCounterNameFromHandle;
+		PR_GetDirectorySepartor;
+		PR_GetEnv;
+		PR_GetError;
+		PR_GetErrorText;
+		PR_GetErrorTextLength;
+		PR_GetFileInfo;
+		PR_GetFileInfo64;
+		PR_GetFileMethods;
+		PR_GetGCRegisters;
+		PR_GetHostByAddr;
+		PR_GetHostByName;
+		PR_GetIPNodeByName;
+		PR_GetIdentitiesLayer;
+		PR_GetInheritedFD;
+		PR_GetInheritedFileMap;
+		PR_GetLayersIdentity;
+		PR_GetLibraryName;
+		PR_GetLibraryPath;
+		PR_GetMonitorEntryCount;
+		PR_GetNameForIdentity;
+		PR_GetOSError;
+		PR_GetOpenFileInfo;
+		PR_GetOpenFileInfo64;
+		PR_GetPageShift;
+		PR_GetPageSize;
+		PR_GetPeerName;
+		PR_GetPipeMethods;
+		PR_GetProtoByName;
+		PR_GetProtoByNumber;
+		PR_GetRandomNoise;
+		PR_GetSP;
+		PR_GetSockName;
+		PR_GetSocketOption;
+		PR_GetSpecialFD;
+		PR_GetStackSpaceLeft;
+		PR_GetSysfdTableMax;
+		PR_GetSystemInfo;
+		PR_GetTCPMethods;
+		PR_GetThreadAffinityMask;
+		PR_GetThreadID;
+		PR_GetThreadPriority;
+		PR_GetThreadPrivate;
+		PR_GetThreadScope;
+		PR_GetThreadState;
+		PR_GetThreadType;
+		PR_GetUDPMethods;
+		PR_GetUniqueIdentity;
+		PR_ImplodeTime;
+		PR_ImportFile;
+		PR_ImportFileMapFromString;
+		PR_ImportTCPSocket;
+		PR_ImportUDPSocket;
+		PR_GetTraceEntries;
+		PR_GetTraceHandleFromName;
+		PR_GetTraceNameFromHandle;
+		PR_GetTraceOption;
+		PR_Init;
+		PR_Initialize;
+		PR_InitializeNetAddr;
+		PR_Initialized;
+		PR_Interrupt;
+		PR_IntervalNow;
+		PR_IntervalToMicroseconds;
+		PR_IntervalToMilliseconds;
+		PR_IncrementCounter;
+		PR_IntervalToSeconds;
+		PR_IsNetAddrType;
+		PR_JoinJob;
+		PR_JoinThread;
+		PR_JoinThreadPool;
+		PR_KillProcess;
+		PR_Listen;
+		PR_LoadLibrary;
+		PR_LoadLibraryWithFlags;
+		PR_LoadStaticLibrary;
+		PR_LocalTimeParameters;
+		PR_Lock;
+		PR_LockFile;
+		PR_LogFlush;
+		PR_LogPrint;
+		PR_MakeDir;
+		PR_Malloc;
+		PR_MemMap;
+		PR_MemUnmap;
+		PR_MicrosecondsToInterval;
+		PR_MillisecondsToInterval;
+		PR_LockOrderedLock;
+		PR_MkDir;
+		PR_NetAddrToString;
+		PR_NewCondVar;
+		PR_NewLock;
+		PR_NewLogModule;
+		PR_NewMonitor;
+		PR_NewNamedMonitor;
+		PR_NewPollableEvent;
+		PR_NewProcessAttr;
+		PR_NewRWLock;
+		PR_NewSem;
+		PR_NewTCPSocket;
+		PR_NewTCPSocketPair;
+		PR_NewThreadPrivateIndex;
+		PR_NewUDPSocket;
+		PR_NormalizeTime;
+		PR_Notify;
+		PR_NotifyAll;
+		PR_NotifyAllCondVar;
+		PR_NotifyCondVar;
+		PR_Now;
+		PR_Open;
+		PR_OpenAnonFileMap;
+		PR_OpenDir;
+		PR_OpenFile;
+		PR_OpenSemaphore;
+		PR_OpenSharedMemory;
+		PR_OpenTCPSocket;
+		PR_OpenUDPSocket;
+		PR_ParseTimeString;
+		PR_Poll;
+		PR_PopIOLayer;
+		PR_PostSem;
+		PR_PostSemaphore;
+		PR_ProcessAttrSetCurrentDirectory;
+		PR_ProcessAttrSetInheritableFD;
+		PR_ProcessAttrSetInheritableFileMap;
+		PR_ProcessAttrSetStdioRedirect;
+		PR_ProcessExit;
+		PR_PushIOLayer;
+		PR_QueueJob;
+		PR_QueueJob_Accept;
+		PR_QueueJob_Connect;
+		PR_QueueJob_Read;
+		PR_QueueJob_Timer;
+		PR_QueueJob_Write;
+		PR_RWLock_Rlock;
+		PR_RWLock_Unlock;
+		PR_RWLock_Wlock;
+		PR_Read;
+		PR_ReadDir;
+		PR_Realloc;
+		PR_Recv;
+		PR_RecvFrom;
+		PR_Rename;
+		PR_ResetAlarm;
+		PR_ResetProcessAttr;
+		PR_ResumeAll;
+		PR_RmDir;
+		PR_ScanStackPointers;
+		PR_RecordTraceEntries;
+		PR_SecondsToInterval;
+		PR_Seek;
+		PR_Seek64;
+		PR_Select;
+		PR_Send;
+		PR_SendFile;
+		PR_SendTo;
+		PR_SetAlarm;
+		PR_SetConcurrency;
+		PR_SetError;
+		PR_SetErrorText;
+		PR_SetFDCacheSize;
+		PR_SetFDInheritable;
+		PR_SetLibraryPath;
+		PR_SetLogBuffering;
+		PR_SetLogFile;
+		PR_SetNetAddr;
+		PR_SetPollableEvent;
+		PR_SetSocketOption;
+		PR_SetCounter;
+		PR_SetStdioRedirect;
+		PR_SetSysfdTableSize;
+		PR_SetThreadAffinityMask;
+		PR_SetThreadDumpProc;
+		PR_SetThreadGCAble;
+		PR_SetThreadPriority;
+		PR_SetThreadPrivate;
+		PR_SetThreadRecycleMode;
+		PR_Shutdown;
+		PR_ShutdownThreadPool;
+		PR_Sleep;
+		PR_Socket;
+		PR_StackPop;
+		PR_StackPush;
+		PR_Stat;
+		PR_StringToNetAddr;
+		PR_SuspendAll;
+		PR_Sync;
+		PR_TLockFile;
+		PR_ThreadScanStackPointers;
+		PR_SetTraceOption;
+		PR_TicksPerSecond;
+		PR_TransmitFile;
+		PR_USPacificTimeParameters;
+		PR_UnblockClockInterrupts;
+		PR_UnblockInterrupt;
+		PR_UnloadLibrary;
+		PR_SubtractFromCounter;
+		PR_Unlock;
+		PR_UnlockFile;
+		PR_VersionCheck;
+		PR_Wait;
+		PR_WaitCondVar;
+		PR_WaitForPollableEvent;
+		PR_Trace;
+		PR_WaitProcess;
+		PR_WaitRecvReady;
+		PR_WaitSem;
+		PR_WaitSemaphore;
+		PR_Write;
+		PR_Writev;
+		PR_Yield;
+		PR_UnlockOrderedLock;
+		PR_cnvtf;
+		PR_dtoa;
+		PR_fprintf;
+		PR_htonl;
+		PR_htonll;
+		PR_htons;
+		PR_ntohl;
+		PR_ntohll;
+		PR_ntohs;
+		PR_smprintf;
+		PR_smprintf_free;
+		PR_snprintf;
+		PR_sprintf_append;
+		PR_sscanf;
+		PR_strtod;
+		PR_sxprintf;
+		PR_vfprintf;
+		PR_vsmprintf;
+		PR_vsnprintf;
+		PR_vsprintf_append;
+		PR_vsxprintf;
+		PRP_DestroyNakedCondVar;
+		PRP_NakedBroadcast;
+		PRP_NakedNotify;
+		PRP_NakedWait;
+		PRP_NewNakedCondVar;
+		PRP_TryLock;
+		libVersionPoint;
+;+	local: *;
+;+};
+;+
+;+NSPRprivate {
+;+	global:
+		GetExecutionEnvironment;
+		PT_FPrintStats;
+		SetExecutionEnvironment;
+;+	local: *;
+;+};
+;+
+;+NSPR_4.1 {
+;+	global:
+		PR_ConnectContinue;
+		PR_CreateIOLayer;
+		PR_EmulateAcceptRead;
+		PR_EmulateSendFile;
+		PR_FindFunctionSymbol;
+		PR_FindFunctionSymbolAndLibrary;
+		PR_GetMemMapAlignment;
+		PR_GetNumberOfProcessors;
+		PR_ImportPipe;
+		PR_SetEnv;
+;+} NSPR_4.0;
+;+
+;+NSPR_4.3 {
+;+	global:
+		LL_MaxUint;
+		PR_CallOnceWithArg;
+		PR_GetLibraryFilePathname;
+;+} NSPR_4.1;
+;+
+;+NSPR_4.4 {
+;+	global:
+		PR_GetPathSeparator;
+;+} NSPR_4.3;
+;+
+;+NSPR_4.5 {
+;+	global:
+		PR_EnumerateAddrInfo;
+		PR_FreeAddrInfo;
+		PR_GetAddrInfoByName;
+		PR_GetCanonNameFromAddrInfo;
+;+} NSPR_4.4;
+;+
+;+NSPR_4.6 {
+;+	global:
+		PR_GetPhysicalMemorySize;
+;+} NSPR_4.5;
+;+NSPR_4.7 {
+;+	global:
+		PR_ParseTimeStringToExplodedTime;
+;+} NSPR_4.6;
+;+NSPR_4.8 {
+;+	global:
+		PR_AssertCurrentThreadOwnsLock;
+		PR_AssertCurrentThreadInMonitor;
+;+} NSPR_4.7;
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/nspr.rc b/nspr-4.8.6/mozilla/nsprpub/pr/src/nspr.rc
new file mode 100644
index 0000000..da22313
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/nspr.rc
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include <winver.h>
+
+#define MY_LIBNAME "nspr"
+#define MY_FILEDESCRIPTION "NSPR 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
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+        BEGIN
+            VALUE "CompanyName", "Mozilla Foundation\0"
+            VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+            VALUE "FileVersion", PR_VERSION "\0"
+            VALUE "InternalName", MY_INTERNAL_NAME "\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
+    END
+END
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/os2extra.def b/nspr-4.8.6/mozilla/nsprpub/pr/src/os2extra.def
new file mode 100644
index 0000000..8dbb34d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/os2extra.def
@@ -0,0 +1,16 @@
+    ;
+    ; Support plugins that were explicitly linked to the Visual Age
+    ;   version of nspr4.dll.
+    ;
+    PR_NewMonitor
+    PR_EnterMonitor
+    PR_ExitMonitor
+    PR_GetCurrentThread
+    PR_AttachThread
+    PR_DetachThread
+    ;
+    ; Exception handler functions that are used by nsAppRunner.cpp
+    ;
+    _PR_OS2_SetFloatExcpHandler
+    _PR_OS2_UnsetFloatExcpHandler
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/prvrsion.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/prvrsion.c
new file mode 100644
index 0000000..7c494c6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/prvrsion.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prvrsion.h"
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+#include "_pr_bld.h"
+#if !defined(_BUILD_TIME)
+#ifdef HAVE_LONG_LONG
+#define _BUILD_TIME 0
+#else
+#define _BUILD_TIME {0, 0}
+#endif
+#endif
+#if !defined(_BUILD_STRING)
+#define _BUILD_STRING ""
+#endif
+#if !defined(_PRODUCTION)
+#define _PRODUCTION ""
+#endif
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * 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_libnspr, 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 */
+#if defined(DEBUG)
+    /* debug            */  PR_TRUE,            /* a debug build */
+#else
+    /* debug            */  PR_FALSE,           /* an optomized build */
+#endif
+    /* special          */  PR_FALSE,           /* they're all special, but ... */
+    /* filename         */  _PRODUCTION,        /* the produced library name */
+    /* description      */ "Portable runtime",  /* what we are */
+    /* security         */ "N/A",               /* not applicable here */
+    /* copywrite        */  "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved",
+    /* comment          */  "License information: http://www.mozilla.org/MPL/",
+    /* specialString    */ ""
+};
+
+#ifdef XP_UNIX
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING
+        "  " _BUILD_STRING " $";
+static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
+        "  " _BUILD_STRING;
+
+#endif /* XP_UNIX */
+
+PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
+{
+#ifdef XP_UNIX
+    /*
+     * 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 &VERSION_DESC_NAME;
+}  /* versionEntryPointType */
+
+/* prvrsion.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/Makefile.in
new file mode 100644
index 0000000..006a3e8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/Makefile.in
@@ -0,0 +1,74 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+# Disable optimization of the nspr on SunOS4.1.3
+ifeq ($(OS_ARCH),SunOS)
+ifeq ($(OS_RELEASE),4.1.3_U1)
+OPTIMIZER =
+endif
+endif
+
+CSRCS = \
+	ptio.c \
+	ptsynch.c \
+	ptthread.c \
+	ptmisc.c \
+	$(NULL)
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptio.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptio.c
new file mode 100644
index 0000000..23f415c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptio.c
@@ -0,0 +1,5005 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:   ptio.c
+** Descritpion:  Implemenation of I/O methods for pthreads
+*/
+
+#if defined(_PR_PTHREADS)
+
+#if defined(_PR_POLL_WITH_SELECT)
+#if !(defined(HPUX) && defined(_USE_BIG_FDS))
+/* set fd limit for select(), before including system header files */
+#define FD_SETSIZE (16 * 1024)
+#endif
+#endif
+
+#include <pthread.h>
+#include <string.h>  /* for memset() */
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#if defined(DARWIN)
+#include <sys/utsname.h> /* for uname */
+#endif
+#if defined(SOLARIS) || defined(UNIXWARE)
+#include <sys/filio.h>  /* to pick up FIONREAD */
+#endif
+#ifdef _PR_POLL_AVAILABLE
+#include <poll.h>
+#endif
+#ifdef AIX
+/* To pick up sysconf() */
+#include <unistd.h>
+#include <dlfcn.h>  /* for dlopen */
+#else
+/* To pick up getrlimit() etc. */
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+#ifdef SOLARIS
+/*
+ * Define HAVE_SENDFILEV if the system has the sendfilev() system call.
+ * Code built this way won't run on a system without sendfilev().
+ * We can define HAVE_SENDFILEV by default when the minimum release
+ * of Solaris that NSPR supports has sendfilev().
+ */
+#ifdef HAVE_SENDFILEV
+
+#include <sys/sendfile.h>
+
+#define SOLARIS_SENDFILEV(a, b, c, d) sendfilev((a), (b), (c), (d))
+
+#else
+
+#include <dlfcn.h>  /* for dlopen */
+
+/*
+ * Match the definitions in <sys/sendfile.h>.
+ */
+typedef struct sendfilevec {
+    int sfv_fd;       /* input fd */
+    uint_t sfv_flag;  /* flags */
+    off_t sfv_off;    /* offset to start reading from */
+    size_t sfv_len;   /* amount of data */
+} sendfilevec_t;
+
+#define SFV_FD_SELF (-2)
+
+/*
+ * extern ssize_t sendfilev(int, const struct sendfilevec *, int, size_t *);
+ */
+static ssize_t (*pt_solaris_sendfilev_fptr)() = NULL;
+
+#define SOLARIS_SENDFILEV(a, b, c, d) \
+        (*pt_solaris_sendfilev_fptr)((a), (b), (c), (d))
+
+#endif /* HAVE_SENDFILEV */
+#endif /* SOLARIS */
+
+/*
+ * The send_file() system call is available in AIX 4.3.2 or later.
+ * If this file is compiled on an older AIX system, it attempts to
+ * look up the send_file symbol at run time to determine whether
+ * we can use the faster PR_SendFile/PR_TransmitFile implementation based on
+ * send_file().  On AIX 4.3.2 or later, we can safely skip this
+ * runtime function dispatching and just use the send_file based
+ * implementation.
+ */
+#ifdef AIX
+#ifdef SF_CLOSE
+#define HAVE_SEND_FILE
+#endif
+
+#ifdef HAVE_SEND_FILE
+
+#define AIX_SEND_FILE(a, b, c) send_file(a, b, c)
+
+#else /* HAVE_SEND_FILE */
+
+/*
+ * The following definitions match those in <sys/socket.h>
+ * on AIX 4.3.2.
+ */
+
+/*
+ * Structure for the send_file() system call
+ */
+struct sf_parms {
+    /* --------- header parms ---------- */
+    void      *header_data;         /* Input/Output. Points to header buf */
+    uint_t    header_length;        /* Input/Output. Length of the header */
+    /* --------- file parms ------------ */
+    int       file_descriptor;      /* Input. File descriptor of the file */
+    unsigned long long file_size;   /* Output. Size of the file */
+    unsigned long long file_offset; /* Input/Output. Starting offset */
+    long long file_bytes;           /* Input/Output. no. of bytes to send */
+    /* --------- trailer parms --------- */
+    void      *trailer_data;        /* Input/Output. Points to trailer buf */
+    uint_t    trailer_length;       /* Input/Output. Length of the trailer */
+    /* --------- return info ----------- */
+    unsigned long long bytes_sent;  /* Output. no. of bytes sent */
+};
+
+/*
+ * Flags for the send_file() system call
+ */
+#define SF_CLOSE        0x00000001      /* close the socket after completion */
+#define SF_REUSE        0x00000002      /* reuse socket. not supported */
+#define SF_DONT_CACHE   0x00000004      /* don't apply network buffer cache */
+#define SF_SYNC_CACHE   0x00000008      /* sync/update network buffer cache */
+
+/*
+ * prototype: size_t send_file(int *, struct sf_parms *, uint_t);
+ */
+static ssize_t (*pt_aix_sendfile_fptr)() = NULL;
+
+#define AIX_SEND_FILE(a, b, c) (*pt_aix_sendfile_fptr)(a, b, c)
+
+#endif /* HAVE_SEND_FILE */
+#endif /* AIX */
+
+#ifdef LINUX
+#include <sys/sendfile.h>
+#endif
+
+#include "primpl.h"
+
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>  /* TCP_NODELAY, TCP_MAXSEG */
+#endif
+
+#ifdef LINUX
+/* TCP_CORK is not defined in <netinet/tcp.h> on Red Hat Linux 6.0 */
+#ifndef TCP_CORK
+#define TCP_CORK 3
+#endif
+#endif
+
+#ifdef _PR_IPV6_V6ONLY_PROBE
+static PRBool _pr_ipv6_v6only_on_by_default;
+#endif
+
+#if (defined(HPUX) && !defined(HPUX10_30) && !defined(HPUX11))
+#define _PRSelectFdSetArg_t int *
+#elif defined(AIX4_1)
+#define _PRSelectFdSetArg_t void *
+#elif defined(IRIX) || (defined(AIX) && !defined(AIX4_1)) \
+    || defined(OSF1) || defined(SOLARIS) \
+    || defined(HPUX10_30) || defined(HPUX11) \
+    || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+    || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
+    || defined(BSDI) || defined(NTO) || defined(DARWIN) \
+    || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN)
+#define _PRSelectFdSetArg_t fd_set *
+#else
+#error "Cannot determine architecture"
+#endif
+
+static PRFileDesc *pt_SetMethods(
+    PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported);
+
+static PRLock *_pr_flock_lock;  /* For PR_LockFile() etc. */
+static PRCondVar *_pr_flock_cv;  /* For PR_LockFile() etc. */
+static PRLock *_pr_rename_lock;  /* For PR_Rename() */
+
+/**************************************************************************/
+
+/* These two functions are only used in assertions. */
+#if defined(DEBUG)
+
+PRBool IsValidNetAddr(const PRNetAddr *addr)
+{
+    if ((addr != NULL)
+            && (addr->raw.family != AF_UNIX)
+            && (addr->raw.family != PR_AF_INET6)
+            && (addr->raw.family != AF_INET)) {
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+
+static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
+{
+    /*
+     * The definition of the length of a Unix domain socket address
+     * is not uniform, so we don't check it.
+     */
+    if ((addr != NULL)
+            && (addr->raw.family != AF_UNIX)
+            && (PR_NETADDR_SIZE(addr) != addr_len)) {
+#if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1
+        /*
+         * In glibc 2.1, struct sockaddr_in6 is 24 bytes.  In glibc 2.2
+         * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id
+         * field and is 28 bytes.  It is possible for socket functions
+         * to return an addr_len greater than sizeof(struct sockaddr_in6).
+         * We need to allow that.  (Bugzilla bug #77264)
+         */
+        if ((PR_AF_INET6 == addr->raw.family)
+                && (sizeof(addr->ipv6) == addr_len)) {
+            return PR_TRUE;
+        }
+#endif
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+
+#endif /* DEBUG */
+
+/*****************************************************************************/
+/************************* I/O Continuation machinery ************************/
+/*****************************************************************************/
+
+/*
+ * The polling interval defines the maximum amount of time that a thread
+ * might hang up before an interrupt is noticed.
+ */
+#define PT_DEFAULT_POLL_MSEC 5000
+#if defined(_PR_POLL_WITH_SELECT)
+#define PT_DEFAULT_SELECT_SEC (PT_DEFAULT_POLL_MSEC/PR_MSEC_PER_SEC)
+#define PT_DEFAULT_SELECT_USEC							\
+		((PT_DEFAULT_POLL_MSEC % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC)
+#endif
+
+/*
+ * pt_SockLen is the type for the length of a socket address
+ * structure, used in the address length argument to bind,
+ * connect, accept, getsockname, getpeername, etc.  Posix.1g
+ * defines this type as socklen_t.  It is size_t or int on
+ * most current systems.
+ */
+#if defined(HAVE_SOCKLEN_T) \
+    || (defined(__GLIBC__) && __GLIBC__ >= 2)
+typedef socklen_t pt_SockLen;
+#elif (defined(AIX) && !defined(AIX4_1)) 
+typedef PRSize pt_SockLen;
+#else
+typedef PRIntn pt_SockLen;
+#endif
+
+typedef struct pt_Continuation pt_Continuation;
+typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revents);
+
+typedef enum pr_ContuationStatus
+{
+    pt_continuation_pending,
+    pt_continuation_done
+} pr_ContuationStatus;
+
+struct pt_Continuation
+{
+    /* The building of the continuation operation */
+    ContinuationFn function;                /* what function to continue */
+    union { PRIntn osfd; } arg1;            /* #1 - the op's fd */
+    union { void* buffer; } arg2;           /* #2 - primary transfer buffer */
+    union {
+        PRSize amount;                      /* #3 - size of 'buffer', or */
+        pt_SockLen *addr_len;                  /*    - length of address */
+#ifdef HPUX11
+        /*
+         * For sendfile()
+         */
+		struct file_spec {		
+        	off_t offset;                       /* offset in file to send */
+        	size_t nbytes;                      /* length of file data to send */
+        	size_t st_size;                     /* file size */
+		} file_spec;
+#endif
+    } arg3;
+    union { PRIntn flags; } arg4;           /* #4 - read/write flags */
+    union { PRNetAddr *addr; } arg5;        /* #5 - send/recv address */
+
+#ifdef HPUX11
+    /*
+     * For sendfile()
+     */
+    int filedesc;                           /* descriptor of file to send */
+    int nbytes_to_send;                     /* size of header and file */
+#endif  /* HPUX11 */
+    
+#ifdef SOLARIS
+    /*
+     * For sendfilev()
+     */
+    int nbytes_to_send;                     /* size of header and file */
+#endif  /* SOLARIS */
+
+#ifdef LINUX
+    /*
+     * For sendfile()
+     */
+    int in_fd;                              /* descriptor of file to send */
+    off_t offset;
+    size_t count;
+#endif  /* LINUX */
+ 
+    PRIntervalTime timeout;                 /* client (relative) timeout */
+
+    PRInt16 event;                           /* flags for poll()'s events */
+
+    /*
+    ** The representation and notification of the results of the operation.
+    ** These function can either return an int return code or a pointer to
+    ** some object.
+    */
+    union { PRSize code; void *object; } result;
+
+    PRIntn syserrno;                        /* in case it failed, why (errno) */
+    pr_ContuationStatus status;             /* the status of the operation */
+};
+
+#if defined(DEBUG)
+
+PTDebug pt_debug;  /* this is shared between several modules */
+
+PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
+{
+    PTDebug stats;
+    char buffer[100];
+    PRExplodedTime tod;
+    PRInt64 elapsed, aMil;
+    stats = pt_debug;  /* a copy */
+    PR_ExplodeTime(stats.timeStarted, PR_LocalTimeParameters, &tod);
+    (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod);
+
+    LL_SUB(elapsed, PR_Now(), stats.timeStarted);
+    LL_I2L(aMil, 1000000);
+    LL_DIV(elapsed, elapsed, aMil);
+    
+    if (NULL != msg) PR_fprintf(debug_out, "%s", msg);
+    PR_fprintf(
+        debug_out, "\tstarted: %s[%lld]\n", buffer, elapsed);
+    PR_fprintf(
+        debug_out, "\tlocks [created: %u, destroyed: %u]\n",
+        stats.locks_created, stats.locks_destroyed);
+    PR_fprintf(
+        debug_out, "\tlocks [acquired: %u, released: %u]\n",
+        stats.locks_acquired, stats.locks_released);
+    PR_fprintf(
+        debug_out, "\tcvars [created: %u, destroyed: %u]\n",
+        stats.cvars_created, stats.cvars_destroyed);
+    PR_fprintf(
+        debug_out, "\tcvars [notified: %u, delayed_delete: %u]\n",
+        stats.cvars_notified, stats.delayed_cv_deletes);
+}  /* PT_FPrintStats */
+
+#else
+
+PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
+{
+    /* do nothing */
+}  /* PT_FPrintStats */
+
+#endif  /* DEBUG */
+
+#if defined(_PR_POLL_WITH_SELECT)
+/*
+ * OSF1 and HPUX report the POLLHUP event for a socket when the
+ * shutdown(SHUT_WR) operation is called for the remote end, even though
+ * the socket is still writeable. Use select(), instead of poll(), to
+ * workaround this problem.
+ */
+static void pt_poll_now_with_select(pt_Continuation *op)
+{
+    PRInt32 msecs;
+	fd_set rd, wr, *rdp, *wrp;
+	struct timeval tv;
+	PRIntervalTime epoch, now, elapsed, remaining;
+	PRBool wait_for_remaining;
+    PRThread *self = PR_GetCurrentThread();
+    
+	PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
+	PR_ASSERT(op->arg1.osfd < FD_SETSIZE);
+
+    switch (op->timeout) {
+        case PR_INTERVAL_NO_TIMEOUT:
+			tv.tv_sec = PT_DEFAULT_SELECT_SEC;
+			tv.tv_usec = PT_DEFAULT_SELECT_USEC;
+			do
+			{
+				PRIntn rv;
+
+				if (op->event & POLLIN) {
+					FD_ZERO(&rd);
+					FD_SET(op->arg1.osfd, &rd);
+					rdp = &rd;
+				} else
+					rdp = NULL;
+				if (op->event & POLLOUT) {
+					FD_ZERO(&wr);
+					FD_SET(op->arg1.osfd, &wr);
+					wrp = &wr;
+				} else
+					wrp = NULL;
+
+				rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);
+
+				if (_PT_THREAD_INTERRUPTED(self))
+				{
+					self->state &= ~PT_THREAD_ABORTED;
+					op->result.code = -1;
+					op->syserrno = EINTR;
+					op->status = pt_continuation_done;
+					return;
+				}
+
+				if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN)))
+					continue; /* go around the loop again */
+
+				if (rv > 0)
+				{
+					PRInt16 revents = 0;
+
+					if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd))
+						revents |= POLLIN;
+					if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr))
+						revents |= POLLOUT;
+						
+					if (op->function(op, revents))
+						op->status = pt_continuation_done;
+				} else if (rv == -1) {
+					op->result.code = -1;
+					op->syserrno = errno;
+					op->status = pt_continuation_done;
+				}
+				/* else, select timed out */
+			} while (pt_continuation_done != op->status);
+			break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = op->timeout;
+			do
+			{
+				PRIntn rv;
+
+				if (op->event & POLLIN) {
+					FD_ZERO(&rd);
+					FD_SET(op->arg1.osfd, &rd);
+					rdp = &rd;
+				} else
+					rdp = NULL;
+				if (op->event & POLLOUT) {
+					FD_ZERO(&wr);
+					FD_SET(op->arg1.osfd, &wr);
+					wrp = &wr;
+				} else
+					wrp = NULL;
+
+    			wait_for_remaining = PR_TRUE;
+    			msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);
+				if (msecs > PT_DEFAULT_POLL_MSEC) {
+					wait_for_remaining = PR_FALSE;
+					msecs = PT_DEFAULT_POLL_MSEC;
+				}
+				tv.tv_sec = msecs/PR_MSEC_PER_SEC;
+				tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC;
+				rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);
+
+				if (_PT_THREAD_INTERRUPTED(self))
+				{
+					self->state &= ~PT_THREAD_ABORTED;
+					op->result.code = -1;
+					op->syserrno = EINTR;
+					op->status = pt_continuation_done;
+					return;
+				}
+
+				if (rv > 0) {
+					PRInt16 revents = 0;
+
+					if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd))
+						revents |= POLLIN;
+					if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr))
+						revents |= POLLOUT;
+						
+					if (op->function(op, revents))
+						op->status = pt_continuation_done;
+
+				} else if ((rv == 0) ||
+						((errno == EINTR) || (errno == EAGAIN))) {
+					if (rv == 0) {	/* select timed out */
+						if (wait_for_remaining)
+							now += remaining;
+						else
+							now += PR_MillisecondsToInterval(msecs);
+					} else
+						now = PR_IntervalNow();
+					elapsed = (PRIntervalTime) (now - epoch);
+					if (elapsed >= op->timeout) {
+						op->result.code = -1;
+						op->syserrno = ETIMEDOUT;
+						op->status = pt_continuation_done;
+					} else
+						remaining = op->timeout - elapsed;
+				} else {
+					op->result.code = -1;
+					op->syserrno = errno;
+					op->status = pt_continuation_done;
+				}
+			} while (pt_continuation_done != op->status);
+            break;
+    }
+
+}  /* pt_poll_now_with_select */
+
+#endif	/* _PR_POLL_WITH_SELECT */
+
+static void pt_poll_now(pt_Continuation *op)
+{
+    PRInt32 msecs;
+	PRIntervalTime epoch, now, elapsed, remaining;
+	PRBool wait_for_remaining;
+    PRThread *self = PR_GetCurrentThread();
+    
+	PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
+#if defined (_PR_POLL_WITH_SELECT)
+	/*
+ 	 * If the fd is small enough call the select-based poll operation
+	 */
+	if (op->arg1.osfd < FD_SETSIZE) {
+		pt_poll_now_with_select(op);
+		return;
+	}
+#endif
+
+    switch (op->timeout) {
+        case PR_INTERVAL_NO_TIMEOUT:
+			msecs = PT_DEFAULT_POLL_MSEC;
+			do
+			{
+				PRIntn rv;
+				struct pollfd tmp_pfd;
+
+				tmp_pfd.revents = 0;
+				tmp_pfd.fd = op->arg1.osfd;
+				tmp_pfd.events = op->event;
+
+				rv = poll(&tmp_pfd, 1, msecs);
+				
+				if (_PT_THREAD_INTERRUPTED(self))
+				{
+					self->state &= ~PT_THREAD_ABORTED;
+					op->result.code = -1;
+					op->syserrno = EINTR;
+					op->status = pt_continuation_done;
+					return;
+				}
+
+				if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN)))
+					continue; /* go around the loop again */
+
+				if (rv > 0)
+				{
+					PRInt16 events = tmp_pfd.events;
+					PRInt16 revents = tmp_pfd.revents;
+
+					if ((revents & POLLNVAL)  /* busted in all cases */
+					|| ((events & POLLOUT) && (revents & POLLHUP)))
+						/* write op & hup */
+					{
+						op->result.code = -1;
+						if (POLLNVAL & revents) op->syserrno = EBADF;
+						else if (POLLHUP & revents) op->syserrno = EPIPE;
+						op->status = pt_continuation_done;
+					} else {
+						if (op->function(op, revents))
+							op->status = pt_continuation_done;
+					}
+				} else if (rv == -1) {
+					op->result.code = -1;
+					op->syserrno = errno;
+					op->status = pt_continuation_done;
+				}
+				/* else, poll timed out */
+			} while (pt_continuation_done != op->status);
+			break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = op->timeout;
+			do
+			{
+				PRIntn rv;
+				struct pollfd tmp_pfd;
+
+				tmp_pfd.revents = 0;
+				tmp_pfd.fd = op->arg1.osfd;
+				tmp_pfd.events = op->event;
+
+    			wait_for_remaining = PR_TRUE;
+    			msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);
+				if (msecs > PT_DEFAULT_POLL_MSEC)
+				{
+					wait_for_remaining = PR_FALSE;
+					msecs = PT_DEFAULT_POLL_MSEC;
+				}
+				rv = poll(&tmp_pfd, 1, msecs);
+				
+				if (_PT_THREAD_INTERRUPTED(self))
+				{
+					self->state &= ~PT_THREAD_ABORTED;
+					op->result.code = -1;
+					op->syserrno = EINTR;
+					op->status = pt_continuation_done;
+					return;
+				}
+
+				if (rv > 0)
+				{
+					PRInt16 events = tmp_pfd.events;
+					PRInt16 revents = tmp_pfd.revents;
+
+					if ((revents & POLLNVAL)  /* busted in all cases */
+						|| ((events & POLLOUT) && (revents & POLLHUP))) 
+											/* write op & hup */
+					{
+						op->result.code = -1;
+						if (POLLNVAL & revents) op->syserrno = EBADF;
+						else if (POLLHUP & revents) op->syserrno = EPIPE;
+						op->status = pt_continuation_done;
+					} else {
+						if (op->function(op, revents))
+						{
+							op->status = pt_continuation_done;
+						}
+					}
+				} else if ((rv == 0) ||
+						((errno == EINTR) || (errno == EAGAIN))) {
+					if (rv == 0)	/* poll timed out */
+					{
+						if (wait_for_remaining)
+							now += remaining;
+						else
+							now += PR_MillisecondsToInterval(msecs);
+					}
+					else
+						now = PR_IntervalNow();
+					elapsed = (PRIntervalTime) (now - epoch);
+					if (elapsed >= op->timeout) {
+						op->result.code = -1;
+						op->syserrno = ETIMEDOUT;
+						op->status = pt_continuation_done;
+					} else
+						remaining = op->timeout - elapsed;
+				} else {
+					op->result.code = -1;
+					op->syserrno = errno;
+					op->status = pt_continuation_done;
+				}
+			} while (pt_continuation_done != op->status);
+            break;
+    }
+
+}  /* pt_poll_now */
+
+static PRIntn pt_Continue(pt_Continuation *op)
+{
+    op->status = pt_continuation_pending;  /* set default value */
+	/*
+	 * let each thread call poll directly
+	 */
+	pt_poll_now(op);
+	PR_ASSERT(pt_continuation_done == op->status);
+    return op->result.code;
+}  /* pt_Continue */
+
+/*****************************************************************************/
+/*********************** specific continuation functions *********************/
+/*****************************************************************************/
+static PRBool pt_connect_cont(pt_Continuation *op, PRInt16 revents)
+{
+    op->syserrno = _MD_unix_get_nonblocking_connect_error(op->arg1.osfd);
+    if (op->syserrno != 0) {
+        op->result.code = -1;
+    } else {
+        op->result.code = 0;
+    }
+    return PR_TRUE; /* this one is cooked */
+}  /* pt_connect_cont */
+
+static PRBool pt_accept_cont(pt_Continuation *op, PRInt16 revents)
+{
+    op->syserrno = 0;
+    op->result.code = accept(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.addr_len);
+    if (-1 == op->result.code)
+    {
+        op->syserrno = errno;
+        if (EWOULDBLOCK == errno || EAGAIN == errno || ECONNABORTED == errno)
+            return PR_FALSE;  /* do nothing - this one ain't finished */
+    }
+    return PR_TRUE;
+}  /* pt_accept_cont */
+
+static PRBool pt_read_cont(pt_Continuation *op, PRInt16 revents)
+{
+    /*
+     * Any number of bytes will complete the operation. It need
+     * not (and probably will not) satisfy the request. The only
+     * error we continue is EWOULDBLOCK|EAGAIN.
+     */
+    op->result.code = read(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount);
+    op->syserrno = errno;
+    return ((-1 == op->result.code) && 
+            (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ?
+        PR_FALSE : PR_TRUE;
+}  /* pt_read_cont */
+
+static PRBool pt_recv_cont(pt_Continuation *op, PRInt16 revents)
+{
+    /*
+     * Any number of bytes will complete the operation. It need
+     * not (and probably will not) satisfy the request. The only
+     * error we continue is EWOULDBLOCK|EAGAIN.
+     */
+#if defined(SOLARIS)
+    if (0 == op->arg4.flags)
+        op->result.code = read(
+            op->arg1.osfd, op->arg2.buffer, op->arg3.amount);
+    else
+        op->result.code = recv(
+            op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
+#else
+    op->result.code = recv(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
+#endif
+    op->syserrno = errno;
+    return ((-1 == op->result.code) && 
+            (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ?
+        PR_FALSE : PR_TRUE;
+}  /* pt_recv_cont */
+
+static PRBool pt_send_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes;
+#if defined(SOLARIS)
+    PRInt32 tmp_amount = op->arg3.amount;
+#endif
+    /*
+     * We want to write the entire amount out, no matter how many
+     * tries it takes. Keep advancing the buffer and the decrementing
+     * the amount until the amount goes away. Return the total bytes
+     * (which should be the original amount) when finished (or an
+     * error).
+     */
+#if defined(SOLARIS)
+retry:
+    bytes = write(op->arg1.osfd, op->arg2.buffer, tmp_amount);
+#else
+    bytes = send(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
+#endif
+    op->syserrno = errno;
+
+#if defined(SOLARIS)
+    /*
+     * The write system call has been reported to return the ERANGE error
+     * on occasion. Try to write in smaller chunks to workaround this bug.
+     */
+    if ((bytes == -1) && (op->syserrno == ERANGE))
+    {
+        if (tmp_amount > 1)
+        {
+            tmp_amount = tmp_amount/2;  /* half the bytes */
+            goto retry;
+        }
+    }
+#endif
+
+    if (bytes >= 0)  /* this is progress */
+    {
+        char *bp = (char*)op->arg2.buffer;
+        bp += bytes;  /* adjust the buffer pointer */
+        op->arg2.buffer = bp;
+        op->result.code += bytes;  /* accumulate the number sent */
+        op->arg3.amount -= bytes;  /* and reduce the required count */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+    {
+        op->result.code = -1;
+        return PR_TRUE;
+    }
+    else return PR_FALSE;
+}  /* pt_send_cont */
+
+static PRBool pt_write_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes;
+    /*
+     * We want to write the entire amount out, no matter how many
+     * tries it takes. Keep advancing the buffer and the decrementing
+     * the amount until the amount goes away. Return the total bytes
+     * (which should be the original amount) when finished (or an
+     * error).
+     */
+    bytes = write(op->arg1.osfd, op->arg2.buffer, op->arg3.amount);
+    op->syserrno = errno;
+    if (bytes >= 0)  /* this is progress */
+    {
+        char *bp = (char*)op->arg2.buffer;
+        bp += bytes;  /* adjust the buffer pointer */
+        op->arg2.buffer = bp;
+        op->result.code += bytes;  /* accumulate the number sent */
+        op->arg3.amount -= bytes;  /* and reduce the required count */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+    {
+        op->result.code = -1;
+        return PR_TRUE;
+    }
+    else return PR_FALSE;
+}  /* pt_write_cont */
+
+static PRBool pt_writev_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes;
+    struct iovec *iov = (struct iovec*)op->arg2.buffer;
+    /*
+     * Same rules as write, but continuing seems to be a bit more
+     * complicated. As the number of bytes sent grows, we have to
+     * redefine the vector we're pointing at. We might have to
+     * modify an individual vector parms or we might have to eliminate
+     * a pair altogether.
+     */
+    bytes = writev(op->arg1.osfd, iov, op->arg3.amount);
+    op->syserrno = errno;
+    if (bytes >= 0)  /* this is progress */
+    {
+        PRIntn iov_index;
+        op->result.code += bytes;  /* accumulate the number sent */
+        for (iov_index = 0; iov_index < op->arg3.amount; ++iov_index)
+        {
+            /* how much progress did we make in the i/o vector? */
+            if (bytes < iov[iov_index].iov_len)
+            {
+                /* this element's not done yet */
+                char **bp = (char**)&(iov[iov_index].iov_base);
+                iov[iov_index].iov_len -= bytes;  /* there's that much left */
+                *bp += bytes;  /* starting there */
+                break;  /* go off and do that */
+            }
+            bytes -= iov[iov_index].iov_len;  /* that element's consumed */
+        }
+        op->arg2.buffer = &iov[iov_index];  /* new start of array */
+        op->arg3.amount -= iov_index;  /* and array length */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+    {
+        op->result.code = -1;
+        return PR_TRUE;
+    }
+    else return PR_FALSE;
+}  /* pt_writev_cont */
+
+static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes = sendto(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags,
+        (struct sockaddr*)op->arg5.addr, PR_NETADDR_SIZE(op->arg5.addr));
+    op->syserrno = errno;
+    if (bytes >= 0)  /* this is progress */
+    {
+        char *bp = (char*)op->arg2.buffer;
+        bp += bytes;  /* adjust the buffer pointer */
+        op->arg2.buffer = bp;
+        op->result.code += bytes;  /* accumulate the number sent */
+        op->arg3.amount -= bytes;  /* and reduce the required count */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+    {
+        op->result.code = -1;
+        return PR_TRUE;
+    }
+    else return PR_FALSE;
+}  /* pt_sendto_cont */
+
+static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents)
+{
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+    op->result.code = recvfrom(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount,
+        op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len);
+    op->syserrno = errno;
+    return ((-1 == op->result.code) && 
+            (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ?
+        PR_FALSE : PR_TRUE;
+}  /* pt_recvfrom_cont */
+
+#ifdef AIX
+static PRBool pt_aix_sendfile_cont(pt_Continuation *op, PRInt16 revents)
+{
+    struct sf_parms *sf_struct = (struct sf_parms *) op->arg2.buffer;
+    ssize_t rv;
+	unsigned long long saved_file_offset;
+	long long saved_file_bytes;
+
+	saved_file_offset = sf_struct->file_offset;
+	saved_file_bytes = sf_struct->file_bytes;
+	sf_struct->bytes_sent = 0;
+
+	if ((sf_struct->file_bytes > 0) && (sf_struct->file_size > 0))
+	PR_ASSERT((sf_struct->file_bytes + sf_struct->file_offset) <=
+									sf_struct->file_size);
+    rv = AIX_SEND_FILE(&op->arg1.osfd, sf_struct, op->arg4.flags);
+    op->syserrno = errno;
+
+    if (rv != -1) {
+        op->result.code += sf_struct->bytes_sent;
+		/*
+		 * A bug in AIX 4.3.2 prevents the 'file_bytes' field from
+		 * being updated. So, 'file_bytes' is maintained by NSPR to
+		 * avoid conflict when this bug is fixed in AIX, in the future.
+		 */
+		if (saved_file_bytes != -1)
+			saved_file_bytes -= (sf_struct->file_offset - saved_file_offset);
+		sf_struct->file_bytes = saved_file_bytes;
+    } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {
+        op->result.code = -1;
+    } else {
+        return PR_FALSE;
+    }
+
+    if (rv == 1) {    /* more data to send */
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+#endif  /* AIX */
+
+#ifdef HPUX11
+static PRBool pt_hpux_sendfile_cont(pt_Continuation *op, PRInt16 revents)
+{
+    struct iovec *hdtrl = (struct iovec *) op->arg2.buffer;
+    int count;
+
+    count = sendfile(op->arg1.osfd, op->filedesc, op->arg3.file_spec.offset,
+			op->arg3.file_spec.nbytes, hdtrl, op->arg4.flags);
+    PR_ASSERT(count <= op->nbytes_to_send);
+    op->syserrno = errno;
+
+    if (count != -1) {
+        op->result.code += count;
+    } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {
+        op->result.code = -1;
+    } else {
+        return PR_FALSE;
+    }
+    if (count != -1 && count < op->nbytes_to_send) {
+        if (count < hdtrl[0].iov_len) {
+			/* header not sent */
+
+            hdtrl[0].iov_base = ((char *) hdtrl[0].iov_base) + count;
+            hdtrl[0].iov_len -= count;
+
+        } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes)) {
+			/* header sent, file not sent */
+            PRUint32 file_nbytes_sent = count - hdtrl[0].iov_len;
+
+            hdtrl[0].iov_base = NULL;
+            hdtrl[0].iov_len = 0;
+
+            op->arg3.file_spec.offset += file_nbytes_sent;
+            op->arg3.file_spec.nbytes -= file_nbytes_sent;
+        } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes +
+											hdtrl[1].iov_len)) {
+            PRUint32 trailer_nbytes_sent = count - (hdtrl[0].iov_len +
+                                         op->arg3.file_spec.nbytes);
+
+			/* header sent, file sent, trailer not sent */
+
+            hdtrl[0].iov_base = NULL;
+            hdtrl[0].iov_len = 0;
+			/*
+			 * set file offset and len so that no more file data is
+			 * sent
+			 */
+            op->arg3.file_spec.offset = op->arg3.file_spec.st_size;
+            op->arg3.file_spec.nbytes = 0;
+
+            hdtrl[1].iov_base =((char *) hdtrl[1].iov_base)+ trailer_nbytes_sent;
+            hdtrl[1].iov_len -= trailer_nbytes_sent;
+		}
+        op->nbytes_to_send -= count;
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+#endif  /* HPUX11 */
+
+#ifdef SOLARIS  
+static PRBool pt_solaris_sendfile_cont(pt_Continuation *op, PRInt16 revents)
+{
+    struct sendfilevec *vec = (struct sendfilevec *) op->arg2.buffer;
+    size_t xferred;
+    ssize_t count;
+
+    count = SOLARIS_SENDFILEV(op->arg1.osfd, vec, op->arg3.amount, &xferred);
+    op->syserrno = errno;
+    PR_ASSERT((count == -1) || (count == xferred));
+
+    if (count == -1) {
+        if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN
+                && op->syserrno != EINTR) {
+            op->result.code = -1;
+            return PR_TRUE;
+        }
+        count = xferred;
+    } else if (count == 0) {
+        /* 
+         * We are now at EOF. The file was truncated. Solaris sendfile is
+         * supposed to return 0 and no error in this case, though some versions
+         * may return -1 and EINVAL .
+         */
+        op->result.code = -1;
+        op->syserrno = 0; /* will be treated as EOF */
+        return PR_TRUE;
+    }
+    PR_ASSERT(count <= op->nbytes_to_send);
+    
+    op->result.code += count;
+    if (count < op->nbytes_to_send) {
+        op->nbytes_to_send -= count;
+
+        while (count >= vec->sfv_len) {
+            count -= vec->sfv_len;
+            vec++;
+            op->arg3.amount--;
+        }
+        PR_ASSERT(op->arg3.amount > 0);
+
+        vec->sfv_off += count;
+        vec->sfv_len -= count;
+        PR_ASSERT(vec->sfv_len > 0);
+        op->arg2.buffer = vec;
+
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+#endif  /* SOLARIS */
+
+#ifdef LINUX 
+static PRBool pt_linux_sendfile_cont(pt_Continuation *op, PRInt16 revents)
+{
+    ssize_t rv;
+    off_t oldoffset;
+
+    oldoffset = op->offset;
+    rv = sendfile(op->arg1.osfd, op->in_fd, &op->offset, op->count);
+    op->syserrno = errno;
+
+    if (rv == -1) {
+        if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {
+            op->result.code = -1;
+            return PR_TRUE;
+        }
+        rv = 0;
+    }
+    PR_ASSERT(rv == op->offset - oldoffset);
+    op->result.code += rv;
+    if (rv < op->count) {
+        op->count -= rv;
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+#endif  /* LINUX */
+
+void _PR_InitIO(void)
+{
+#if defined(DEBUG)
+    memset(&pt_debug, 0, sizeof(PTDebug));
+    pt_debug.timeStarted = PR_Now();
+#endif
+
+    _pr_flock_lock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_flock_lock);
+    _pr_flock_cv = PR_NewCondVar(_pr_flock_lock);
+    PR_ASSERT(NULL != _pr_flock_cv);
+    _pr_rename_lock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_rename_lock); 
+
+    _PR_InitFdCache();  /* do that */   
+
+    _pr_stdin = pt_SetMethods(0, PR_DESC_FILE, PR_FALSE, PR_TRUE);
+    _pr_stdout = pt_SetMethods(1, PR_DESC_FILE, PR_FALSE, PR_TRUE);
+    _pr_stderr = pt_SetMethods(2, PR_DESC_FILE, PR_FALSE, PR_TRUE);
+    PR_ASSERT(_pr_stdin && _pr_stdout && _pr_stderr);
+
+#ifdef _PR_IPV6_V6ONLY_PROBE
+    /* In Mac OS X v10.3 Panther Beta the IPV6_V6ONLY socket option
+     * is turned on by default, contrary to what RFC 3493, Section
+     * 5.3 says.  So we have to turn it off.  Find out whether we
+     * are running on such a system.
+     */
+    {
+        int osfd;
+        osfd = socket(AF_INET6, SOCK_STREAM, 0);
+        if (osfd != -1) {
+            int on;
+            int optlen = sizeof(on);
+            if (getsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY,
+                    &on, &optlen) == 0) {
+                _pr_ipv6_v6only_on_by_default = on;
+            }
+            close(osfd);
+        }
+    }
+#endif
+}  /* _PR_InitIO */
+
+void _PR_CleanupIO(void)
+{
+    _PR_Putfd(_pr_stdin);
+    _pr_stdin = NULL;
+    _PR_Putfd(_pr_stdout);
+    _pr_stdout = NULL;
+    _PR_Putfd(_pr_stderr); 
+    _pr_stderr = NULL;
+
+    _PR_CleanupFdCache();
+    
+    if (_pr_flock_cv)
+    {
+        PR_DestroyCondVar(_pr_flock_cv);
+        _pr_flock_cv = NULL;
+    }
+    if (_pr_flock_lock)
+    {
+        PR_DestroyLock(_pr_flock_lock);
+        _pr_flock_lock = NULL;
+    }
+    if (_pr_rename_lock)
+    {
+        PR_DestroyLock(_pr_rename_lock);
+        _pr_rename_lock = NULL;
+    }
+}  /* _PR_CleanupIO */
+
+PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
+{
+    PRFileDesc *result = NULL;
+    PR_ASSERT(osfd >= PR_StandardInput && osfd <= PR_StandardError);
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    
+    switch (osfd)
+    {
+        case PR_StandardInput: result = _pr_stdin; break;
+        case PR_StandardOutput: result = _pr_stdout; break;
+        case PR_StandardError: result = _pr_stderr; break;
+        default:
+            (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    }
+    return result;
+}  /* PR_GetSpecialFD */
+
+/*****************************************************************************/
+/***************************** I/O private methods ***************************/
+/*****************************************************************************/
+
+static PRBool pt_TestAbort(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    if(_PT_THREAD_INTERRUPTED(me))
+    {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        me->state &= ~PT_THREAD_ABORTED;
+        return PR_TRUE;
+    }
+    return PR_FALSE;
+}  /* pt_TestAbort */
+
+static void pt_MapError(void (*mapper)(PRIntn), PRIntn syserrno)
+{
+    switch (syserrno)
+    {
+        case EINTR:
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); break;
+        case ETIMEDOUT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0); break;
+        default:
+            mapper(syserrno);
+    }
+}  /* pt_MapError */
+
+static PRStatus pt_Close(PRFileDesc *fd)
+{
+    if ((NULL == fd) || (NULL == fd->secret)
+        || ((_PR_FILEDESC_OPEN != fd->secret->state)
+        && (_PR_FILEDESC_CLOSED != fd->secret->state)))
+    {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    if (_PR_FILEDESC_OPEN == fd->secret->state)
+    {
+        if (-1 == close(fd->secret->md.osfd))
+        {
+#ifdef OSF1
+            /*
+             * Bug 86941: On Tru64 UNIX V5.0A and V5.1, the close()
+             * system call, when called to close a TCP socket, may
+             * return -1 with errno set to EINVAL but the system call
+             * does close the socket successfully.  An application
+             * may safely ignore the EINVAL error.  This bug is fixed
+             * on Tru64 UNIX V5.1A and later.  The defect tracking
+             * number is QAR 81431.
+             */
+            if (PR_DESC_SOCKET_TCP != fd->methods->file_type
+            || EINVAL != errno)
+            {
+                pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno);
+                return PR_FAILURE;
+            }
+#else
+            pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno);
+            return PR_FAILURE;
+#endif
+        }
+        fd->secret->state = _PR_FILEDESC_CLOSED;
+    }
+    _PR_Putfd(fd);
+    return PR_SUCCESS;
+}  /* pt_Close */
+
+static PRInt32 pt_Read(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    PRInt32 syserrno, bytes = -1;
+
+    if (pt_TestAbort()) return bytes;
+
+    bytes = read(fd->secret->md.osfd, buf, amount);
+    syserrno = errno;
+
+    if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking))
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = buf;
+        op.arg3.amount = amount;
+        op.timeout = PR_INTERVAL_NO_TIMEOUT;
+        op.function = pt_read_cont;
+        op.event = POLLIN | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes < 0)
+        pt_MapError(_PR_MD_MAP_READ_ERROR, syserrno);
+    return bytes;
+}  /* pt_Read */
+
+static PRInt32 pt_Write(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    PRInt32 syserrno, bytes = -1;
+    PRBool fNeedContinue = PR_FALSE;
+
+    if (pt_TestAbort()) return bytes;
+
+    bytes = write(fd->secret->md.osfd, buf, amount);
+    syserrno = errno;
+
+    if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) )
+    {
+        buf = (char *) buf + bytes;
+        amount -= bytes;
+        fNeedContinue = PR_TRUE;
+    }
+    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking) )
+    {
+        bytes = 0;
+        fNeedContinue = PR_TRUE;
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = (void*)buf;
+        op.arg3.amount = amount;
+        op.timeout = PR_INTERVAL_NO_TIMEOUT;
+        op.result.code = bytes;  /* initialize the number sent */
+        op.function = pt_write_cont;
+        op.event = POLLOUT | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes == -1)
+        pt_MapError(_PR_MD_MAP_WRITE_ERROR, syserrno);
+    return bytes;
+}  /* pt_Write */
+
+static PRInt32 pt_Writev(
+    PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_len, PRIntervalTime timeout)
+{
+    PRIntn iov_index;
+    PRBool fNeedContinue = PR_FALSE;
+    PRInt32 syserrno, bytes, rv = -1;
+    struct iovec osiov_local[PR_MAX_IOVECTOR_SIZE], *osiov;
+    int osiov_len;
+
+    if (pt_TestAbort()) return rv;
+
+    /* Ensured by PR_Writev */
+    PR_ASSERT(iov_len <= PR_MAX_IOVECTOR_SIZE);
+
+    /*
+     * We can't pass iov to writev because PRIOVec and struct iovec
+     * may not be binary compatible.  Make osiov a copy of iov and
+     * pass osiov to writev.  We can modify osiov if we need to
+     * continue the operation.
+     */
+    osiov = osiov_local;
+    osiov_len = iov_len;
+    for (iov_index = 0; iov_index < osiov_len; iov_index++)
+    {
+        osiov[iov_index].iov_base = iov[iov_index].iov_base;
+        osiov[iov_index].iov_len = iov[iov_index].iov_len;
+    }
+
+    rv = bytes = writev(fd->secret->md.osfd, osiov, osiov_len);
+    syserrno = errno;
+
+    if (!fd->secret->nonblocking)
+    {
+        if (bytes >= 0)
+        {
+            /*
+             * If we moved some bytes, how does that implicate the
+             * i/o vector list?  In other words, exactly where are
+             * we within that array?  What are the parameters for
+             * resumption?  Maybe we're done!
+             */
+            for ( ;osiov_len > 0; osiov++, osiov_len--)
+            {
+                if (bytes < osiov->iov_len)
+                {
+                    /* this one's not done yet */
+                    osiov->iov_base = (char*)osiov->iov_base + bytes;
+                    osiov->iov_len -= bytes;
+                    break;  /* go off and do that */
+                }
+                bytes -= osiov->iov_len;  /* this one's done cooked */
+            }
+            PR_ASSERT(osiov_len > 0 || bytes == 0);
+            if (osiov_len > 0)
+            {
+                if (PR_INTERVAL_NO_WAIT == timeout)
+                {
+                    rv = -1;
+                    syserrno = ETIMEDOUT;
+                }
+                else fNeedContinue = PR_TRUE;
+            }
+        }
+        else if (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        {
+            if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+            else
+            {
+                rv = 0;
+                fNeedContinue = PR_TRUE;
+            }
+        }
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = (void*)osiov;
+        op.arg3.amount = osiov_len;
+        op.timeout = timeout;
+        op.result.code = rv;
+        op.function = pt_writev_cont;
+        op.event = POLLOUT | POLLPRI;
+        rv = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (rv == -1) pt_MapError(_PR_MD_MAP_WRITEV_ERROR, syserrno);
+    return rv;
+}  /* pt_Writev */
+
+static PRInt32 pt_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
+{
+    return _PR_MD_LSEEK(fd, offset, whence);
+}  /* pt_Seek */
+
+static PRInt64 pt_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
+{
+    return _PR_MD_LSEEK64(fd, offset, whence);
+}  /* pt_Seek64 */
+
+static PRInt32 pt_Available_f(PRFileDesc *fd)
+{
+    PRInt32 result, cur, end;
+
+    cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);
+
+    if (cur >= 0)
+        end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
+
+    if ((cur < 0) || (end < 0)) {
+        return -1;
+    }
+
+    result = end - cur;
+    _PR_MD_LSEEK(fd, cur, PR_SEEK_SET);
+
+    return result;
+}  /* pt_Available_f */
+
+static PRInt64 pt_Available64_f(PRFileDesc *fd)
+{
+    PRInt64 result, cur, end;
+    PRInt64 minus_one;
+
+    LL_I2L(minus_one, -1);
+    cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);
+
+    if (LL_GE_ZERO(cur))
+        end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
+
+    if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;
+
+    LL_SUB(result, end, cur);
+    (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);
+
+    return result;
+}  /* pt_Available64_f */
+
+static PRInt32 pt_Available_s(PRFileDesc *fd)
+{
+    PRInt32 rv, bytes = -1;
+    if (pt_TestAbort()) return bytes;
+
+    rv = ioctl(fd->secret->md.osfd, FIONREAD, &bytes);
+
+    if (rv == -1)
+        pt_MapError(_PR_MD_MAP_SOCKETAVAILABLE_ERROR, errno);
+    return bytes;
+}  /* pt_Available_s */
+
+static PRInt64 pt_Available64_s(PRFileDesc *fd)
+{
+    PRInt64 rv;
+    LL_I2L(rv, pt_Available_s(fd));
+    return rv;
+}  /* pt_Available64_s */
+
+static PRStatus pt_FileInfo(PRFileDesc *fd, PRFileInfo *info)
+{
+    PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, info);
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* pt_FileInfo */
+
+static PRStatus pt_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
+{
+    PRInt32 rv = _PR_MD_GETOPENFILEINFO64(fd, info);
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* pt_FileInfo64 */
+
+static PRStatus pt_Synch(PRFileDesc *fd)
+{
+    return (NULL == fd) ? PR_FAILURE : PR_SUCCESS;
+} /* pt_Synch */
+
+static PRStatus pt_Fsync(PRFileDesc *fd)
+{
+    PRIntn rv = -1;
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = fsync(fd->secret->md.osfd);
+    if (rv < 0) {
+        pt_MapError(_PR_MD_MAP_FSYNC_ERROR, errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Fsync */
+
+static PRStatus pt_Connect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRIntn rv = -1, syserrno;
+    pt_SockLen addr_len;
+	const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+	PRUint16 md_af = addr->raw.family;
+    PRNetAddr addrCopy;
+#endif
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+    addr_len = PR_NETADDR_SIZE(addr);
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		md_af = AF_INET6;
+#ifndef _PR_HAVE_SOCKADDR_LEN
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+#endif
+	}
+#endif
+
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    addrCopy = *addr;
+    ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
+    ((struct sockaddr*)&addrCopy)->sa_family = md_af;
+    addrp = &addrCopy;
+#endif
+    rv = connect(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);
+    syserrno = errno;
+    if ((-1 == rv) && (EINPROGRESS == syserrno) && (!fd->secret->nonblocking))
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else
+        {
+            pt_Continuation op;
+            op.arg1.osfd = fd->secret->md.osfd;
+            op.arg2.buffer = (void*)addrp;
+            op.arg3.amount = addr_len;
+            op.timeout = timeout;
+            op.function = pt_connect_cont;
+            op.event = POLLOUT | POLLPRI;
+            rv = pt_Continue(&op);
+            syserrno = op.syserrno;
+        }
+    }
+    if (-1 == rv) {
+        pt_MapError(_PR_MD_MAP_CONNECT_ERROR, syserrno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Connect */
+
+static PRStatus pt_ConnectContinue(
+    PRFileDesc *fd, PRInt16 out_flags)
+{
+    int err;
+    PRInt32 osfd;
+
+    if (out_flags & PR_POLL_NVAL)
+    {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0)
+    {
+        PR_ASSERT(out_flags == 0);
+        PR_SetError(PR_IN_PROGRESS_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    osfd = fd->secret->md.osfd;
+
+    err = _MD_unix_get_nonblocking_connect_error(osfd);
+    if (err != 0)
+    {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_ConnectContinue */
+
+PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
+{
+    /* Find the NSPR layer and invoke its connectcontinue method */
+    PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+
+    if (NULL == bottom)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    return pt_ConnectContinue(bottom, pd->out_flags);
+}  /* PR_GetConnectStatus */
+
+static PRFileDesc* pt_Accept(
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRFileDesc *newfd = NULL;
+    PRIntn syserrno, osfd = -1;
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+#ifdef SYMBIAN
+    PRNetAddr dummy_addr;
+#endif
+
+    if (pt_TestAbort()) return newfd;
+
+#ifdef SYMBIAN
+    /* On Symbian OS, accept crashes if addr is NULL. */
+    if (!addr)
+        addr = &dummy_addr;
+#endif
+
+#ifdef _PR_STRICT_ADDR_LEN
+    if (addr)
+    {
+        /*
+         * Set addr->raw.family just so that we can use the
+         * PR_NETADDR_SIZE macro.
+         */
+        addr->raw.family = fd->secret->af;
+        addr_len = PR_NETADDR_SIZE(addr);
+    }
+#endif
+
+    osfd = accept(fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
+    syserrno = errno;
+
+    if (osfd == -1)
+    {
+        if (fd->secret->nonblocking) goto failed;
+
+        if (EWOULDBLOCK != syserrno && EAGAIN != syserrno
+        && ECONNABORTED != syserrno)
+            goto failed;
+        else
+        {
+            if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+            else
+            {
+                pt_Continuation op;
+                op.arg1.osfd = fd->secret->md.osfd;
+                op.arg2.buffer = addr;
+                op.arg3.addr_len = &addr_len;
+                op.timeout = timeout;
+                op.function = pt_accept_cont;
+                op.event = POLLIN | POLLPRI;
+                osfd = pt_Continue(&op);
+                syserrno = op.syserrno;
+            }
+            if (osfd < 0) goto failed;
+        }
+    }
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    /* ignore the sa_len field of struct sockaddr */
+    if (addr)
+    {
+        addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
+    newfd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_TRUE, PR_FALSE);
+    if (newfd == NULL) close(osfd);  /* $$$ whoops! this doesn't work $$$ */
+    else
+    {
+        PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+        PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
+#ifdef LINUX
+        /*
+         * On Linux, experiments showed that the accepted sockets
+         * inherit the TCP_NODELAY socket option of the listening
+         * socket.
+         */
+        newfd->secret->md.tcp_nodelay = fd->secret->md.tcp_nodelay;
+#endif
+    }
+    return newfd;
+
+failed:
+    pt_MapError(_PR_MD_MAP_ACCEPT_ERROR, syserrno);
+    return NULL;
+}  /* pt_Accept */
+
+static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
+{
+    PRIntn rv;
+    pt_SockLen addr_len;
+	const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+	PRUint16 md_af = addr->raw.family;
+    PRNetAddr addrCopy;
+#endif
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+    if (addr->raw.family == AF_UNIX)
+    {
+        /* Disallow relative pathnames */
+        if (addr->local.path[0] != '/')
+        {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return PR_FAILURE;
+        }
+    }
+
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		md_af = AF_INET6;
+#ifndef _PR_HAVE_SOCKADDR_LEN
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+#endif
+	}
+#endif
+
+    addr_len = PR_NETADDR_SIZE(addr);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    addrCopy = *addr;
+    ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
+    ((struct sockaddr*)&addrCopy)->sa_family = md_af;
+    addrp = &addrCopy;
+#endif
+    rv = bind(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);
+
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_BIND_ERROR, errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Bind */
+
+static PRStatus pt_Listen(PRFileDesc *fd, PRIntn backlog)
+{
+    PRIntn rv;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = listen(fd->secret->md.osfd, backlog);
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_LISTEN_ERROR, errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Listen */
+
+static PRStatus pt_Shutdown(PRFileDesc *fd, PRIntn how)
+{
+    PRIntn rv = -1;
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_SHUTDOWN_ERROR, errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Shutdown */
+
+static PRInt16 pt_Poll(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    *out_flags = 0;
+    return in_flags;
+}  /* pt_Poll */
+
+static PRInt32 pt_Recv(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    PRInt32 syserrno, bytes = -1;
+    PRIntn osflags;
+
+    if (0 == flags)
+        osflags = 0;
+    else if (PR_MSG_PEEK == flags)
+    {
+#ifdef SYMBIAN
+        /* MSG_PEEK doesn't work as expected. */
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        return bytes;
+#else
+        osflags = MSG_PEEK;
+#endif
+    }
+    else
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return bytes;
+    }
+
+    if (pt_TestAbort()) return bytes;
+
+    /* recv() is a much slower call on pre-2.6 Solaris than read(). */
+#if defined(SOLARIS)
+    if (0 == osflags)
+        bytes = read(fd->secret->md.osfd, buf, amount);
+    else
+        bytes = recv(fd->secret->md.osfd, buf, amount, osflags);
+#else
+    bytes = recv(fd->secret->md.osfd, buf, amount, osflags);
+#endif
+    syserrno = errno;
+
+    if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking))
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else
+        {
+            pt_Continuation op;
+            op.arg1.osfd = fd->secret->md.osfd;
+            op.arg2.buffer = buf;
+            op.arg3.amount = amount;
+            op.arg4.flags = osflags;
+            op.timeout = timeout;
+            op.function = pt_recv_cont;
+            op.event = POLLIN | POLLPRI;
+            bytes = pt_Continue(&op);
+            syserrno = op.syserrno;
+        }
+    }
+    if (bytes < 0)
+        pt_MapError(_PR_MD_MAP_RECV_ERROR, syserrno);
+    return bytes;
+}  /* pt_Recv */
+
+static PRInt32 pt_SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    return pt_Recv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}  /* pt_SocketRead */
+
+static PRInt32 pt_Send(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    PRInt32 syserrno, bytes = -1;
+    PRBool fNeedContinue = PR_FALSE;
+#if defined(SOLARIS)
+	PRInt32 tmp_amount = amount;
+#endif
+
+    /*
+     * Under HP-UX DCE threads, pthread.h includes dce/cma_ux.h,
+     * which has the following:
+     *     #  define send        cma_send
+     *     extern int  cma_send (int , void *, int, int );
+     * So we need to cast away the 'const' of argument #2 for send().
+     */
+#if defined (HPUX) && defined(_PR_DCETHREADS)
+#define PT_SENDBUF_CAST (void *)
+#else
+#define PT_SENDBUF_CAST
+#endif
+
+    if (pt_TestAbort()) return bytes;
+
+    /*
+     * On pre-2.6 Solaris, send() is much slower than write().
+     * On 2.6 and beyond, with in-kernel sockets, send() and
+     * write() are fairly equivalent in performance.
+     */
+#if defined(SOLARIS)
+    PR_ASSERT(0 == flags);
+retry:
+    bytes = write(fd->secret->md.osfd, PT_SENDBUF_CAST buf, tmp_amount);
+#else
+    bytes = send(fd->secret->md.osfd, PT_SENDBUF_CAST buf, amount, flags);
+#endif
+    syserrno = errno;
+
+#if defined(SOLARIS)
+    /*
+     * The write system call has been reported to return the ERANGE error
+     * on occasion. Try to write in smaller chunks to workaround this bug.
+     */
+    if ((bytes == -1) && (syserrno == ERANGE))
+    {
+        if (tmp_amount > 1)
+        {
+            tmp_amount = tmp_amount/2;  /* half the bytes */
+            goto retry;
+        }
+    }
+#endif
+
+    if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) )
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout)
+        {
+            bytes = -1;
+            syserrno = ETIMEDOUT;
+        }
+        else
+        {
+            buf = (char *) buf + bytes;
+            amount -= bytes;
+            fNeedContinue = PR_TRUE;
+        }
+    }
+    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking) )
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else
+        {
+            bytes = 0;
+            fNeedContinue = PR_TRUE;
+        }
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = (void*)buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.timeout = timeout;
+        op.result.code = bytes;  /* initialize the number sent */
+        op.function = pt_send_cont;
+        op.event = POLLOUT | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes == -1)
+        pt_MapError(_PR_MD_MAP_SEND_ERROR, syserrno);
+    return bytes;
+}  /* pt_Send */
+
+static PRInt32 pt_SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    return pt_Send(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}  /* pt_SocketWrite */
+
+static PRInt32 pt_SendTo(
+    PRFileDesc *fd, const void *buf,
+    PRInt32 amount, PRIntn flags, const PRNetAddr *addr,
+    PRIntervalTime timeout)
+{
+    PRInt32 syserrno, bytes = -1;
+    PRBool fNeedContinue = PR_FALSE;
+    pt_SockLen addr_len;
+	const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+	PRUint16 md_af = addr->raw.family;
+    PRNetAddr addrCopy;
+#endif
+
+    if (pt_TestAbort()) return bytes;
+
+    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		md_af = AF_INET6;
+#ifndef _PR_HAVE_SOCKADDR_LEN
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+#endif
+	}
+#endif
+
+    addr_len = PR_NETADDR_SIZE(addr);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    addrCopy = *addr;
+    ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
+    ((struct sockaddr*)&addrCopy)->sa_family = md_af;
+    addrp = &addrCopy;
+#endif
+    bytes = sendto(
+        fd->secret->md.osfd, buf, amount, flags,
+        (struct sockaddr*)addrp, addr_len);
+    syserrno = errno;
+    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking) )
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else fNeedContinue = PR_TRUE;
+    }
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = (void*)buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.arg5.addr = (PRNetAddr*)addrp;
+        op.timeout = timeout;
+        op.result.code = 0;  /* initialize the number sent */
+        op.function = pt_sendto_cont;
+        op.event = POLLOUT | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes < 0)
+        pt_MapError(_PR_MD_MAP_SENDTO_ERROR, syserrno);
+    return bytes;
+}  /* pt_SendTo */
+
+static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRBool fNeedContinue = PR_FALSE;
+    PRInt32 syserrno, bytes = -1;
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+
+    if (pt_TestAbort()) return bytes;
+
+    bytes = recvfrom(
+        fd->secret->md.osfd, buf, amount, flags,
+        (struct sockaddr*)addr, &addr_len);
+    syserrno = errno;
+
+    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking) )
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else fNeedContinue = PR_TRUE;
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.arg5.addr = addr;
+        op.timeout = timeout;
+        op.function = pt_recvfrom_cont;
+        op.event = POLLIN | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes >= 0)
+    {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr)
+        {
+            addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+        }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+#ifdef _PR_INET6
+        if (addr && (AF_INET6 == addr->raw.family))
+            addr->raw.family = PR_AF_INET6;
+#endif
+    }
+    else
+        pt_MapError(_PR_MD_MAP_RECVFROM_ERROR, syserrno);
+    return bytes;
+}  /* pt_RecvFrom */
+
+#ifdef AIX
+#ifndef HAVE_SEND_FILE
+static pthread_once_t pt_aix_sendfile_once_block = PTHREAD_ONCE_INIT;
+
+static void pt_aix_sendfile_init_routine(void)
+{
+    void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
+    pt_aix_sendfile_fptr = (ssize_t (*)()) dlsym(handle, "send_file");
+    dlclose(handle);
+}
+
+/* 
+ * pt_AIXDispatchSendFile
+ */
+static PRInt32 pt_AIXDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+	  PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    int rv;
+
+    rv = pthread_once(&pt_aix_sendfile_once_block,
+            pt_aix_sendfile_init_routine);
+    PR_ASSERT(0 == rv);
+    if (pt_aix_sendfile_fptr) {
+        return pt_AIXSendFile(sd, sfd, flags, timeout);
+    } else {
+        return PR_EmulateSendFile(sd, sfd, flags, timeout);
+    }
+}
+#endif /* !HAVE_SEND_FILE */
+
+
+/*
+ * pt_AIXSendFile
+ *
+ *    Send file sfd->fd across socket sd. If specified, header and trailer
+ *    buffers are sent before and after the file, respectively. 
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *    
+ *    return number of bytes sent or -1 on error
+ *
+ *      This implementation takes advantage of the send_file() system
+ *      call available in AIX 4.3.2.
+ */
+
+static PRInt32 pt_AIXSendFile(PRFileDesc *sd, PRSendFileData *sfd, 
+		PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    struct sf_parms sf_struct;
+    uint_t send_flags;
+    ssize_t rv;
+    int syserrno;
+    PRInt32 count;
+	unsigned long long saved_file_offset;
+	long long saved_file_bytes;
+
+    sf_struct.header_data = (void *) sfd->header;  /* cast away the 'const' */
+    sf_struct.header_length = sfd->hlen;
+    sf_struct.file_descriptor = sfd->fd->secret->md.osfd;
+    sf_struct.file_size = 0;
+    sf_struct.file_offset = sfd->file_offset;
+    if (sfd->file_nbytes == 0)
+    	sf_struct.file_bytes = -1;
+	else
+    	sf_struct.file_bytes = sfd->file_nbytes;
+    sf_struct.trailer_data = (void *) sfd->trailer;
+    sf_struct.trailer_length = sfd->tlen;
+    sf_struct.bytes_sent = 0;
+
+	saved_file_offset = sf_struct.file_offset;
+    saved_file_bytes = sf_struct.file_bytes;
+
+    send_flags = 0;			/* flags processed at the end */
+
+    /* The first argument to send_file() is int*. */
+    PR_ASSERT(sizeof(int) == sizeof(sd->secret->md.osfd));
+    do {
+        rv = AIX_SEND_FILE(&sd->secret->md.osfd, &sf_struct, send_flags);
+    } while (rv == -1 && (syserrno = errno) == EINTR);
+
+    if (rv == -1) {
+        if (syserrno == EAGAIN || syserrno == EWOULDBLOCK) {
+            count = 0; /* Not a real error.  Need to continue. */
+        } else {
+            count = -1;
+        }
+    } else {
+        count = sf_struct.bytes_sent;
+		/*
+		 * A bug in AIX 4.3.2 prevents the 'file_bytes' field from
+		 * being updated. So, 'file_bytes' is maintained by NSPR to
+		 * avoid conflict when this bug is fixed in AIX, in the future.
+		 */
+		if (saved_file_bytes != -1)
+			saved_file_bytes -= (sf_struct.file_offset - saved_file_offset);
+		sf_struct.file_bytes = saved_file_bytes;
+    }
+
+    if ((rv == 1) || ((rv == -1) && (count == 0))) {
+        pt_Continuation op;
+
+        op.arg1.osfd = sd->secret->md.osfd;
+        op.arg2.buffer = &sf_struct;
+        op.arg4.flags = send_flags;
+        op.result.code = count;
+        op.timeout = timeout;
+        op.function = pt_aix_sendfile_cont;
+        op.event = POLLOUT | POLLPRI;
+        count = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+
+    if (count == -1) {
+        pt_MapError(_MD_aix_map_sendfile_error, syserrno);
+        return -1;
+    }
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+        PR_Close(sd);
+    }
+	PR_ASSERT(count == (sfd->hlen + sfd->tlen +
+						((sfd->file_nbytes ==  0) ?
+						sf_struct.file_size - sfd->file_offset :
+						sfd->file_nbytes)));
+    return count;
+}
+#endif /* AIX */
+
+#ifdef HPUX11
+/*
+ * pt_HPUXSendFile
+ *
+ *    Send file sfd->fd across socket sd. If specified, header and trailer
+ *    buffers are sent before and after the file, respectively.
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *    
+ *    return number of bytes sent or -1 on error
+ *
+ *      This implementation takes advantage of the sendfile() system
+ *      call available in HP-UX B.11.00.
+ */
+
+static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd, 
+		PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    struct stat statbuf;
+    size_t nbytes_to_send, file_nbytes_to_send;
+    struct iovec hdtrl[2];  /* optional header and trailer buffers */
+    int send_flags;
+    PRInt32 count;
+    int syserrno;
+
+    if (sfd->file_nbytes == 0) {
+        /* Get file size */
+        if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) {
+            _PR_MD_MAP_FSTAT_ERROR(errno);
+            return -1;
+        } 		
+        file_nbytes_to_send = statbuf.st_size - sfd->file_offset;
+    } else {
+        file_nbytes_to_send = sfd->file_nbytes;
+    }
+    nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send;
+
+    hdtrl[0].iov_base = (void *) sfd->header;  /* cast away the 'const' */
+    hdtrl[0].iov_len = sfd->hlen;
+    hdtrl[1].iov_base = (void *) sfd->trailer;
+    hdtrl[1].iov_len = sfd->tlen;
+    /*
+     * SF_DISCONNECT seems to close the socket even if sendfile()
+     * only does a partial send on a nonblocking socket.  This
+     * would prevent the subsequent sendfile() calls on that socket
+     * from working.  So we don't use the SD_DISCONNECT flag.
+     */
+    send_flags = 0;
+
+    do {
+        count = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd,
+                sfd->file_offset, file_nbytes_to_send, hdtrl, send_flags);
+    } while (count == -1 && (syserrno = errno) == EINTR);
+
+    if (count == -1 && (syserrno == EAGAIN || syserrno == EWOULDBLOCK)) {
+        count = 0;
+    }
+    if (count != -1 && count < nbytes_to_send) {
+        pt_Continuation op;
+
+        if (count < sfd->hlen) {
+			/* header not sent */
+
+            hdtrl[0].iov_base = ((char *) sfd->header) + count;
+            hdtrl[0].iov_len = sfd->hlen - count;
+            op.arg3.file_spec.offset = sfd->file_offset;
+            op.arg3.file_spec.nbytes = file_nbytes_to_send;
+        } else if (count < (sfd->hlen + file_nbytes_to_send)) {
+			/* header sent, file not sent */
+
+            hdtrl[0].iov_base = NULL;
+            hdtrl[0].iov_len = 0;
+
+            op.arg3.file_spec.offset = sfd->file_offset + count - sfd->hlen;
+            op.arg3.file_spec.nbytes = file_nbytes_to_send - (count - sfd->hlen);
+        } else if (count < (sfd->hlen + file_nbytes_to_send + sfd->tlen)) {
+			PRUint32 trailer_nbytes_sent;
+
+			/* header sent, file sent, trailer not sent */
+
+            hdtrl[0].iov_base = NULL;
+            hdtrl[0].iov_len = 0;
+			/*
+			 * set file offset and len so that no more file data is
+			 * sent
+			 */
+            op.arg3.file_spec.offset = statbuf.st_size;
+            op.arg3.file_spec.nbytes = 0;
+
+			trailer_nbytes_sent = count - sfd->hlen - file_nbytes_to_send;
+            hdtrl[1].iov_base = ((char *) sfd->trailer) + trailer_nbytes_sent;
+            hdtrl[1].iov_len = sfd->tlen - trailer_nbytes_sent;
+		}
+
+        op.arg1.osfd = sd->secret->md.osfd;
+        op.filedesc = sfd->fd->secret->md.osfd;
+        op.arg2.buffer = hdtrl;
+        op.arg3.file_spec.st_size = statbuf.st_size;
+        op.arg4.flags = send_flags;
+        op.nbytes_to_send = nbytes_to_send - count;
+        op.result.code = count;
+        op.timeout = timeout;
+        op.function = pt_hpux_sendfile_cont;
+        op.event = POLLOUT | POLLPRI;
+        count = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+
+    if (count == -1) {
+        pt_MapError(_MD_hpux_map_sendfile_error, syserrno);
+        return -1;
+    }
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+        PR_Close(sd);
+    }
+    PR_ASSERT(count == nbytes_to_send);
+    return count;
+}
+
+#endif  /* HPUX11 */
+
+#ifdef SOLARIS 
+
+/*
+ *    pt_SolarisSendFile
+ *
+ *    Send file sfd->fd across socket sd. If specified, header and trailer
+ *    buffers are sent before and after the file, respectively.
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *
+ *    return number of bytes sent or -1 on error
+ *
+ *    This implementation takes advantage of the sendfilev() system
+ *    call available in Solaris 8.
+ */
+
+static PRInt32 pt_SolarisSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+                PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    struct stat statbuf;
+    size_t nbytes_to_send, file_nbytes_to_send;	
+    struct sendfilevec sfv_struct[3];  
+    int sfvcnt = 0;	
+    size_t xferred;
+    PRInt32 count;
+    int syserrno;
+
+    if (sfd->file_nbytes == 0) {
+        /* Get file size */
+        if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) {
+            _PR_MD_MAP_FSTAT_ERROR(errno);
+            return -1;
+        } 		
+        file_nbytes_to_send = statbuf.st_size - sfd->file_offset;
+    } else {
+        file_nbytes_to_send = sfd->file_nbytes;
+    }
+
+    nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send;
+
+    if (sfd->hlen != 0) {
+        sfv_struct[sfvcnt].sfv_fd = SFV_FD_SELF;
+        sfv_struct[sfvcnt].sfv_flag = 0;
+        sfv_struct[sfvcnt].sfv_off = (off_t) sfd->header; 
+        sfv_struct[sfvcnt].sfv_len = sfd->hlen;
+        sfvcnt++;
+    }
+
+    if (file_nbytes_to_send != 0) {
+        sfv_struct[sfvcnt].sfv_fd = sfd->fd->secret->md.osfd;
+        sfv_struct[sfvcnt].sfv_flag = 0;
+        sfv_struct[sfvcnt].sfv_off = sfd->file_offset;
+        sfv_struct[sfvcnt].sfv_len = file_nbytes_to_send;
+        sfvcnt++;
+    }
+
+    if (sfd->tlen != 0) {
+        sfv_struct[sfvcnt].sfv_fd = SFV_FD_SELF;
+        sfv_struct[sfvcnt].sfv_flag = 0;
+        sfv_struct[sfvcnt].sfv_off = (off_t) sfd->trailer; 
+        sfv_struct[sfvcnt].sfv_len = sfd->tlen;
+        sfvcnt++;
+    }
+
+    if (0 == sfvcnt) {
+        count = 0;
+        goto done;
+    }
+   	   
+    /*
+     * Strictly speaking, we may have sent some bytes when the
+     * sendfilev() is interrupted and we should retry it from an
+     * updated offset.  We are not doing that here.
+     */
+    count = SOLARIS_SENDFILEV(sd->secret->md.osfd, sfv_struct,
+            sfvcnt, &xferred);
+
+    PR_ASSERT((count == -1) || (count == xferred));
+
+    if (count == -1) {
+        syserrno = errno;
+        if (syserrno == EINTR
+                || syserrno == EAGAIN || syserrno == EWOULDBLOCK) {
+            count = xferred;
+        }
+    } else if (count == 0) {
+        /*
+         * We are now at EOF. The file was truncated. Solaris sendfile is
+         * supposed to return 0 and no error in this case, though some versions
+         * may return -1 and EINVAL .
+         */
+        count = -1;
+        syserrno = 0;  /* will be treated as EOF */
+    }
+
+    if (count != -1 && count < nbytes_to_send) {
+        pt_Continuation op;
+        struct sendfilevec *vec = sfv_struct;
+        PRInt32 rem = count;
+
+        while (rem >= vec->sfv_len) {
+            rem -= vec->sfv_len;
+            vec++;
+            sfvcnt--;
+        }
+        PR_ASSERT(sfvcnt > 0);
+
+        vec->sfv_off += rem;
+        vec->sfv_len -= rem;
+        PR_ASSERT(vec->sfv_len > 0);
+
+        op.arg1.osfd = sd->secret->md.osfd;
+        op.arg2.buffer = vec;
+        op.arg3.amount = sfvcnt;
+        op.arg4.flags = 0;
+        op.nbytes_to_send = nbytes_to_send - count;
+        op.result.code = count;
+        op.timeout = timeout;
+        op.function = pt_solaris_sendfile_cont;
+        op.event = POLLOUT | POLLPRI;
+        count = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+
+done:
+    if (count == -1) {
+        pt_MapError(_MD_solaris_map_sendfile_error, syserrno);
+        return -1;
+    }
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+        PR_Close(sd);
+    }
+    PR_ASSERT(count == nbytes_to_send);
+    return count;
+}
+
+#ifndef HAVE_SENDFILEV
+static pthread_once_t pt_solaris_sendfilev_once_block = PTHREAD_ONCE_INIT;
+
+static void pt_solaris_sendfilev_init_routine(void)
+{
+    void *handle;
+    PRBool close_it = PR_FALSE;
+ 
+    /*
+     * We do not want to unload libsendfile.so.  This handle is leaked
+     * intentionally.
+     */
+    handle = dlopen("libsendfile.so", RTLD_LAZY | RTLD_GLOBAL);
+    PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+        ("dlopen(libsendfile.so) returns %p", handle));
+
+    if (NULL == handle) {
+        /*
+         * The dlopen(0, mode) call is to allow for the possibility that
+         * sendfilev() may become part of a standard system library in a
+         * future Solaris release.
+         */
+        handle = dlopen(0, RTLD_LAZY | RTLD_GLOBAL);
+        PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+            ("dlopen(0) returns %p", handle));
+        close_it = PR_TRUE;
+    }
+    pt_solaris_sendfilev_fptr = (ssize_t (*)()) dlsym(handle, "sendfilev");
+    PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+        ("dlsym(sendfilev) returns %p", pt_solaris_sendfilev_fptr));
+    
+    if (close_it) {
+        dlclose(handle);
+    }
+}
+
+/* 
+ * pt_SolarisDispatchSendFile
+ */
+static PRInt32 pt_SolarisDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+	  PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    int rv;
+
+    rv = pthread_once(&pt_solaris_sendfilev_once_block,
+            pt_solaris_sendfilev_init_routine);
+    PR_ASSERT(0 == rv);
+    if (pt_solaris_sendfilev_fptr) {
+        return pt_SolarisSendFile(sd, sfd, flags, timeout);
+    } else {
+        return PR_EmulateSendFile(sd, sfd, flags, timeout);
+    }
+}
+#endif /* !HAVE_SENDFILEV */
+
+#endif  /* SOLARIS */
+
+#ifdef LINUX
+/*
+ * pt_LinuxSendFile
+ *
+ *    Send file sfd->fd across socket sd. If specified, header and trailer
+ *    buffers are sent before and after the file, respectively.
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *    
+ *    return number of bytes sent or -1 on error
+ *
+ *      This implementation takes advantage of the sendfile() system
+ *      call available in Linux kernel 2.2 or higher.
+ */
+
+static PRInt32 pt_LinuxSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+                PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    struct stat statbuf;
+    size_t file_nbytes_to_send;	
+    PRInt32 count = 0;
+    ssize_t rv;
+    int syserrno;
+    off_t offset;
+    PRBool tcp_cork_enabled = PR_FALSE;
+    int tcp_cork;
+
+    if (sfd->file_nbytes == 0) {
+        /* Get file size */
+        if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) {
+            _PR_MD_MAP_FSTAT_ERROR(errno);
+            return -1;
+        } 		
+        file_nbytes_to_send = statbuf.st_size - sfd->file_offset;
+    } else {
+        file_nbytes_to_send = sfd->file_nbytes;
+    }
+
+    if ((sfd->hlen != 0 || sfd->tlen != 0)
+            && sd->secret->md.tcp_nodelay == 0) {
+        tcp_cork = 1;
+        if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK,
+                &tcp_cork, sizeof tcp_cork) == 0) {
+            tcp_cork_enabled = PR_TRUE;
+        } else {
+            syserrno = errno;
+            if (syserrno != EINVAL) {
+                _PR_MD_MAP_SETSOCKOPT_ERROR(syserrno);
+                return -1;
+            }
+            /*
+             * The most likely reason for the EINVAL error is that
+             * TCP_NODELAY is set (with a function other than
+             * PR_SetSocketOption).  This is not fatal, so we keep
+             * on going.
+             */
+            PR_LOG(_pr_io_lm, PR_LOG_WARNING,
+                ("pt_LinuxSendFile: "
+                "setsockopt(TCP_CORK) failed with EINVAL\n"));
+        }
+    }
+
+    if (sfd->hlen != 0) {
+        count = PR_Send(sd, sfd->header, sfd->hlen, 0, timeout);
+        if (count == -1) {
+            goto failed;
+        }
+    }
+
+    if (file_nbytes_to_send != 0) {
+        offset = sfd->file_offset;
+        do {
+            rv = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd,
+                &offset, file_nbytes_to_send);
+        } while (rv == -1 && (syserrno = errno) == EINTR);
+        if (rv == -1) {
+            if (syserrno != EAGAIN && syserrno != EWOULDBLOCK) {
+                _MD_linux_map_sendfile_error(syserrno);
+                count = -1;
+                goto failed;
+            }
+            rv = 0;
+        }
+        PR_ASSERT(rv == offset - sfd->file_offset);
+        count += rv;
+
+        if (rv < file_nbytes_to_send) {
+            pt_Continuation op;
+
+            op.arg1.osfd = sd->secret->md.osfd;
+            op.in_fd = sfd->fd->secret->md.osfd;
+            op.offset = offset;
+            op.count = file_nbytes_to_send - rv;
+            op.result.code = count;
+            op.timeout = timeout;
+            op.function = pt_linux_sendfile_cont;
+            op.event = POLLOUT | POLLPRI;
+            count = pt_Continue(&op);
+            syserrno = op.syserrno;
+            if (count == -1) {
+                pt_MapError(_MD_linux_map_sendfile_error, syserrno);
+                goto failed;
+            }
+        }
+    }
+
+    if (sfd->tlen != 0) {
+        rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout);
+        if (rv == -1) {
+            count = -1;
+            goto failed;
+        }
+        count += rv;
+    }
+
+failed:
+    if (tcp_cork_enabled) {
+        tcp_cork = 0;
+        if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK,
+                &tcp_cork, sizeof tcp_cork) == -1 && count != -1) {
+            _PR_MD_MAP_SETSOCKOPT_ERROR(errno);
+            count = -1;
+        }
+    }
+    if (count != -1) {
+        if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+            PR_Close(sd);
+        }
+        PR_ASSERT(count == sfd->hlen + sfd->tlen + file_nbytes_to_send);
+    }
+    return count;
+}
+#endif  /* LINUX */
+
+#ifdef AIX
+extern	int _pr_aix_send_file_use_disabled;
+#endif
+
+static PRInt32 pt_SendFile(
+    PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    if (pt_TestAbort()) return -1;
+    /* The socket must be in blocking mode. */
+    if (sd->secret->nonblocking)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+#ifdef HPUX11
+    return(pt_HPUXSendFile(sd, sfd, flags, timeout));
+#elif defined(AIX)
+#ifdef HAVE_SEND_FILE
+	/*
+	 * A bug in AIX 4.3.2 results in corruption of data transferred by
+	 * send_file(); AIX patch PTF U463956 contains the fix.  A user can
+	 * disable the use of send_file function in NSPR, when this patch is
+	 * not installed on the system, by setting the envionment variable
+	 * NSPR_AIX_SEND_FILE_USE_DISABLED to 1.
+	 */
+	if (_pr_aix_send_file_use_disabled)
+		return(PR_EmulateSendFile(sd, sfd, flags, timeout));
+	else
+    	return(pt_AIXSendFile(sd, sfd, flags, timeout));
+#else
+	return(PR_EmulateSendFile(sd, sfd, flags, timeout));
+    /* return(pt_AIXDispatchSendFile(sd, sfd, flags, timeout));*/
+#endif /* HAVE_SEND_FILE */
+#elif defined(SOLARIS)
+#ifdef HAVE_SENDFILEV
+    	return(pt_SolarisSendFile(sd, sfd, flags, timeout));
+#else
+	return(pt_SolarisDispatchSendFile(sd, sfd, flags, timeout));
+#endif /* HAVE_SENDFILEV */
+#elif defined(LINUX)
+    	return(pt_LinuxSendFile(sd, sfd, flags, timeout));
+#else
+	return(PR_EmulateSendFile(sd, sfd, flags, timeout));
+#endif
+}
+
+static PRInt32 pt_TransmitFile(
+    PRFileDesc *sd, PRFileDesc *fd, const void *headers,
+    PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+	PRSendFileData sfd;
+
+	sfd.fd = fd;
+	sfd.file_offset = 0;
+	sfd.file_nbytes = 0;
+	sfd.header = headers;
+	sfd.hlen = hlen;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+
+	return(pt_SendFile(sd, &sfd, flags, timeout));
+}  /* pt_TransmitFile */
+
+static PRInt32 pt_AcceptRead(
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
+    void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+
+    if (pt_TestAbort()) return rv;
+    /* The socket must be in blocking mode. */
+    if (sd->secret->nonblocking)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return rv;
+    }
+
+    rv = PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout);
+    return rv;
+}  /* pt_AcceptRead */
+
+static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
+{
+    PRIntn rv = -1;
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = getsockname(
+        fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno);
+        return PR_FAILURE;
+    } else {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr)
+        {
+            addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+        }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+#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, addr_len) == PR_TRUE);
+        return PR_SUCCESS;
+    }
+}  /* pt_GetSockName */
+
+static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
+{
+    PRIntn rv = -1;
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = getpeername(
+        fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
+
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno);
+        return PR_FAILURE;
+    } else {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr)
+        {
+            addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+        }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+#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, addr_len) == PR_TRUE);
+        return PR_SUCCESS;
+    }
+}  /* pt_GetPeerName */
+
+static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
+{
+    PRIntn rv;
+    pt_SockLen length;
+    PRInt32 level, name;
+
+    /*
+     * PR_SockOpt_Nonblocking is a special case that does not
+     * translate to a getsockopt() call
+     */
+    if (PR_SockOpt_Nonblocking == data->option)
+    {
+        data->value.non_blocking = fd->secret->nonblocking;
+        return PR_SUCCESS;
+    }
+
+    rv = _PR_MapOptionName(data->option, &level, &name);
+    if (PR_SUCCESS == rv)
+    {
+        switch (data->option)
+        {
+            case PR_SockOpt_Linger:
+            {
+                struct linger linger;
+                length = sizeof(linger);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name, (char *) &linger, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(linger) == length));
+                data->value.linger.polarity =
+                    (linger.l_onoff) ? PR_TRUE : PR_FALSE;
+                data->value.linger.linger =
+                    PR_SecondsToInterval(linger.l_linger);
+                break;
+            }
+            case PR_SockOpt_Reuseaddr:
+            case PR_SockOpt_Keepalive:
+            case PR_SockOpt_NoDelay:
+            case PR_SockOpt_Broadcast:
+            {
+                PRIntn value;
+                length = sizeof(PRIntn);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name, (char*)&value, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length));
+                data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
+                break;
+            }
+            case PR_SockOpt_McastLoopback:
+            {
+                PRUint8 xbool;
+                length = sizeof(xbool);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&xbool, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(xbool) == length));
+                data->value.mcast_loopback = (0 == xbool) ? PR_FALSE : PR_TRUE;
+                break;
+            }
+            case PR_SockOpt_RecvBufferSize:
+            case PR_SockOpt_SendBufferSize:
+            case PR_SockOpt_MaxSegment:
+            {
+                PRIntn value;
+                length = sizeof(PRIntn);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name, (char*)&value, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length));
+                data->value.recv_buffer_size = value;
+                break;
+            }
+            case PR_SockOpt_IpTimeToLive:
+            case PR_SockOpt_IpTypeOfService:
+            {
+                length = sizeof(PRUintn);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&data->value.ip_ttl, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length));
+                break;
+            }
+            case PR_SockOpt_McastTimeToLive:
+            {
+                PRUint8 ttl;
+                length = sizeof(ttl);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&ttl, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(ttl) == length));
+                data->value.mcast_ttl = ttl;
+                break;
+            }
+            case PR_SockOpt_AddMember:
+            case PR_SockOpt_DropMember:
+            {
+                struct ip_mreq mreq;
+                length = sizeof(mreq);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name, (char*)&mreq, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(mreq) == length));
+                data->value.add_member.mcaddr.inet.ip =
+                    mreq.imr_multiaddr.s_addr;
+                data->value.add_member.ifaddr.inet.ip =
+                    mreq.imr_interface.s_addr;
+                break;
+            }
+            case PR_SockOpt_McastInterface:
+            {
+                length = sizeof(data->value.mcast_if.inet.ip);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&data->value.mcast_if.inet.ip, &length);
+                PR_ASSERT((-1 == rv)
+                    || (sizeof(data->value.mcast_if.inet.ip) == length));
+                break;
+            }
+            default:
+                PR_NOT_REACHED("Unknown socket option");
+                break;
+        }
+        if (-1 == rv) _PR_MD_MAP_GETSOCKOPT_ERROR(errno);
+    }
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* pt_GetSocketOption */
+
+static PRStatus pt_SetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data)
+{
+    PRIntn rv;
+    PRInt32 level, name;
+
+    /*
+     * PR_SockOpt_Nonblocking is a special case that does not
+     * translate to a setsockopt call.
+     */
+    if (PR_SockOpt_Nonblocking == data->option)
+    {
+        fd->secret->nonblocking = data->value.non_blocking;
+        return PR_SUCCESS;
+    }
+
+    rv = _PR_MapOptionName(data->option, &level, &name);
+    if (PR_SUCCESS == rv)
+    {
+        switch (data->option)
+        {
+            case PR_SockOpt_Linger:
+            {
+                struct linger linger;
+                linger.l_onoff = data->value.linger.polarity;
+                linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name, (char*)&linger, sizeof(linger));
+                break;
+            }
+            case PR_SockOpt_Reuseaddr:
+            case PR_SockOpt_Keepalive:
+            case PR_SockOpt_NoDelay:
+            case PR_SockOpt_Broadcast:
+            {
+                PRIntn value = (data->value.reuse_addr) ? 1 : 0;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&value, sizeof(PRIntn));
+#ifdef LINUX
+                /* for pt_LinuxSendFile */
+                if (name == TCP_NODELAY && rv == 0) {
+                    fd->secret->md.tcp_nodelay = value;
+                }
+#endif
+                break;
+            }
+            case PR_SockOpt_McastLoopback:
+            {
+                PRUint8 xbool = data->value.mcast_loopback ? 1 : 0;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&xbool, sizeof(xbool));
+                break;
+            }
+            case PR_SockOpt_RecvBufferSize:
+            case PR_SockOpt_SendBufferSize:
+            case PR_SockOpt_MaxSegment:
+            {
+                PRIntn value = data->value.recv_buffer_size;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&value, sizeof(PRIntn));
+                break;
+            }
+            case PR_SockOpt_IpTimeToLive:
+            case PR_SockOpt_IpTypeOfService:
+            {
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&data->value.ip_ttl, sizeof(PRUintn));
+                break;
+            }
+            case PR_SockOpt_McastTimeToLive:
+            {
+                PRUint8 ttl = data->value.mcast_ttl;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&ttl, sizeof(ttl));
+                break;
+            }
+            case PR_SockOpt_AddMember:
+            case PR_SockOpt_DropMember:
+            {
+                struct ip_mreq mreq;
+                mreq.imr_multiaddr.s_addr =
+                    data->value.add_member.mcaddr.inet.ip;
+                mreq.imr_interface.s_addr =
+                    data->value.add_member.ifaddr.inet.ip;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&mreq, sizeof(mreq));
+                break;
+            }
+            case PR_SockOpt_McastInterface:
+            {
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&data->value.mcast_if.inet.ip,
+                    sizeof(data->value.mcast_if.inet.ip));
+                break;
+            }
+            default:
+                PR_NOT_REACHED("Unknown socket option");
+                break;
+        }
+        if (-1 == rv) _PR_MD_MAP_SETSOCKOPT_ERROR(errno);
+    }
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* pt_SetSocketOption */
+
+/*****************************************************************************/
+/****************************** I/O method objects ***************************/
+/*****************************************************************************/
+
+static PRIOMethods _pr_file_methods = {
+    PR_DESC_FILE,
+    pt_Close,
+    pt_Read,
+    pt_Write,
+    pt_Available_f,
+    pt_Available64_f,
+    pt_Fsync,
+    pt_Seek,
+    pt_Seek64,
+    pt_FileInfo,
+    pt_FileInfo64,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    pt_Poll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods _pr_pipe_methods = {
+    PR_DESC_PIPE,
+    pt_Close,
+    pt_Read,
+    pt_Write,
+    pt_Available_s,
+    pt_Available64_s,
+    pt_Synch,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    pt_Poll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods _pr_tcp_methods = {
+    PR_DESC_SOCKET_TCP,
+    pt_Close,
+    pt_SocketRead,
+    pt_SocketWrite,
+    pt_Available_s,
+    pt_Available64_s,
+    pt_Synch,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    pt_Writev,
+    pt_Connect,
+    pt_Accept,
+    pt_Bind,
+    pt_Listen,
+    pt_Shutdown,
+    pt_Recv,
+    pt_Send,
+    (PRRecvfromFN)_PR_InvalidInt,
+    (PRSendtoFN)_PR_InvalidInt,
+    pt_Poll,
+    pt_AcceptRead,
+    pt_TransmitFile,
+    pt_GetSockName,
+    pt_GetPeerName,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    pt_GetSocketOption,
+    pt_SetSocketOption,
+    pt_SendFile, 
+    pt_ConnectContinue,
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods _pr_udp_methods = {
+    PR_DESC_SOCKET_UDP,
+    pt_Close,
+    pt_SocketRead,
+    pt_SocketWrite,
+    pt_Available_s,
+    pt_Available64_s,
+    pt_Synch,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    pt_Writev,
+    pt_Connect,
+    (PRAcceptFN)_PR_InvalidDesc,
+    pt_Bind,
+    pt_Listen,
+    pt_Shutdown,
+    pt_Recv,
+    pt_Send,
+    pt_RecvFrom,
+    pt_SendTo,
+    pt_Poll,
+    (PRAcceptreadFN)_PR_InvalidInt,
+    (PRTransmitfileFN)_PR_InvalidInt,
+    pt_GetSockName,
+    pt_GetPeerName,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    pt_GetSocketOption,
+    pt_SetSocketOption,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods _pr_socketpollfd_methods = {
+    (PRDescType) 0,
+    (PRCloseFN)_PR_InvalidStatus,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+	pt_Poll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+#if defined(HPUX) || defined(OSF1) || defined(SOLARIS) || defined (IRIX) \
+    || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+    || defined(AIX) || defined(FREEBSD) || defined(NETBSD) \
+    || defined(OPENBSD) || defined(BSDI) || defined(NTO) \
+    || defined(DARWIN) || defined(UNIXWARE) || defined(RISCOS) \
+    || defined(SYMBIAN)
+#define _PR_FCNTL_FLAGS O_NONBLOCK
+#else
+#error "Can't determine architecture"
+#endif
+
+/*
+ * Put a Unix file descriptor in non-blocking mode.
+ */
+static void pt_MakeFdNonblock(PRIntn osfd)
+{
+    PRIntn flags;
+    flags = fcntl(osfd, F_GETFL, 0);
+    flags |= _PR_FCNTL_FLAGS;
+    (void)fcntl(osfd, F_SETFL, flags);
+}
+
+/*
+ * Put a Unix socket fd in non-blocking mode that can
+ * ideally be inherited by an accepted socket.
+ *
+ * Why doesn't pt_MakeFdNonblock do?  This is to deal with
+ * the special case of HP-UX.  HP-UX has three kinds of
+ * non-blocking modes for sockets: the fcntl() O_NONBLOCK
+ * and O_NDELAY flags and ioctl() FIOSNBIO request.  Only
+ * the ioctl() FIOSNBIO form of non-blocking mode is
+ * inherited by an accepted socket.
+ *
+ * Other platforms just use the generic pt_MakeFdNonblock
+ * to put a socket in non-blocking mode.
+ */
+#ifdef HPUX
+static void pt_MakeSocketNonblock(PRIntn osfd)
+{
+    PRIntn one = 1;
+    (void)ioctl(osfd, FIOSNBIO, &one);
+}
+#else
+#define pt_MakeSocketNonblock pt_MakeFdNonblock
+#endif
+
+static PRFileDesc *pt_SetMethods(
+    PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported)
+{
+    PRFileDesc *fd = _PR_Getfd();
+    
+    if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    else
+    {
+        fd->secret->md.osfd = osfd;
+        fd->secret->state = _PR_FILEDESC_OPEN;
+        if (imported) fd->secret->inheritable = _PR_TRI_UNKNOWN;
+        else
+        {
+            /* By default, a Unix fd is not closed on exec. */
+#ifdef DEBUG
+            PRIntn flags;
+            flags = fcntl(osfd, F_GETFD, 0);
+            PR_ASSERT(0 == flags);
+#endif
+            fd->secret->inheritable = _PR_TRI_TRUE;
+        }
+        switch (type)
+        {
+            case PR_DESC_FILE:
+                fd->methods = PR_GetFileMethods();
+                break;
+            case PR_DESC_SOCKET_TCP:
+                fd->methods = PR_GetTCPMethods();
+#ifdef _PR_ACCEPT_INHERIT_NONBLOCK
+                if (!isAcceptedSocket) pt_MakeSocketNonblock(osfd);
+#else
+                pt_MakeSocketNonblock(osfd);
+#endif
+                break;
+            case PR_DESC_SOCKET_UDP:
+                fd->methods = PR_GetUDPMethods();
+                pt_MakeFdNonblock(osfd);
+                break;
+            case PR_DESC_PIPE:
+                fd->methods = PR_GetPipeMethods();
+                pt_MakeFdNonblock(osfd);
+                break;
+            default:
+                break;
+        }
+    }
+    return fd;
+}  /* pt_SetMethods */
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
+{
+    return &_pr_file_methods;
+}  /* PR_GetFileMethods */
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void)
+{
+    return &_pr_pipe_methods;
+}  /* PR_GetPipeMethods */
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods(void)
+{
+    return &_pr_tcp_methods;
+}  /* PR_GetTCPMethods */
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods(void)
+{
+    return &_pr_udp_methods;
+}  /* PR_GetUDPMethods */
+
+static const PRIOMethods* PR_GetSocketPollFdMethods(void)
+{
+    return &_pr_socketpollfd_methods;
+}  /* PR_GetSocketPollFdMethods */
+
+PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
+    PRInt32 osfd, const PRIOMethods *methods)
+{
+    PRFileDesc *fd = _PR_Getfd();
+
+    if (NULL == fd) goto failed;
+
+    fd->methods = methods;
+    fd->secret->md.osfd = osfd;
+    /* Make fd non-blocking */
+    if (osfd > 2)
+    {
+        /* Don't mess around with stdin, stdout or stderr */
+        if (&_pr_tcp_methods == methods) pt_MakeSocketNonblock(osfd);
+        else pt_MakeFdNonblock(osfd);
+    }
+    fd->secret->state = _PR_FILEDESC_OPEN;
+    fd->secret->inheritable = _PR_TRI_UNKNOWN;
+    return fd;
+    
+failed:
+    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    return fd;
+}  /* PR_AllocFileDesc */
+
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd);
+#if defined(_PR_INET6_PROBE)
+extern PRBool _pr_ipv6_is_present(void);
+PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket()
+{
+PRInt32 osfd;
+
+#if defined(DARWIN)
+    /*
+     * Disable IPv6 if Darwin version is less than 7.0.0 (OS X 10.3).  IPv6 on
+     * lesser versions is not ready for general use (see bug 222031).
+     */
+    {
+        struct utsname u;
+        if (uname(&u) != 0 || atoi(u.release) < 7)
+            return PR_FALSE;
+    }
+#endif
+
+    /*
+     * HP-UX only: HP-UX IPv6 Porting Guide (dated February 2001)
+     * suggests that we call open("/dev/ip6", O_RDWR) to determine
+     * whether IPv6 APIs and the IPv6 stack are on the system.
+     * Our portable test below seems to work fine, so I am using it.
+     */
+    osfd = socket(AF_INET6, SOCK_STREAM, 0);
+    if (osfd != -1) {
+        close(osfd);
+        return PR_TRUE;
+    }
+    return PR_FALSE;
+}
+#endif	/* _PR_INET6_PROBE */
+#endif
+
+PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
+{
+    PRIntn osfd;
+    PRDescType ftype;
+    PRFileDesc *fd = NULL;
+	PRInt32 tmp_domain = domain;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (pt_TestAbort()) return NULL;
+
+    if (PF_INET != domain
+        && PR_AF_INET6 != domain
+        && PF_UNIX != domain)
+    {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+        return fd;
+    }
+	if (type == SOCK_STREAM) ftype = PR_DESC_SOCKET_TCP;
+	else if (type == SOCK_DGRAM) ftype = PR_DESC_SOCKET_UDP;
+	else
+	{
+		(void)PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return fd;
+	}
+#if defined(_PR_INET6_PROBE)
+	if (PR_AF_INET6 == domain)
+		domain = _pr_ipv6_is_present() ? AF_INET6 : AF_INET;
+#elif defined(_PR_INET6) 
+	if (PR_AF_INET6 == domain)
+		domain = AF_INET6;
+#else
+	if (PR_AF_INET6 == domain)
+		domain = AF_INET;
+#endif
+
+    osfd = socket(domain, type, proto);
+    if (osfd == -1) pt_MapError(_PR_MD_MAP_SOCKET_ERROR, errno);
+    else
+    {
+#ifdef _PR_IPV6_V6ONLY_PROBE
+        if ((domain == AF_INET6) && _pr_ipv6_v6only_on_by_default)
+        {
+            int on = 0;
+            (void)setsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY,
+                    &on, sizeof(on));
+        }
+#endif
+        fd = pt_SetMethods(osfd, ftype, PR_FALSE, PR_FALSE);
+        if (fd == NULL) close(osfd);
+    }
+#ifdef _PR_NEED_SECRET_AF
+    if (fd != NULL) fd->secret->af = domain;
+#endif
+#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6)
+	if (fd != NULL) {
+		/*
+		 * 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
+    return fd;
+}  /* PR_Socket */
+
+/*****************************************************************************/
+/****************************** I/O public methods ***************************/
+/*****************************************************************************/
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode)
+{
+    PRFileDesc *fd = NULL;
+    PRIntn syserrno, osfd = -1, osflags = 0;;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (pt_TestAbort()) return NULL;
+
+    if (flags & PR_RDONLY) osflags |= O_RDONLY;
+    if (flags & PR_WRONLY) osflags |= O_WRONLY;
+    if (flags & PR_RDWR) osflags |= O_RDWR;
+    if (flags & PR_APPEND) osflags |= O_APPEND;
+    if (flags & PR_TRUNCATE) osflags |= O_TRUNC;
+    if (flags & PR_EXCL) osflags |= O_EXCL;
+    if (flags & PR_SYNC)
+    {
+#if defined(O_SYNC)
+        osflags |= O_SYNC;
+#elif defined(O_FSYNC)
+        osflags |= O_FSYNC;
+#else
+#error "Neither O_SYNC nor O_FSYNC is defined on this platform"
+#endif
+    }
+
+    /*
+    ** We have to hold the lock across the creation in order to
+    ** enforce the sematics of PR_Rename(). (see the latter for
+    ** more details)
+    */
+    if (flags & PR_CREATE_FILE)
+    {
+        osflags |= O_CREAT;
+        if (NULL !=_pr_rename_lock)
+            PR_Lock(_pr_rename_lock);
+    }
+
+    osfd = _md_iovector._open64(name, osflags, mode);
+    syserrno = errno;
+
+    if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
+        PR_Unlock(_pr_rename_lock);
+
+    if (osfd == -1)
+        pt_MapError(_PR_MD_MAP_OPEN_ERROR, syserrno);
+    else
+    {
+        fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_FALSE);
+        if (fd == NULL) close(osfd);  /* $$$ whoops! this is bad $$$ */
+    }
+    return fd;
+}  /* PR_OpenFile */
+
+PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
+{
+    return PR_OpenFile(name, flags, mode);
+}  /* PR_Open */
+
+PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
+{
+    PRIntn rv = -1;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = unlink(name);
+
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_UNLINK_ERROR, errno);
+        return PR_FAILURE;
+    } else
+        return PR_SUCCESS;
+}  /* PR_Delete */
+
+PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how)
+{
+    PRIntn rv;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    switch (how)
+    {
+    case PR_ACCESS_READ_OK:
+        rv =  access(name, R_OK);
+        break;
+    case PR_ACCESS_WRITE_OK:
+        rv = access(name, W_OK);
+        break;
+    case PR_ACCESS_EXISTS:
+    default:
+        rv = access(name, F_OK);
+    }
+    if (0 == rv) return PR_SUCCESS;
+    pt_MapError(_PR_MD_MAP_ACCESS_ERROR, errno);
+    return PR_FAILURE;
+    
+}  /* PR_Access */
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info)
+{
+    PRInt32 rv = _PR_MD_GETFILEINFO(fn, info);
+    return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+}  /* PR_GetFileInfo */
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    rv = _PR_MD_GETFILEINFO64(fn, info);
+    return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+}  /* PR_GetFileInfo64 */
+
+PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to)
+{
+    PRIntn rv = -1;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    /*
+    ** We have to acquire a lock here to stiffle anybody trying to create
+    ** a new file at the same time. And we have to hold that lock while we
+    ** test to see if the file exists and do the rename. The other place
+    ** where the lock is held is in PR_Open() when possibly creating a 
+    ** new file.
+    */
+
+    PR_Lock(_pr_rename_lock);
+    rv = access(to, F_OK);
+    if (0 == rv)
+    {
+        PR_SetError(PR_FILE_EXISTS_ERROR, 0);
+        rv = -1;
+    }
+    else
+    {
+        rv = rename(from, to);
+        if (rv == -1)
+            pt_MapError(_PR_MD_MAP_RENAME_ERROR, errno);
+    }
+    PR_Unlock(_pr_rename_lock);
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* PR_Rename */
+
+PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir)
+{
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    if (NULL != dir->md.d)
+    {
+        if (closedir(dir->md.d) == -1)
+        {
+            _PR_MD_MAP_CLOSEDIR_ERROR(errno);
+            return PR_FAILURE;
+        }
+        dir->md.d = NULL;
+        PR_DELETE(dir);
+    }
+    return PR_SUCCESS;
+}  /* PR_CloseDir */
+
+PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode)
+{
+    PRInt32 rv = -1;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    /*
+    ** This lock is used to enforce rename semantics as described
+    ** in PR_Rename.
+    */
+    if (NULL !=_pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+    rv = mkdir(name, mode);
+    if (-1 == rv)
+        pt_MapError(_PR_MD_MAP_MKDIR_ERROR, errno);
+    if (NULL !=_pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* PR_Makedir */
+
+PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode)
+{
+    return PR_MakeDir(name, mode);
+}  /* PR_Mkdir */
+
+PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name)
+{
+    PRInt32 rv;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = rmdir(name);
+    if (0 == rv) {
+    return PR_SUCCESS;
+    } else {
+    pt_MapError(_PR_MD_MAP_RMDIR_ERROR, errno);
+    return PR_FAILURE;
+    }
+}  /* PR_Rmdir */
+
+
+PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name)
+{
+    DIR *osdir;
+    PRDir *dir = NULL;
+
+    if (pt_TestAbort()) return dir;
+
+    osdir = opendir(name);
+    if (osdir == NULL)
+        pt_MapError(_PR_MD_MAP_OPENDIR_ERROR, errno);
+    else
+    {
+        dir = PR_NEWZAP(PRDir);
+        if (dir)
+            dir->md.d = osdir;
+        else
+            (void)closedir(osdir);
+    }
+    return dir;
+}  /* PR_OpenDir */
+
+static PRInt32 _pr_poll_with_poll(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRInt32 ready = 0;
+    /*
+     * For restarting poll() if it is interrupted by a signal.
+     * We use these variables to figure out how much time has
+     * elapsed and how much of the timeout still remains.
+     */
+    PRIntervalTime start, elapsed, remaining;
+
+    if (pt_TestAbort()) return -1;
+
+    if (0 == npds) PR_Sleep(timeout);
+    else
+    {
+#define STACK_POLL_DESC_COUNT 64
+        struct pollfd stack_syspoll[STACK_POLL_DESC_COUNT];
+        struct pollfd *syspoll;
+        PRIntn index, msecs;
+
+        if (npds <= STACK_POLL_DESC_COUNT)
+        {
+            syspoll = stack_syspoll;
+        }
+        else
+        {
+            PRThread *me = PR_GetCurrentThread();
+            if (npds > me->syspoll_count)
+            {
+                PR_Free(me->syspoll_list);
+                me->syspoll_list =
+                    (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
+                if (NULL == me->syspoll_list)
+                {
+                    me->syspoll_count = 0;
+                    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                    return -1;
+                }
+                me->syspoll_count = npds;
+            }
+            syspoll = me->syspoll_list;
+        }
+
+        for (index = 0; index < npds; ++index)
+        {
+            PRInt16 in_flags_read = 0, in_flags_write = 0;
+            PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+            if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+            {
+                if (pds[index].in_flags & PR_POLL_READ)
+                {
+                    in_flags_read = (pds[index].fd->methods->poll)(
+                        pds[index].fd,
+                        pds[index].in_flags & ~PR_POLL_WRITE,
+                        &out_flags_read);
+                }
+                if (pds[index].in_flags & PR_POLL_WRITE)
+                {
+                    in_flags_write = (pds[index].fd->methods->poll)(
+                        pds[index].fd,
+                        pds[index].in_flags & ~PR_POLL_READ,
+                        &out_flags_write);
+                }
+                if ((0 != (in_flags_read & out_flags_read))
+                || (0 != (in_flags_write & out_flags_write)))
+                {
+                    /* this one is ready right now */
+                    if (0 == ready)
+                    {
+                        /*
+                         * We will return without calling the system
+                         * poll function.  So zero the out_flags
+                         * fields of all the poll descriptors before
+                         * this one.
+                         */
+                        int i;
+                        for (i = 0; i < index; i++)
+                        {
+                            pds[i].out_flags = 0;
+                        }
+                    }
+                    ready += 1;
+                    pds[index].out_flags = out_flags_read | out_flags_write;
+                }
+                else
+                {
+                    /* now locate the NSPR layer at the bottom of the stack */
+                    PRFileDesc *bottom = PR_GetIdentitiesLayer(
+                        pds[index].fd, PR_NSPR_IO_LAYER);
+                    PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                    pds[index].out_flags = 0;  /* pre-condition */
+                    if ((NULL != bottom)
+                    && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                    {
+                        if (0 == ready)
+                        {
+                            syspoll[index].fd = bottom->secret->md.osfd;
+                            syspoll[index].events = 0;
+                            if (in_flags_read & PR_POLL_READ)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_READ_SYS_READ;
+                                syspoll[index].events |= POLLIN;
+                            }
+                            if (in_flags_read & PR_POLL_WRITE)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_READ_SYS_WRITE;
+                                syspoll[index].events |= POLLOUT;
+                            }
+                            if (in_flags_write & PR_POLL_READ)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_WRITE_SYS_READ;
+                                syspoll[index].events |= POLLIN;
+                            }
+                            if (in_flags_write & PR_POLL_WRITE)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_WRITE_SYS_WRITE;
+                                syspoll[index].events |= POLLOUT;
+                            }
+                            if (pds[index].in_flags & PR_POLL_EXCEPT)
+                                syspoll[index].events |= POLLPRI;
+                        }
+                    }
+                    else
+                    {
+                        if (0 == ready)
+                        {
+                            int i;
+                            for (i = 0; i < index; i++)
+                            {
+                                pds[i].out_flags = 0;
+                            }
+                        }
+                        ready += 1;  /* this will cause an abrupt return */
+                        pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
+                    }
+                }
+            }
+            else
+            {
+                /* make poll() ignore this entry */
+                syspoll[index].fd = -1;
+                syspoll[index].events = 0;
+                pds[index].out_flags = 0;
+            }
+        }
+        if (0 == ready)
+        {
+            switch (timeout)
+            {
+            case PR_INTERVAL_NO_WAIT: msecs = 0; break;
+            case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break;
+            default:
+                msecs = PR_IntervalToMilliseconds(timeout);
+                start = PR_IntervalNow();
+            }
+
+retry:
+            ready = poll(syspoll, npds, msecs);
+            if (-1 == ready)
+            {
+                PRIntn oserror = errno;
+
+                if (EINTR == oserror)
+                {
+                    if (timeout == PR_INTERVAL_NO_TIMEOUT)
+                        goto retry;
+                    else if (timeout == PR_INTERVAL_NO_WAIT)
+                        ready = 0;  /* don't retry, just time out */
+                    else
+                    {
+                        elapsed = (PRIntervalTime) (PR_IntervalNow()
+                                - start);
+                        if (elapsed > timeout)
+                            ready = 0;  /* timed out */
+                        else
+                        {
+                            remaining = timeout - elapsed;
+                            msecs = PR_IntervalToMilliseconds(remaining);
+                            goto retry;
+                        }
+                    }
+                }
+                else
+                {
+                    _PR_MD_MAP_POLL_ERROR(oserror);
+                }
+            }
+            else if (ready > 0)
+            {
+                for (index = 0; index < npds; ++index)
+                {
+                    PRInt16 out_flags = 0;
+                    if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+                    {
+                        if (0 != syspoll[index].revents)
+                        {
+                            if (syspoll[index].revents & POLLIN)
+                            {
+                                if (pds[index].out_flags
+                                & _PR_POLL_READ_SYS_READ)
+                                {
+                                    out_flags |= PR_POLL_READ;
+                                }
+                                if (pds[index].out_flags
+                                & _PR_POLL_WRITE_SYS_READ)
+                                {
+                                    out_flags |= PR_POLL_WRITE;
+                                }
+                            }
+                            if (syspoll[index].revents & POLLOUT)
+                            {
+                                if (pds[index].out_flags
+                                & _PR_POLL_READ_SYS_WRITE)
+                                {
+                                    out_flags |= PR_POLL_READ;
+                                }
+                                if (pds[index].out_flags
+                                & _PR_POLL_WRITE_SYS_WRITE)
+                                {
+                                    out_flags |= PR_POLL_WRITE;
+                                }
+                            }
+                            if (syspoll[index].revents & POLLPRI)
+                                out_flags |= PR_POLL_EXCEPT;
+                            if (syspoll[index].revents & POLLERR)
+                                out_flags |= PR_POLL_ERR;
+                            if (syspoll[index].revents & POLLNVAL)
+                                out_flags |= PR_POLL_NVAL;
+                            if (syspoll[index].revents & POLLHUP)
+                                out_flags |= PR_POLL_HUP;
+                        }
+                    }
+                    pds[index].out_flags = out_flags;
+                }
+            }
+        }
+    }
+    return ready;
+
+} /* _pr_poll_with_poll */
+
+#if defined(_PR_POLL_WITH_SELECT)
+/*
+ * OSF1 and HPUX report the POLLHUP event for a socket when the
+ * shutdown(SHUT_WR) operation is called for the remote end, even though
+ * the socket is still writeable. Use select(), instead of poll(), to
+ * workaround this problem.
+ */
+static PRInt32 _pr_poll_with_select(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRInt32 ready = 0;
+    /*
+     * For restarting select() if it is interrupted by a signal.
+     * We use these variables to figure out how much time has
+     * elapsed and how much of the timeout still remains.
+     */
+    PRIntervalTime start, elapsed, remaining;
+
+    if (pt_TestAbort()) return -1;
+
+    if (0 == npds) PR_Sleep(timeout);
+    else
+    {
+#define STACK_POLL_DESC_COUNT 64
+        int stack_selectfd[STACK_POLL_DESC_COUNT];
+        int *selectfd;
+		fd_set rd, wr, ex, *rdp = NULL, *wrp = NULL, *exp = NULL;
+		struct timeval tv, *tvp;
+        PRIntn index, msecs, maxfd = 0;
+
+        if (npds <= STACK_POLL_DESC_COUNT)
+        {
+            selectfd = stack_selectfd;
+        }
+        else
+        {
+            PRThread *me = PR_GetCurrentThread();
+            if (npds > me->selectfd_count)
+            {
+                PR_Free(me->selectfd_list);
+                me->selectfd_list = (int *)PR_MALLOC(npds * sizeof(int));
+                if (NULL == me->selectfd_list)
+                {
+                    me->selectfd_count = 0;
+                    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                    return -1;
+                }
+                me->selectfd_count = npds;
+            }
+            selectfd = me->selectfd_list;
+        }
+		FD_ZERO(&rd);
+		FD_ZERO(&wr);
+		FD_ZERO(&ex);
+
+        for (index = 0; index < npds; ++index)
+        {
+            PRInt16 in_flags_read = 0, in_flags_write = 0;
+            PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+            if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+            {
+                if (pds[index].in_flags & PR_POLL_READ)
+                {
+                    in_flags_read = (pds[index].fd->methods->poll)(
+                        pds[index].fd,
+                        pds[index].in_flags & ~PR_POLL_WRITE,
+                        &out_flags_read);
+                }
+                if (pds[index].in_flags & PR_POLL_WRITE)
+                {
+                    in_flags_write = (pds[index].fd->methods->poll)(
+                        pds[index].fd,
+                        pds[index].in_flags & ~PR_POLL_READ,
+                        &out_flags_write);
+                }
+                if ((0 != (in_flags_read & out_flags_read))
+                || (0 != (in_flags_write & out_flags_write)))
+                {
+                    /* this one is ready right now */
+                    if (0 == ready)
+                    {
+                        /*
+                         * We will return without calling the system
+                         * poll function.  So zero the out_flags
+                         * fields of all the poll descriptors before
+                         * this one.
+                         */
+                        int i;
+                        for (i = 0; i < index; i++)
+                        {
+                            pds[i].out_flags = 0;
+                        }
+                    }
+                    ready += 1;
+                    pds[index].out_flags = out_flags_read | out_flags_write;
+                }
+                else
+                {
+                    /* now locate the NSPR layer at the bottom of the stack */
+                    PRFileDesc *bottom = PR_GetIdentitiesLayer(
+                        pds[index].fd, PR_NSPR_IO_LAYER);
+                    PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                    pds[index].out_flags = 0;  /* pre-condition */
+                    if ((NULL != bottom)
+                    && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                    {
+                        if (0 == ready)
+                        {
+                            PRBool add_to_rd = PR_FALSE;
+                            PRBool add_to_wr = PR_FALSE;
+                            PRBool add_to_ex = PR_FALSE;
+
+                            selectfd[index] = bottom->secret->md.osfd;
+                            if (in_flags_read & PR_POLL_READ)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_READ_SYS_READ;
+                                add_to_rd = PR_TRUE;
+                            }
+                            if (in_flags_read & PR_POLL_WRITE)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_READ_SYS_WRITE;
+                                add_to_wr = PR_TRUE;
+                            }
+                            if (in_flags_write & PR_POLL_READ)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_WRITE_SYS_READ;
+                                add_to_rd = PR_TRUE;
+                            }
+                            if (in_flags_write & PR_POLL_WRITE)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_WRITE_SYS_WRITE;
+                                add_to_wr = PR_TRUE;
+                            }
+                            if (pds[index].in_flags & PR_POLL_EXCEPT)
+                            {
+                                add_to_ex = PR_TRUE;
+                            }
+                            if ((selectfd[index] > maxfd) &&
+                                    (add_to_rd || add_to_wr || add_to_ex))
+                            {
+                                maxfd = selectfd[index];
+                                /*
+                                 * If maxfd is too large to be used with
+                                 * select, fall back to calling poll.
+                                 */
+                                if (maxfd >= FD_SETSIZE)
+                                    break;
+                            }
+                            if (add_to_rd)
+                            {
+                                FD_SET(bottom->secret->md.osfd, &rd);
+                                rdp = &rd;
+                            }
+                            if (add_to_wr)
+                            {
+                                FD_SET(bottom->secret->md.osfd, &wr);
+                                wrp = &wr;
+                            }
+                            if (add_to_ex)
+                            {
+                                FD_SET(bottom->secret->md.osfd, &ex);
+                                exp = &ex;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (0 == ready)
+                        {
+                            int i;
+                            for (i = 0; i < index; i++)
+                            {
+                                pds[i].out_flags = 0;
+                            }
+                        }
+                        ready += 1;  /* this will cause an abrupt return */
+                        pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
+                    }
+                }
+            }
+            else
+            {
+                pds[index].out_flags = 0;
+            }
+        }
+        if (0 == ready)
+        {
+			if (maxfd >= FD_SETSIZE)
+			{
+				/*
+				 * maxfd too large to be used with select, fall back to
+				 * calling poll
+				 */
+				return(_pr_poll_with_poll(pds, npds, timeout));
+			}
+            switch (timeout)
+            {
+            case PR_INTERVAL_NO_WAIT:
+				tv.tv_sec = 0;
+				tv.tv_usec = 0;
+				tvp = &tv;
+				break;
+            case PR_INTERVAL_NO_TIMEOUT:
+				tvp = NULL;
+				break;
+            default:
+                msecs = PR_IntervalToMilliseconds(timeout);
+				tv.tv_sec = msecs/PR_MSEC_PER_SEC;
+				tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC;
+				tvp = &tv;
+                start = PR_IntervalNow();
+            }
+
+retry:
+            ready = select(maxfd + 1, rdp, wrp, exp, tvp);
+            if (-1 == ready)
+            {
+                PRIntn oserror = errno;
+
+                if ((EINTR == oserror) || (EAGAIN == oserror))
+                {
+                    if (timeout == PR_INTERVAL_NO_TIMEOUT)
+                        goto retry;
+                    else if (timeout == PR_INTERVAL_NO_WAIT)
+                        ready = 0;  /* don't retry, just time out */
+                    else
+                    {
+                        elapsed = (PRIntervalTime) (PR_IntervalNow()
+                                - start);
+                        if (elapsed > timeout)
+                            ready = 0;  /* timed out */
+                        else
+                        {
+                            remaining = timeout - elapsed;
+                            msecs = PR_IntervalToMilliseconds(remaining);
+							tv.tv_sec = msecs/PR_MSEC_PER_SEC;
+							tv.tv_usec = (msecs % PR_MSEC_PER_SEC) *
+													PR_USEC_PER_MSEC;
+                            goto retry;
+                        }
+                    }
+                } else if (EBADF == oserror)
+                {
+					/* find all the bad fds */
+					ready = 0;
+                	for (index = 0; index < npds; ++index)
+					{
+                    	pds[index].out_flags = 0;
+            			if ((NULL != pds[index].fd) &&
+											(0 != pds[index].in_flags))
+						{
+							if (fcntl(selectfd[index], F_GETFL, 0) == -1)
+							{
+                    			pds[index].out_flags = PR_POLL_NVAL;
+								ready++;
+							}
+						}
+					}
+                } else 
+                    _PR_MD_MAP_SELECT_ERROR(oserror);
+            }
+            else if (ready > 0)
+            {
+                for (index = 0; index < npds; ++index)
+                {
+                    PRInt16 out_flags = 0;
+                    if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+                    {
+						if (FD_ISSET(selectfd[index], &rd))
+						{
+							if (pds[index].out_flags
+							& _PR_POLL_READ_SYS_READ)
+							{
+								out_flags |= PR_POLL_READ;
+							}
+							if (pds[index].out_flags
+							& _PR_POLL_WRITE_SYS_READ)
+							{
+								out_flags |= PR_POLL_WRITE;
+							}
+						}
+						if (FD_ISSET(selectfd[index], &wr))
+						{
+							if (pds[index].out_flags
+							& _PR_POLL_READ_SYS_WRITE)
+							{
+								out_flags |= PR_POLL_READ;
+							}
+							if (pds[index].out_flags
+							& _PR_POLL_WRITE_SYS_WRITE)
+							{
+								out_flags |= PR_POLL_WRITE;
+							}
+						}
+						if (FD_ISSET(selectfd[index], &ex))
+							out_flags |= PR_POLL_EXCEPT;
+                    }
+                    pds[index].out_flags = out_flags;
+                }
+            }
+        }
+    }
+    return ready;
+
+} /* _pr_poll_with_select */
+#endif	/* _PR_POLL_WITH_SELECT */
+
+PR_IMPLEMENT(PRInt32) PR_Poll(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+#if defined(_PR_POLL_WITH_SELECT)
+	return(_pr_poll_with_select(pds, npds, timeout));
+#else
+	return(_pr_poll_with_poll(pds, npds, timeout));
+#endif
+}
+
+PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags)
+{
+    struct dirent *dp;
+
+    if (pt_TestAbort()) return NULL;
+
+    for (;;)
+    {
+        errno = 0;
+        dp = readdir(dir->md.d);
+        if (NULL == dp)
+        {
+            pt_MapError(_PR_MD_MAP_READDIR_ERROR, errno);
+            return NULL;
+        }
+        if ((flags & PR_SKIP_DOT)
+            && ('.' == dp->d_name[0])
+            && (0 == dp->d_name[1])) continue;
+        if ((flags & PR_SKIP_DOT_DOT)
+            && ('.' == dp->d_name[0])
+            && ('.' == dp->d_name[1])
+            && (0 == dp->d_name[2])) continue;
+        if ((flags & PR_SKIP_HIDDEN) && ('.' == dp->d_name[0]))
+            continue;
+        break;
+    }
+    dir->d.name = dp->d_name;
+    return &dir->d;
+}  /* PR_ReadDir */
+
+PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void)
+{
+    PRIntn domain = PF_INET;
+
+    return PR_Socket(domain, SOCK_DGRAM, 0);
+}  /* PR_NewUDPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_NewTCPSocket(void)
+{
+    PRIntn domain = PF_INET;
+
+    return PR_Socket(domain, SOCK_STREAM, 0);
+}  /* PR_NewTCPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenUDPSocket(PRIntn af)
+{
+    return PR_Socket(af, SOCK_DGRAM, 0);
+}  /* PR_NewUDPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenTCPSocket(PRIntn af)
+{
+    return PR_Socket(af, SOCK_STREAM, 0);
+}  /* PR_NewTCPSocket */
+
+PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2])
+{
+#ifdef SYMBIAN
+    /*
+     * For the platforms that don't have socketpair.
+     *
+     * Copied from prsocket.c, with the parameter f[] renamed fds[] and the
+     * _PR_CONNECT_DOES_NOT_BIND code removed.
+     */
+    PRFileDesc *listenSock;
+    PRNetAddr selfAddr, peerAddr;
+    PRUint16 port;
+
+    fds[0] = fds[1] = NULL;
+    listenSock = PR_NewTCPSocket();
+    if (listenSock == NULL) {
+        goto failed;
+    }
+    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */
+    if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    port = ntohs(selfAddr.inet.port);
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        goto failed;
+    }
+    fds[0] = PR_NewTCPSocket();
+    if (fds[0] == NULL) {
+        goto failed;
+    }
+    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr);
+
+    /*
+     * Only a thread is used to do the connect and accept.
+     * I am relying on the fact that PR_Connect returns
+     * successfully as soon as the connect request is put
+     * into the listen queue (but before PR_Accept is called).
+     * This is the behavior of the BSD socket code.  If
+     * connect does not return until accept is called, we
+     * will need to create another thread to call connect.
+     */
+    if (PR_Connect(fds[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT)
+            == PR_FAILURE) {
+        goto failed;
+    }
+    /*
+     * A malicious local process may connect to the listening
+     * socket, so we need to verify that the accepted connection
+     * is made from our own socket fds[0].
+     */
+    if (PR_GetSockName(fds[0], &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    fds[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT);
+    if (fds[1] == NULL) {
+        goto failed;
+    }
+    if (peerAddr.inet.port != selfAddr.inet.port) {
+        /* the connection we accepted is not from fds[0] */
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        goto failed;
+    }
+    PR_Close(listenSock);
+    return PR_SUCCESS;
+
+failed:
+    if (listenSock) {
+        PR_Close(listenSock);
+    }
+    if (fds[0]) {
+        PR_Close(fds[0]);
+    }
+    if (fds[1]) {
+        PR_Close(fds[1]);
+    }
+    return PR_FAILURE;
+#else
+    PRInt32 osfd[2];
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, osfd) == -1) {
+        pt_MapError(_PR_MD_MAP_SOCKETPAIR_ERROR, errno);
+        return PR_FAILURE;
+    }
+
+    fds[0] = pt_SetMethods(osfd[0], PR_DESC_SOCKET_TCP, PR_FALSE, PR_FALSE);
+    if (fds[0] == NULL) {
+        close(osfd[0]);
+        close(osfd[1]);
+        return PR_FAILURE;
+    }
+    fds[1] = pt_SetMethods(osfd[1], PR_DESC_SOCKET_TCP, PR_FALSE, PR_FALSE);
+    if (fds[1] == NULL) {
+        PR_Close(fds[0]);
+        close(osfd[1]);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+#endif
+}  /* PR_NewTCPSocketPair */
+
+PR_IMPLEMENT(PRStatus) PR_CreatePipe(
+    PRFileDesc **readPipe,
+    PRFileDesc **writePipe
+)
+{
+    int pipefd[2];
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    if (pipe(pipefd) == -1)
+    {
+    /* XXX map pipe error */
+        PR_SetError(PR_UNKNOWN_ERROR, errno);
+        return PR_FAILURE;
+    }
+    *readPipe = pt_SetMethods(pipefd[0], PR_DESC_PIPE, PR_FALSE, PR_FALSE);
+    if (NULL == *readPipe)
+    {
+        close(pipefd[0]);
+        close(pipefd[1]);
+        return PR_FAILURE;
+    }
+    *writePipe = pt_SetMethods(pipefd[1], PR_DESC_PIPE, PR_FALSE, PR_FALSE);
+    if (NULL == *writePipe)
+    {
+        PR_Close(*readPipe);
+        close(pipefd[1]);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+/*
+** Set the inheritance attribute of a file descriptor.
+*/
+PR_IMPLEMENT(PRStatus) PR_SetFDInheritable(
+    PRFileDesc *fd,
+    PRBool inheritable)
+{
+    /*
+     * Only a non-layered, NSPR file descriptor can be inherited
+     * by a child process.
+     */
+    if (fd->identity != PR_NSPR_IO_LAYER)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (fd->secret->inheritable != inheritable)
+    {
+        if (fcntl(fd->secret->md.osfd, F_SETFD,
+        inheritable ? 0 : FD_CLOEXEC) == -1)
+        {
+            _PR_MD_MAP_DEFAULT_ERROR(errno);
+            return PR_FAILURE;
+        }
+        fd->secret->inheritable = (_PRTriStateBool) inheritable;
+    }
+    return PR_SUCCESS;
+}
+
+/*****************************************************************************/
+/***************************** I/O friends methods ***************************/
+/*****************************************************************************/
+
+PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_TRUE);
+    if (NULL == fd) close(osfd);
+    return fd;
+}  /* PR_ImportFile */
+
+PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    fd = pt_SetMethods(osfd, PR_DESC_PIPE, PR_FALSE, PR_TRUE);
+    if (NULL == fd) close(osfd);
+    return fd;
+}  /* PR_ImportPipe */
+
+PR_IMPLEMENT(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_FALSE, PR_TRUE);
+    if (NULL == fd) close(osfd);
+#ifdef _PR_NEED_SECRET_AF
+    if (NULL != fd) fd->secret->af = PF_INET;
+#endif
+    return fd;
+}  /* PR_ImportTCPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    fd = pt_SetMethods(osfd, PR_DESC_SOCKET_UDP, PR_FALSE, PR_TRUE);
+    if (NULL != fd) close(osfd);
+    return fd;
+}  /* PR_ImportUDPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    fd = _PR_Getfd();
+
+    if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    else
+    {
+        fd->secret->md.osfd = osfd;
+        fd->secret->inheritable = _PR_TRI_FALSE;
+    	fd->secret->state = _PR_FILEDESC_OPEN;
+        fd->methods = PR_GetSocketPollFdMethods();
+    }
+
+    return fd;
+}  /* PR_CreateSocketPollFD */
+
+PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd)
+{
+    if (NULL == fd)
+    {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    fd->secret->state = _PR_FILEDESC_CLOSED;
+    _PR_Putfd(fd);
+    return PR_SUCCESS;
+}  /* PR_DestroySocketPollFd */
+
+PR_IMPLEMENT(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *bottom)
+{
+    PRInt32 osfd = -1;
+    bottom = (NULL == bottom) ?
+        NULL : PR_GetIdentitiesLayer(bottom, PR_NSPR_IO_LAYER);
+    if (NULL == bottom) PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    else osfd = bottom->secret->md.osfd;
+    return osfd;
+}  /* PR_FileDesc2NativeHandle */
+
+PR_IMPLEMENT(void) PR_ChangeFileDescNativeHandle(PRFileDesc *fd,
+    PRInt32 handle)
+{
+    if (fd) fd->secret->md.osfd = handle;
+}  /*  PR_ChangeFileDescNativeHandle*/
+
+PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_Lock(_pr_flock_lock);
+    while (-1 == fd->secret->lockCount)
+        PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT);
+    if (0 == fd->secret->lockCount)
+    {
+        fd->secret->lockCount = -1;
+        PR_Unlock(_pr_flock_lock);
+        status = _PR_MD_LOCKFILE(fd->secret->md.osfd);
+        PR_Lock(_pr_flock_lock);
+        fd->secret->lockCount = (PR_SUCCESS == status) ? 1 : 0;
+        PR_NotifyAllCondVar(_pr_flock_cv);
+    }
+    else
+    {
+        fd->secret->lockCount += 1;
+    }
+    PR_Unlock(_pr_flock_lock);
+ 
+    return status;
+}  /* PR_LockFile */
+
+PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_Lock(_pr_flock_lock);
+    if (0 == fd->secret->lockCount)
+    {
+        status = _PR_MD_TLOCKFILE(fd->secret->md.osfd);
+        if (PR_SUCCESS == status) fd->secret->lockCount = 1;
+    }
+    else fd->secret->lockCount += 1;
+    PR_Unlock(_pr_flock_lock);
+ 
+    return status;
+}  /* PR_TLockFile */
+
+PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_Lock(_pr_flock_lock);
+    if (fd->secret->lockCount == 1)
+    {
+        status = _PR_MD_UNLOCKFILE(fd->secret->md.osfd);
+        if (PR_SUCCESS == status) fd->secret->lockCount = 0;
+    }
+    else fd->secret->lockCount -= 1;
+    PR_Unlock(_pr_flock_lock);
+
+    return status;
+}
+
+/*
+ * The next two entry points should not be in the API, but they are
+ * defined here for historical (or hysterical) reasons.
+ */
+
+PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void)
+{
+#if defined(AIX) || defined(SYMBIAN)
+    return sysconf(_SC_OPEN_MAX);
+#else
+    struct rlimit rlim;
+
+    if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) 
+       return -1;
+
+    return rlim.rlim_max;
+#endif
+}
+
+PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(PRIntn table_size)
+{
+#if defined(AIX) || defined(SYMBIAN)
+    return -1;
+#else
+    struct rlimit rlim;
+    PRInt32 tableMax = PR_GetSysfdTableMax();
+
+    if (tableMax < 0) return -1;
+    rlim.rlim_max = tableMax;
+
+    /* Grow as much as we can; even if too big */
+    if ( rlim.rlim_max < table_size )
+        rlim.rlim_cur = rlim.rlim_max;
+    else
+        rlim.rlim_cur = table_size;
+
+    if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) 
+        return -1;
+
+    return rlim.rlim_cur;
+#endif
+}
+
+/*
+ * PR_Stat is supported for backward compatibility; some existing Java
+ * code uses it.  New code should use PR_GetFileInfo.
+ */
+
+#ifndef NO_NSPR_10_SUPPORT
+PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_Stat", "PR_GetFileInfo");
+
+    if (pt_TestAbort()) return -1;
+
+    if (-1 == stat(name, buf)) {
+        pt_MapError(_PR_MD_MAP_STAT_ERROR, errno);
+        return -1;
+    } else {
+        return 0;
+    }
+}
+#endif /* ! NO_NSPR_10_SUPPORT */
+
+
+PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_ZERO (PR_Select)", "PR_Poll");
+    memset(set, 0, sizeof(PR_fd_set));
+}
+
+PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_SET (PR_Select)", "PR_Poll");
+    PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC );
+
+    set->harray[set->hsize++] = fh;
+}
+
+PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set)
+{
+    PRUint32 index, index2;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_CLR (PR_Select)", "PR_Poll");
+
+    for (index = 0; index<set->hsize; index++)
+       if (set->harray[index] == fh) {
+           for (index2=index; index2 < (set->hsize-1); index2++) {
+               set->harray[index2] = set->harray[index2+1];
+           }
+           set->hsize--;
+           break;
+       }
+}
+
+PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set)
+{
+    PRUint32 index;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_ISSET (PR_Select)", "PR_Poll");
+    for (index = 0; index<set->hsize; index++)
+       if (set->harray[index] == fh) {
+           return 1;
+       }
+    return 0;
+}
+
+PR_IMPLEMENT(void) PR_FD_NSET(PRInt32 fd, PR_fd_set *set)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_NSET (PR_Select)", "PR_Poll");
+    PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC );
+
+    set->narray[set->nsize++] = fd;
+}
+
+PR_IMPLEMENT(void) PR_FD_NCLR(PRInt32 fd, PR_fd_set *set)
+{
+    PRUint32 index, index2;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_NCLR (PR_Select)", "PR_Poll");
+
+    for (index = 0; index<set->nsize; index++)
+       if (set->narray[index] == fd) {
+           for (index2=index; index2 < (set->nsize-1); index2++) {
+               set->narray[index2] = set->narray[index2+1];
+           }
+           set->nsize--;
+           break;
+       }
+}
+
+PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PRInt32 fd, PR_fd_set *set)
+{
+    PRUint32 index;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_NISSET (PR_Select)", "PR_Poll");
+    for (index = 0; index<set->nsize; index++)
+       if (set->narray[index] == fd) {
+           return 1;
+       }
+    return 0;
+}
+
+#include <sys/types.h>
+#include <sys/time.h>
+#if !defined(SUNOS4) && !defined(HPUX) \
+    && !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__)
+#include <sys/select.h>
+#endif
+
+static PRInt32
+_PR_getset(PR_fd_set *pr_set, fd_set *set)
+{
+    PRUint32 index;
+    PRInt32 max = 0;
+
+    if (!pr_set)
+        return 0;
+   
+    FD_ZERO(set);
+
+    /* First set the pr file handle osfds */
+    for (index=0; index<pr_set->hsize; index++) {
+        FD_SET(pr_set->harray[index]->secret->md.osfd, set);
+        if (pr_set->harray[index]->secret->md.osfd > max)
+            max = pr_set->harray[index]->secret->md.osfd;
+    }
+    /* Second set the native osfds */
+    for (index=0; index<pr_set->nsize; index++) {
+        FD_SET(pr_set->narray[index], set);
+        if (pr_set->narray[index] > max)
+            max = pr_set->narray[index];
+    }
+    return max;
+}
+
+static void
+_PR_setset(PR_fd_set *pr_set, fd_set *set)
+{
+    PRUint32 index, last_used;
+
+    if (!pr_set)
+        return;
+
+    for (last_used=0, index=0; index<pr_set->hsize; index++) {
+        if ( FD_ISSET(pr_set->harray[index]->secret->md.osfd, set) ) {
+            pr_set->harray[last_used++] = pr_set->harray[index];
+        }
+    }
+    pr_set->hsize = last_used;
+
+    for (last_used=0, index=0; index<pr_set->nsize; index++) {
+        if ( FD_ISSET(pr_set->narray[index], set) ) {
+            pr_set->narray[last_used++] = pr_set->narray[index];
+        }
+    }
+    pr_set->nsize = last_used;
+}
+
+PR_IMPLEMENT(PRInt32) PR_Select(
+    PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, 
+    PR_fd_set *pr_ex, PRIntervalTime timeout)
+{
+    fd_set rd, wr, ex;
+    struct timeval tv, *tvp;
+    PRInt32 max, max_fd;
+    PRInt32 rv;
+    /*
+     * For restarting select() if it is interrupted by a Unix signal.
+     * We use these variables to figure out how much time has elapsed
+     * and how much of the timeout still remains.
+     */
+    PRIntervalTime start, elapsed, remaining;
+
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete( "PR_Select", "PR_Poll");
+
+    FD_ZERO(&rd);
+    FD_ZERO(&wr);
+    FD_ZERO(&ex);
+
+    max_fd = _PR_getset(pr_rd, &rd);
+    max_fd = (max = _PR_getset(pr_wr, &wr))>max_fd?max:max_fd;
+    max_fd = (max = _PR_getset(pr_ex, &ex))>max_fd?max:max_fd;
+
+    if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+        tvp = NULL;
+    } else {
+        tv.tv_sec = (PRInt32)PR_IntervalToSeconds(timeout);
+        tv.tv_usec = (PRInt32)PR_IntervalToMicroseconds(
+                timeout - PR_SecondsToInterval(tv.tv_sec));
+        tvp = &tv;
+        start = PR_IntervalNow();
+    }
+
+retry:
+    rv = select(max_fd + 1, (_PRSelectFdSetArg_t) &rd,
+        (_PRSelectFdSetArg_t) &wr, (_PRSelectFdSetArg_t) &ex, tvp);
+
+    if (rv == -1 && errno == EINTR) {
+        if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+            goto retry;
+        } else {
+            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+            if (elapsed > timeout) {
+                rv = 0;  /* timed out */
+            } else {
+                remaining = timeout - elapsed;
+                tv.tv_sec = (PRInt32)PR_IntervalToSeconds(remaining);
+                tv.tv_usec = (PRInt32)PR_IntervalToMicroseconds(
+                        remaining - PR_SecondsToInterval(tv.tv_sec));
+                goto retry;
+            }
+        }
+    }
+
+    if (rv > 0) {
+        _PR_setset(pr_rd, &rd);
+        _PR_setset(pr_wr, &wr);
+        _PR_setset(pr_ex, &ex);
+    } else if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_SELECT_ERROR, errno);
+    }
+    return rv;
+}
+#endif /* defined(_PR_PTHREADS) */
+
+#ifdef MOZ_UNICODE 
+/* ================ UTF16 Interfaces ================================ */
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
+    const PRUnichar *name, PRIntn flags, PRIntn mode)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDir *dir)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+/* ================ UTF16 Interfaces ================================ */
+#endif /* MOZ_UNICODE */
+
+/* ptio.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptmisc.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptmisc.c
new file mode 100644
index 0000000..920d00d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptmisc.c
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:   ptmisc.c
+** Descritpion:  Implemenation of miscellaneous methods for pthreads
+*/
+
+#if defined(_PR_PTHREADS)
+
+#include "primpl.h"
+
+#include <stdio.h>
+#ifdef SOLARIS
+#include <thread.h>
+#endif
+
+#define PT_LOG(f)
+
+void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")}
+void _PR_InitStacks(void) {PT_LOG("_PR_InitStacks")}
+
+PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs) 
+{
+#ifdef SOLARIS
+	thr_setconcurrency(numCPUs);	
+#else
+	PT_LOG("PR_SetConcurrency");
+#endif
+}
+
+PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 flag)
+    {PT_LOG("PR_SetThreadRecycleMode")}
+
+#endif /* defined(_PR_PTHREADS) */
+
+/* ptmisc.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptsynch.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptsynch.c
new file mode 100644
index 0000000..f90917e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptsynch.c
@@ -0,0 +1,1170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:            ptsynch.c
+** Descritpion:        Implemenation for thread synchronization using pthreads
+** Exports:            prlock.h, prcvar.h, prmon.h, prcmon.h
+*/
+
+#if defined(_PR_PTHREADS)
+
+#include "primpl.h"
+#include "obsolete/prsem.h"
+
+#include <string.h>
+#include <pthread.h>
+#include <sys/time.h>
+
+static pthread_mutexattr_t _pt_mattr;
+static pthread_condattr_t _pt_cvar_attr;
+
+#if defined(DEBUG)
+extern PTDebug pt_debug;  /* this is shared between several modules */
+
+#if defined(_PR_DCETHREADS)
+static pthread_t pt_zero_tid;  /* a null pthread_t (pthread_t is a struct
+                                * in DCE threads) to compare with */
+#endif  /* defined(_PR_DCETHREADS) */
+#endif  /* defined(DEBUG) */
+
+#if defined(FREEBSD)
+/*
+ * On older versions of FreeBSD, pthread_mutex_trylock returns EDEADLK.
+ * Newer versions return EBUSY.  We still need to support both.
+ */
+static int
+pt_pthread_mutex_is_locked(pthread_mutex_t *m)
+{
+    int rv = pthread_mutex_trylock(m);
+    return (EBUSY == rv || EDEADLK == rv);
+}
+#endif
+
+/**************************************************************/
+/**************************************************************/
+/*****************************LOCKS****************************/
+/**************************************************************/
+/**************************************************************/
+
+void _PR_InitLocks(void)
+{
+    int rv;
+    rv = _PT_PTHREAD_MUTEXATTR_INIT(&_pt_mattr); 
+    PR_ASSERT(0 == rv);
+
+#ifdef LINUX
+#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
+    rv = pthread_mutexattr_settype(&_pt_mattr, PTHREAD_MUTEX_ADAPTIVE_NP);
+    PR_ASSERT(0 == rv);
+#endif
+#endif
+
+    rv = _PT_PTHREAD_CONDATTR_INIT(&_pt_cvar_attr);
+    PR_ASSERT(0 == rv);
+}
+
+static void pt_PostNotifies(PRLock *lock, PRBool unlock)
+{
+    PRIntn index, rv;
+    _PT_Notified post;
+    _PT_Notified *notified, *prev = NULL;
+    /*
+     * Time to actually notify any conditions that were affected
+     * while the lock was held. Get a copy of the list that's in
+     * the lock structure and then zero the original. If it's
+     * linked to other such structures, we own that storage.
+     */
+    post = lock->notified;  /* a safe copy; we own the lock */
+
+#if defined(DEBUG)
+    memset(&lock->notified, 0, sizeof(_PT_Notified));  /* reset */
+#else
+    lock->notified.length = 0;  /* these are really sufficient */
+    lock->notified.link = NULL;
+#endif
+
+    /* should (may) we release lock before notifying? */
+    if (unlock)
+    {
+        rv = pthread_mutex_unlock(&lock->mutex);
+        PR_ASSERT(0 == rv);
+    }
+
+    notified = &post;  /* this is where we start */
+    do
+    {
+        for (index = 0; index < notified->length; ++index)
+        {
+            PRCondVar *cv = notified->cv[index].cv;
+            PR_ASSERT(NULL != cv);
+            PR_ASSERT(0 != notified->cv[index].times);
+            if (-1 == notified->cv[index].times)
+            {
+                rv = pthread_cond_broadcast(&cv->cv);
+                PR_ASSERT(0 == rv);
+            }
+            else
+            {
+                while (notified->cv[index].times-- > 0)
+                {
+                    rv = pthread_cond_signal(&cv->cv);
+                    PR_ASSERT(0 == rv);
+                }
+            }
+#if defined(DEBUG)
+            pt_debug.cvars_notified += 1;
+            if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending))
+            {
+                pt_debug.delayed_cv_deletes += 1;
+                PR_DestroyCondVar(cv);
+            }
+#else  /* defined(DEBUG) */
+            if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending))
+                PR_DestroyCondVar(cv);
+#endif  /* defined(DEBUG) */
+        }
+        prev = notified;
+        notified = notified->link;
+        if (&post != prev) PR_DELETE(prev);
+    } while (NULL != notified);
+}  /* pt_PostNotifies */
+
+PR_IMPLEMENT(PRLock*) PR_NewLock(void)
+{
+    PRIntn rv;
+    PRLock *lock;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    lock = PR_NEWZAP(PRLock);
+    if (lock != NULL)
+    {
+        rv = _PT_PTHREAD_MUTEX_INIT(lock->mutex, _pt_mattr); 
+        PR_ASSERT(0 == rv);
+    }
+#if defined(DEBUG)
+    pt_debug.locks_created += 1;
+#endif
+    return lock;
+}  /* PR_NewLock */
+
+PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock)
+{
+    PRIntn rv;
+    PR_ASSERT(NULL != lock);
+    PR_ASSERT(PR_FALSE == lock->locked);
+    PR_ASSERT(0 == lock->notified.length);
+    PR_ASSERT(NULL == lock->notified.link);
+    rv = pthread_mutex_destroy(&lock->mutex);
+    PR_ASSERT(0 == rv);
+#if defined(DEBUG)
+    memset(lock, 0xaf, sizeof(PRLock));
+    pt_debug.locks_destroyed += 1;
+#endif
+    PR_Free(lock);
+}  /* PR_DestroyLock */
+
+PR_IMPLEMENT(void) PR_Lock(PRLock *lock)
+{
+    PRIntn rv;
+    PR_ASSERT(lock != NULL);
+    rv = pthread_mutex_lock(&lock->mutex);
+    PR_ASSERT(0 == rv);
+    PR_ASSERT(0 == lock->notified.length);
+    PR_ASSERT(NULL == lock->notified.link);
+    PR_ASSERT(PR_FALSE == lock->locked);
+    /* Nb: the order of the next two statements is not critical to
+     * the correctness of PR_AssertCurrentThreadOwnsLock(), but 
+     * this particular order makes the assertion more likely to
+     * catch errors. */
+    lock->owner = pthread_self();
+    lock->locked = PR_TRUE;
+#if defined(DEBUG)
+    pt_debug.locks_acquired += 1;
+#endif
+}  /* PR_Lock */
+
+PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock)
+{
+    PRIntn rv;
+
+    PR_ASSERT(lock != NULL);
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(lock->mutex));
+    PR_ASSERT(PR_TRUE == lock->locked);
+    PR_ASSERT(pthread_equal(lock->owner, pthread_self()));
+
+    if (!lock->locked || !pthread_equal(lock->owner, pthread_self()))
+        return PR_FAILURE;
+
+    lock->locked = PR_FALSE;
+    if (0 == lock->notified.length)  /* shortcut */
+    {
+        rv = pthread_mutex_unlock(&lock->mutex);
+        PR_ASSERT(0 == rv);
+    }
+    else pt_PostNotifies(lock, PR_TRUE);
+
+#if defined(DEBUG)
+    pt_debug.locks_released += 1;
+#endif
+    return PR_SUCCESS;
+}  /* PR_Unlock */
+
+PR_IMPLEMENT(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock)
+{
+    /* Nb: the order of the |locked| and |owner==me| checks is not critical 
+     * to the correctness of PR_AssertCurrentThreadOwnsLock(), but 
+     * this particular order makes the assertion more likely to
+     * catch errors. */
+    PR_ASSERT(lock->locked && pthread_equal(lock->owner, pthread_self()));
+}
+
+/**************************************************************/
+/**************************************************************/
+/***************************CONDITIONS*************************/
+/**************************************************************/
+/**************************************************************/
+
+
+/*
+ * This code is used to compute the absolute time for the wakeup.
+ * It's moderately ugly, so it's defined here and called in a
+ * couple of places.
+ */
+#define PT_NANOPERMICRO 1000UL
+#define PT_BILLION 1000000000UL
+
+static PRIntn pt_TimedWait(
+    pthread_cond_t *cv, pthread_mutex_t *ml, PRIntervalTime timeout)
+{
+    int rv;
+    struct timeval now;
+    struct timespec tmo;
+    PRUint32 ticks = PR_TicksPerSecond();
+
+    tmo.tv_sec = (PRInt32)(timeout / ticks);
+    tmo.tv_nsec = (PRInt32)(timeout - (tmo.tv_sec * ticks));
+    tmo.tv_nsec = (PRInt32)PR_IntervalToMicroseconds(PT_NANOPERMICRO * tmo.tv_nsec);
+
+    /* pthreads wants this in absolute time, off we go ... */
+    (void)GETTIMEOFDAY(&now);
+    /* that one's usecs, this one's nsecs - grrrr! */
+    tmo.tv_sec += now.tv_sec;
+    tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
+    tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
+    tmo.tv_nsec %= PT_BILLION;
+
+    rv = pthread_cond_timedwait(cv, ml, &tmo);
+
+    /* NSPR doesn't report timeouts */
+#ifdef _PR_DCETHREADS
+    if (rv == -1) return (errno == EAGAIN) ? 0 : errno;
+    else return rv;
+#else
+    return (rv == ETIMEDOUT) ? 0 : rv;
+#endif
+}  /* pt_TimedWait */
+
+
+/*
+ * Notifies just get posted to the protecting mutex. The
+ * actual notification is done when the lock is released so that
+ * MP systems don't contend for a lock that they can't have.
+ */
+static void pt_PostNotifyToCvar(PRCondVar *cvar, PRBool broadcast)
+{
+    PRIntn index = 0;
+    _PT_Notified *notified = &cvar->lock->notified;
+
+    PR_ASSERT(PR_TRUE == cvar->lock->locked);
+    PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self()));
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(cvar->lock->mutex));
+
+    while (1)
+    {
+        for (index = 0; index < notified->length; ++index)
+        {
+            if (notified->cv[index].cv == cvar)
+            {
+                if (broadcast)
+                    notified->cv[index].times = -1;
+                else if (-1 != notified->cv[index].times)
+                    notified->cv[index].times += 1;
+                goto finished;  /* we're finished */
+            }
+        }
+        /* if not full, enter new CV in this array */
+        if (notified->length < PT_CV_NOTIFIED_LENGTH) break;
+
+        /* if there's no link, create an empty array and link it */
+        if (NULL == notified->link)
+            notified->link = PR_NEWZAP(_PT_Notified);
+        notified = notified->link;
+    }
+
+    /* A brand new entry in the array */
+    (void)PR_ATOMIC_INCREMENT(&cvar->notify_pending);
+    notified->cv[index].times = (broadcast) ? -1 : 1;
+    notified->cv[index].cv = cvar;
+    notified->length += 1;
+
+finished:
+    PR_ASSERT(PR_TRUE == cvar->lock->locked);
+    PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self()));
+}  /* pt_PostNotifyToCvar */
+
+PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock)
+{
+    PRCondVar *cv = PR_NEW(PRCondVar);
+    PR_ASSERT(lock != NULL);
+    if (cv != NULL)
+    {
+        int rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); 
+        PR_ASSERT(0 == rv);
+        cv->lock = lock;
+        cv->notify_pending = 0;
+#if defined(DEBUG)
+        pt_debug.cvars_created += 1;
+#endif
+    }
+    return cv;
+}  /* PR_NewCondVar */
+
+PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar)
+{
+    if (0 > PR_ATOMIC_DECREMENT(&cvar->notify_pending))
+    {
+        PRIntn rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv);
+#if defined(DEBUG)
+        memset(cvar, 0xaf, sizeof(PRCondVar));
+        pt_debug.cvars_destroyed += 1;
+#endif
+        PR_Free(cvar);
+    }
+}  /* PR_DestroyCondVar */
+
+PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout)
+{
+    PRIntn rv;
+    PRThread *thred = PR_GetCurrentThread();
+
+    PR_ASSERT(cvar != NULL);
+    /* We'd better be locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(cvar->lock->mutex));
+    PR_ASSERT(PR_TRUE == cvar->lock->locked);
+    /* and it better be by us */
+    PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self()));
+
+    if (_PT_THREAD_INTERRUPTED(thred)) goto aborted;
+
+    /*
+     * The thread waiting is used for PR_Interrupt
+     */
+    thred->waiting = cvar;  /* this is where we're waiting */
+
+    /*
+     * If we have pending notifies, post them now.
+     *
+     * This is not optimal. We're going to post these notifies
+     * while we're holding the lock. That means on MP systems
+     * that they are going to collide for the lock that we will
+     * hold until we actually wait.
+     */
+    if (0 != cvar->lock->notified.length)
+        pt_PostNotifies(cvar->lock, PR_FALSE);
+
+    /*
+     * We're surrendering the lock, so clear out the locked field.
+     */
+    cvar->lock->locked = PR_FALSE;
+
+    if (timeout == PR_INTERVAL_NO_TIMEOUT)
+        rv = pthread_cond_wait(&cvar->cv, &cvar->lock->mutex);
+    else
+        rv = pt_TimedWait(&cvar->cv, &cvar->lock->mutex, timeout);
+
+    /* We just got the lock back - this better be empty */
+    PR_ASSERT(PR_FALSE == cvar->lock->locked);
+    cvar->lock->locked = PR_TRUE;
+    cvar->lock->owner = pthread_self();
+
+    PR_ASSERT(0 == cvar->lock->notified.length);
+    thred->waiting = NULL;  /* and now we're not */
+    if (_PT_THREAD_INTERRUPTED(thred)) goto aborted;
+    if (rv != 0)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(rv);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+
+aborted:
+    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    thred->state &= ~PT_THREAD_ABORTED;
+    return PR_FAILURE;
+}  /* PR_WaitCondVar */
+
+PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar)
+{
+    PR_ASSERT(cvar != NULL);   
+    pt_PostNotifyToCvar(cvar, PR_FALSE);
+    return PR_SUCCESS;
+}  /* PR_NotifyCondVar */
+
+PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar)
+{
+    PR_ASSERT(cvar != NULL);
+    pt_PostNotifyToCvar(cvar, PR_TRUE);
+    return PR_SUCCESS;
+}  /* PR_NotifyAllCondVar */
+
+/**************************************************************/
+/**************************************************************/
+/***************************MONITORS***************************/
+/**************************************************************/
+/**************************************************************/
+
+PR_IMPLEMENT(PRMonitor*) PR_NewMonitor(void)
+{
+    PRMonitor *mon;
+    PRCondVar *cvar;
+    int rv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    cvar = PR_NEWZAP(PRCondVar);
+    if (NULL == cvar)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    mon = PR_NEWZAP(PRMonitor);
+    if (mon == NULL)
+    {
+        PR_Free(cvar);
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    rv = _PT_PTHREAD_MUTEX_INIT(mon->lock.mutex, _pt_mattr); 
+    PR_ASSERT(0 == rv);
+    if (0 != rv)
+    {
+        PR_Free(mon);
+        PR_Free(cvar);
+        PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
+        return NULL;
+    }
+
+    _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);
+
+    mon->cvar = cvar;
+    rv = _PT_PTHREAD_COND_INIT(mon->cvar->cv, _pt_cvar_attr); 
+    PR_ASSERT(0 == rv);
+    mon->entryCount = 0;
+    mon->cvar->lock = &mon->lock;
+    if (0 != rv)
+    {
+        pthread_mutex_destroy(&mon->lock.mutex);
+        PR_Free(mon);
+        PR_Free(cvar);
+        PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
+        return NULL;
+    }
+    return mon;
+}  /* PR_NewMonitor */
+
+PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name)
+{
+    PRMonitor* mon = PR_NewMonitor();
+    if (mon)
+        mon->name = name;
+    return mon;
+}
+
+PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon)
+{
+    int rv;
+    PR_ASSERT(mon != NULL);
+    PR_DestroyCondVar(mon->cvar);
+    rv = pthread_mutex_destroy(&mon->lock.mutex); PR_ASSERT(0 == rv);
+#if defined(DEBUG)
+        memset(mon, 0xaf, sizeof(PRMonitor));
+#endif
+    PR_Free(mon);    
+}  /* PR_DestroyMonitor */
+
+
+/* The GC uses this; it is quite arguably a bad interface.  I'm just 
+ * duplicating it for now - XXXMB
+ */
+PR_IMPLEMENT(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon)
+{
+    pthread_t self = pthread_self();
+    if (pthread_equal(mon->owner, self))
+        return mon->entryCount;
+    return 0;
+}
+
+PR_IMPLEMENT(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon)
+{
+    PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(&mon->lock);
+}
+
+PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon)
+{
+    pthread_t self = pthread_self();
+
+    PR_ASSERT(mon != NULL);
+    /*
+     * This is safe only if mon->owner (a pthread_t) can be
+     * read in one instruction.  Perhaps mon->owner should be
+     * a "PRThread *"?
+     */
+    if (!pthread_equal(mon->owner, self))
+    {
+        PR_Lock(&mon->lock);
+        /* and now I have the lock */
+        PR_ASSERT(0 == mon->entryCount);
+        PR_ASSERT(_PT_PTHREAD_THR_HANDLE_IS_INVALID(mon->owner));
+        _PT_PTHREAD_COPY_THR_HANDLE(self, mon->owner);
+    }
+    mon->entryCount += 1;
+}  /* PR_EnterMonitor */
+
+PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon)
+{
+    pthread_t self = pthread_self();
+
+    PR_ASSERT(mon != NULL);
+    /* The lock better be that - locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
+    /* we'd better be the owner */
+    PR_ASSERT(pthread_equal(mon->owner, self));
+    if (!pthread_equal(mon->owner, self))
+        return PR_FAILURE;
+
+    /* if it's locked and we have it, then the entries should be > 0 */
+    PR_ASSERT(mon->entryCount > 0);
+    mon->entryCount -= 1;  /* reduce by one */
+    if (mon->entryCount == 0)
+    {
+        /* and if it transitioned to zero - unlock */
+        _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);  /* make the owner unknown */
+        PR_Unlock(&mon->lock);
+    }
+    return PR_SUCCESS;
+}  /* PR_ExitMonitor */
+
+PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRInt16 saved_entries;
+    pthread_t saved_owner;
+
+    PR_ASSERT(mon != NULL);
+    /* we'd better be locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
+    /* and the entries better be positive */
+    PR_ASSERT(mon->entryCount > 0);
+    /* and it better be by us */
+    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
+
+    /* tuck these away 'till later */
+    saved_entries = mon->entryCount; 
+    mon->entryCount = 0;
+    _PT_PTHREAD_COPY_THR_HANDLE(mon->owner, saved_owner);
+    _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);
+    
+    rv = PR_WaitCondVar(mon->cvar, timeout);
+
+    /* reinstate the intresting information */
+    mon->entryCount = saved_entries;
+    _PT_PTHREAD_COPY_THR_HANDLE(saved_owner, mon->owner);
+
+    return rv;
+}  /* PR_Wait */
+
+PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon)
+{
+    PR_ASSERT(NULL != mon);
+    /* we'd better be locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
+    /* and the entries better be positive */
+    PR_ASSERT(mon->entryCount > 0);
+    /* and it better be by us */
+    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
+
+    pt_PostNotifyToCvar(mon->cvar, PR_FALSE);
+
+    return PR_SUCCESS;
+}  /* PR_Notify */
+
+PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon)
+{
+    PR_ASSERT(mon != NULL);
+    /* we'd better be locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
+    /* and the entries better be positive */
+    PR_ASSERT(mon->entryCount > 0);
+    /* and it better be by us */
+    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
+
+    pt_PostNotifyToCvar(mon->cvar, PR_TRUE);
+
+    return PR_SUCCESS;
+}  /* PR_NotifyAll */
+
+/**************************************************************/
+/**************************************************************/
+/**************************SEMAPHORES**************************/
+/**************************************************************/
+/**************************************************************/
+PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *semaphore)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete(
+        "PR_PostSem", "locks & condition variables");
+	PR_Lock(semaphore->cvar->lock);
+	PR_NotifyCondVar(semaphore->cvar);
+	semaphore->count += 1;
+	PR_Unlock(semaphore->cvar->lock);
+}  /* PR_PostSem */
+
+PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *semaphore)
+{
+	PRStatus status = PR_SUCCESS;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete(
+        "PR_WaitSem", "locks & condition variables");
+	PR_Lock(semaphore->cvar->lock);
+	while ((semaphore->count == 0) && (PR_SUCCESS == status))
+		status = PR_WaitCondVar(semaphore->cvar, PR_INTERVAL_NO_TIMEOUT);
+	if (PR_SUCCESS == status) semaphore->count -= 1;
+	PR_Unlock(semaphore->cvar->lock);
+	return status;
+}  /* PR_WaitSem */
+
+PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *semaphore)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete(
+        "PR_DestroySem", "locks & condition variables");
+    PR_DestroyLock(semaphore->cvar->lock);
+    PR_DestroyCondVar(semaphore->cvar);
+    PR_Free(semaphore);
+}  /* PR_DestroySem */
+
+PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value)
+{
+    PRSemaphore *semaphore;
+    static PRBool unwarned = PR_TRUE;
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (unwarned) unwarned = _PR_Obsolete(
+        "PR_NewSem", "locks & condition variables");
+
+    semaphore = PR_NEWZAP(PRSemaphore);
+    if (NULL != semaphore)
+    {
+        PRLock *lock = PR_NewLock();
+        if (NULL != lock)
+        {
+            semaphore->cvar = PR_NewCondVar(lock);
+            if (NULL != semaphore->cvar)
+            {
+                semaphore->count = value;
+                return semaphore;
+            }
+            PR_DestroyLock(lock);
+        }
+        PR_Free(semaphore);
+    }
+    return NULL;
+}
+
+/*
+ * Define the interprocess named semaphore functions.
+ * There are three implementations:
+ * 1. POSIX semaphore based;
+ * 2. System V semaphore based;
+ * 3. unsupported (fails with PR_NOT_IMPLEMENTED_ERROR).
+ */
+
+#ifdef _PR_HAVE_POSIX_SEMAPHORES
+#include <fcntl.h>
+
+PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(
+    const char *name,
+    PRIntn flags,
+    PRIntn mode,
+    PRUintn value)
+{
+    PRSem *sem;
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+        == PR_FAILURE)
+    {
+        return NULL;
+    }
+
+    sem = PR_NEW(PRSem);
+    if (NULL == sem)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    if (flags & PR_SEM_CREATE)
+    {
+        int oflag = O_CREAT;
+
+        if (flags & PR_SEM_EXCL) oflag |= O_EXCL;
+        sem->sem = sem_open(osname, oflag, mode, value);
+    }
+    else
+    {
+#ifdef HPUX
+        /* Pass 0 as the mode and value arguments to work around a bug. */
+        sem->sem = sem_open(osname, 0, 0, 0);
+#else
+        sem->sem = sem_open(osname, 0);
+#endif
+    }
+    if ((sem_t *) -1 == sem->sem)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        PR_Free(sem);
+        return NULL;
+    }
+    return sem;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem)
+{
+    int rv;
+    rv = sem_wait(sem->sem);
+    if (0 != rv)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem)
+{
+    int rv;
+    rv = sem_post(sem->sem);
+    if (0 != rv)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem)
+{
+    int rv;
+    rv = sem_close(sem->sem);
+    if (0 != rv)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    PR_Free(sem);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
+{
+    int rv;
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+        == PR_FAILURE)
+    {
+        return PR_FAILURE;
+    }
+    rv = sem_unlink(osname);
+    if (0 != rv)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+    
+#elif defined(_PR_HAVE_SYSV_SEMAPHORES)
+
+#include <fcntl.h>
+#include <sys/sem.h>
+
+/*
+ * From the semctl(2) man page in glibc 2.0
+ */
+#if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \
+    || defined(FREEBSD) || defined(OPENBSD) || defined(BSDI) \
+    || defined(DARWIN) || defined(SYMBIAN)
+/* union semun is defined by including <sys/sem.h> */
+#else
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+    int val;
+    struct semid_ds *buf;
+    unsigned short  *array;
+};
+#endif
+
+/*
+ * 'a' (97) is the final closing price of NSCP stock.
+ */
+#define NSPR_IPC_KEY_ID 'a'  /* the id argument for ftok() */
+
+#define NSPR_SEM_MODE 0666
+
+PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(
+    const char *name,
+    PRIntn flags,
+    PRIntn mode,
+    PRUintn value)
+{
+    PRSem *sem;
+    key_t key;
+    union semun arg;
+    struct sembuf sop;
+    struct semid_ds seminfo;
+#define MAX_TRIES 60
+    PRIntn i;
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+        == PR_FAILURE)
+    {
+        return NULL;
+    }
+
+    /* Make sure the file exists before calling ftok. */
+    if (flags & PR_SEM_CREATE)
+    {
+        int osfd = open(osname, O_RDWR|O_CREAT, mode);
+        if (-1 == osfd)
+        {
+            _PR_MD_MAP_OPEN_ERROR(errno);
+            return NULL;
+        }
+        if (close(osfd) == -1)
+        {
+            _PR_MD_MAP_CLOSE_ERROR(errno);
+            return NULL;
+        }
+    }
+    key = ftok(osname, NSPR_IPC_KEY_ID);
+    if ((key_t)-1 == key)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return NULL;
+    }
+
+    sem = PR_NEW(PRSem);
+    if (NULL == sem)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    if (flags & PR_SEM_CREATE)
+    {
+        sem->semid = semget(key, 1, mode|IPC_CREAT|IPC_EXCL);
+        if (sem->semid >= 0)
+        {
+            /* creator of a semaphore is responsible for initializing it */
+            arg.val = 0;
+            if (semctl(sem->semid, 0, SETVAL, arg) == -1)
+            {
+                _PR_MD_MAP_DEFAULT_ERROR(errno);
+                PR_Free(sem);
+                return NULL;
+            }
+            /* call semop to set sem_otime to nonzero */
+            sop.sem_num = 0;
+            sop.sem_op = value;
+            sop.sem_flg = 0;
+            if (semop(sem->semid, &sop, 1) == -1)
+            {
+                _PR_MD_MAP_DEFAULT_ERROR(errno);
+                PR_Free(sem);
+                return NULL;
+            }
+            return sem;
+        }
+
+        if (errno != EEXIST || flags & PR_SEM_EXCL)
+        {
+            _PR_MD_MAP_DEFAULT_ERROR(errno);
+            PR_Free(sem);
+            return NULL;
+        }
+    }
+
+    sem->semid = semget(key, 1, NSPR_SEM_MODE);
+    if (sem->semid == -1)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        PR_Free(sem);
+        return NULL;
+    }
+    for (i = 0; i < MAX_TRIES; i++)
+    {
+        arg.buf = &seminfo;
+        semctl(sem->semid, 0, IPC_STAT, arg);
+        if (seminfo.sem_otime != 0) break;
+        sleep(1);
+    }
+    if (i == MAX_TRIES)
+    {
+        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        PR_Free(sem);
+        return NULL;
+    }
+    return sem;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem)
+{
+    struct sembuf sop;
+
+    sop.sem_num = 0;
+    sop.sem_op = -1;
+    sop.sem_flg = 0;
+    if (semop(sem->semid, &sop, 1) == -1)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem)
+{
+    struct sembuf sop;
+
+    sop.sem_num = 0;
+    sop.sem_op = 1;
+    sop.sem_flg = 0;
+    if (semop(sem->semid, &sop, 1) == -1)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem)
+{
+    PR_Free(sem);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
+{
+    key_t key;
+    int semid;
+    /* On some systems (e.g., glibc 2.0) semctl requires a fourth argument */
+    union semun unused;
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+        == PR_FAILURE)
+    {
+        return PR_FAILURE;
+    }
+    key = ftok(osname, NSPR_IPC_KEY_ID);
+    if ((key_t) -1 == key)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    if (unlink(osname) == -1)
+    {
+        _PR_MD_MAP_UNLINK_ERROR(errno);
+        return PR_FAILURE;
+    }
+    semid = semget(key, 1, NSPR_SEM_MODE);
+    if (-1 == semid)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    unused.val = 0;
+    if (semctl(semid, 0, IPC_RMID, unused) == -1)
+    { 
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+#else /* neither POSIX nor System V semaphores are available */
+
+PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(
+    const char *name,
+    PRIntn flags,
+    PRIntn mode,
+    PRUintn value)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+#endif /* end of interprocess named semaphore functions */
+
+/**************************************************************/
+/**************************************************************/
+/******************ROUTINES FOR DCE EMULATION******************/
+/**************************************************************/
+/**************************************************************/
+
+#include "prpdce.h"
+
+PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock)
+{
+    PRIntn rv = pthread_mutex_trylock(&lock->mutex);
+    if (rv == PT_TRYLOCK_SUCCESS)
+    {
+        PR_ASSERT(PR_FALSE == lock->locked);
+        lock->locked = PR_TRUE;
+        lock->owner = pthread_self();
+    }
+    /* XXX set error code? */
+    return (PT_TRYLOCK_SUCCESS == rv) ? PR_SUCCESS : PR_FAILURE;
+}  /* PRP_TryLock */
+
+PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void)
+{
+    PRCondVar *cv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    cv = PR_NEW(PRCondVar);
+    if (cv != NULL)
+    {
+        int rv;
+        rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); 
+        PR_ASSERT(0 == rv);
+        cv->lock = _PR_NAKED_CV_LOCK;
+    }
+    return cv;
+}  /* PRP_NewNakedCondVar */
+
+PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar)
+{
+    int rv;
+    rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv);
+#if defined(DEBUG)
+        memset(cvar, 0xaf, sizeof(PRCondVar));
+#endif
+    PR_Free(cvar);
+}  /* PRP_DestroyNakedCondVar */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedWait(
+    PRCondVar *cvar, PRLock *ml, PRIntervalTime timeout)
+{
+    PRIntn rv;
+    PR_ASSERT(cvar != NULL);
+    /* XXX do we really want to assert this in a naked wait? */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(ml->mutex));
+    if (timeout == PR_INTERVAL_NO_TIMEOUT)
+        rv = pthread_cond_wait(&cvar->cv, &ml->mutex);
+    else
+        rv = pt_TimedWait(&cvar->cv, &ml->mutex, timeout);
+    if (rv != 0)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(rv);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* PRP_NakedWait */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar)
+{
+    int rv;
+    PR_ASSERT(cvar != NULL);
+    rv = pthread_cond_signal(&cvar->cv);
+    PR_ASSERT(0 == rv);
+    return PR_SUCCESS;
+}  /* PRP_NakedNotify */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar)
+{
+    int rv;
+    PR_ASSERT(cvar != NULL);
+    rv = pthread_cond_broadcast(&cvar->cv);
+    PR_ASSERT(0 == rv);
+    return PR_SUCCESS;
+}  /* PRP_NakedBroadcast */
+
+#endif  /* defined(_PR_PTHREADS) */
+
+/* ptsynch.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptthread.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptthread.c
new file mode 100644
index 0000000..b28dc07
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptthread.c
@@ -0,0 +1,1670 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:            ptthread.c
+** Descritpion:        Implemenation for threds using pthreds
+** Exports:            ptthread.h
+*/
+
+#if defined(_PR_PTHREADS) || defined(_PR_DCETHREADS)
+
+#include "prlog.h"
+#include "primpl.h"
+#include "prpdce.h"
+
+#include <pthread.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+
+#ifdef SYMBIAN
+/* In Open C sched_get_priority_min/max do not work properly, so we undefine
+ * _POSIX_THREAD_PRIORITY_SCHEDULING here.
+ */
+#undef _POSIX_THREAD_PRIORITY_SCHEDULING
+#endif
+
+/*
+ * Record whether or not we have the privilege to set the scheduling
+ * policy and priority of threads.  0 means that privilege is available.
+ * EPERM means that privilege is not available.
+ */
+
+static PRIntn pt_schedpriv = 0;
+extern PRLock *_pr_sleeplock;
+
+static struct _PT_Bookeeping
+{
+    PRLock *ml;                 /* a lock to protect ourselves */
+    PRCondVar *cv;              /* used to signal global things */
+    PRInt32 system, user;       /* a count of the two different types */
+    PRUintn this_many;          /* number of threads allowed for exit */
+    pthread_key_t key;          /* private private data key */
+    PRThread *first, *last;     /* list of threads we know about */
+#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+    PRInt32 minPrio, maxPrio;   /* range of scheduling priorities */
+#endif
+} pt_book = {0};
+
+static void _pt_thread_death(void *arg);
+static void _pt_thread_death_internal(void *arg, PRBool callDestructors);
+static void init_pthread_gc_support(void);
+
+#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+static PRIntn pt_PriorityMap(PRThreadPriority pri)
+{
+#ifdef NTO
+    /* This priority algorithm causes lots of problems on Neutrino
+     * for now I have just hard coded everything to run at priority 10
+     * until I can come up with a new algorithm.
+     *     Jerry.Kirk@Nexwarecorp.com
+     */
+    return 10;
+#else
+    return pt_book.minPrio +
+	    pri * (pt_book.maxPrio - pt_book.minPrio) / PR_PRIORITY_LAST;
+#endif
+}
+#endif
+
+#if defined(GC_LEAK_DETECTOR) && (__GLIBC__ >= 2) && defined(__i386__) 
+
+#include <setjmp.h>
+
+typedef struct stack_frame stack_frame;
+
+struct stack_frame {
+    stack_frame* next;
+    void* pc;
+};
+
+static stack_frame* GetStackFrame()
+{
+    jmp_buf jb;
+    stack_frame* currentFrame;
+    setjmp(jb);
+    currentFrame = (stack_frame*)(jb[0].__jmpbuf[JB_BP]);
+    currentFrame = currentFrame->next;
+    return currentFrame;
+}
+
+static void* GetStackTop()
+{
+    stack_frame* frame;
+    frame = GetStackFrame();
+    while (frame != NULL)
+    {
+        ptrdiff_t pc = (ptrdiff_t)frame->pc;
+        if ((pc < 0x08000000) || (pc > 0x7fffffff) || (frame->next < frame))
+            return frame;
+        frame = frame->next;
+    }
+    return NULL;
+}
+#endif /* GC_LEAK_DETECTOR && (__GLIBC__ >= 2) && __i386__ */
+
+/*
+** Initialize a stack for a native pthread thread
+*/
+static void _PR_InitializeStack(PRThreadStack *ts)
+{
+    if( ts && (ts->stackTop == 0) ) {
+        ts->allocBase = (char *) &ts;
+        ts->allocSize = ts->stackSize;
+
+        /*
+        ** Setup stackTop and stackBottom values.
+        */
+#ifdef HAVE_STACK_GROWING_UP
+        ts->stackBottom = ts->allocBase + ts->stackSize;
+        ts->stackTop = ts->allocBase;
+#else
+#ifdef GC_LEAK_DETECTOR
+        ts->stackTop    = GetStackTop();
+        ts->stackBottom = ts->stackTop - ts->stackSize;
+#else
+        ts->stackTop    = ts->allocBase;
+        ts->stackBottom = ts->allocBase - ts->stackSize;
+#endif
+#endif
+    }
+}
+
+static void *_pt_root(void *arg)
+{
+    PRIntn rv;
+    PRThread *thred = (PRThread*)arg;
+    PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE;
+
+    /*
+     * Both the parent thread and this new thread set thred->id.
+     * The new thread must ensure that thred->id is set before
+     * it executes its startFunc.  The parent thread must ensure
+     * that thred->id is set before PR_CreateThread() returns.
+     * Both threads set thred->id without holding a lock.  Since
+     * they are writing the same value, this unprotected double
+     * write should be safe.
+     */
+    thred->id = pthread_self();
+
+    /*
+    ** DCE Threads can't detach during creation, so do it late.
+    ** I would like to do it only here, but that doesn't seem
+    ** to work.
+    */
+#if defined(_PR_DCETHREADS)
+    if (detached)
+    {
+        /* pthread_detach() modifies its argument, so we must pass a copy */
+        pthread_t self = thred->id;
+        rv = pthread_detach(&self);
+        PR_ASSERT(0 == rv);
+    }
+#endif /* defined(_PR_DCETHREADS) */
+
+    /* Set up the thread stack information */
+    _PR_InitializeStack(thred->stack);
+
+    /*
+     * Set within the current thread the pointer to our object.
+     * This object will be deleted when the thread termintates,
+     * whether in a join or detached (see _PR_InitThreads()).
+     */
+    rv = pthread_setspecific(pt_book.key, thred);
+    PR_ASSERT(0 == rv);
+
+    /* make the thread visible to the rest of the runtime */
+    PR_Lock(pt_book.ml);
+
+    /* If this is a GCABLE thread, set its state appropriately */
+    if (thred->suspend & PT_THREAD_SETGCABLE)
+	    thred->state |= PT_THREAD_GCABLE;
+    thred->suspend = 0;
+
+    thred->prev = pt_book.last;
+    if (pt_book.last)
+        pt_book.last->next = thred;
+    else
+        pt_book.first = thred;
+    thred->next = NULL;
+    pt_book.last = thred;
+    PR_Unlock(pt_book.ml);
+
+    thred->startFunc(thred->arg);  /* make visible to the client */
+
+    /* unhook the thread from the runtime */
+    PR_Lock(pt_book.ml);
+    /*
+     * At this moment, PR_CreateThread() may not have set thred->id yet.
+     * It is safe for a detached thread to free thred only after
+     * PR_CreateThread() has set thred->id.
+     */
+    if (detached)
+    {
+        while (!thred->okToDelete)
+            PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    if (thred->state & PT_THREAD_SYSTEM)
+        pt_book.system -= 1;
+    else if (--pt_book.user == pt_book.this_many)
+        PR_NotifyAllCondVar(pt_book.cv);
+    if (NULL == thred->prev)
+        pt_book.first = thred->next;
+    else
+        thred->prev->next = thred->next;
+    if (NULL == thred->next)
+        pt_book.last = thred->prev;
+    else
+        thred->next->prev = thred->prev;
+    PR_Unlock(pt_book.ml);
+
+    /*
+    * Here we set the pthread's backpointer to the PRThread to NULL.
+    * Otherwise the destructor would get called eagerly as the thread
+    * returns to the pthread runtime. The joining thread would them be
+    * the proud possessor of a dangling reference. However, this is the
+    * last chance to delete the object if the thread is detached, so
+    * just let the destructor do the work.
+    */
+    if (PR_FALSE == detached)
+    {
+        /* Call TPD destructors on this thread. */
+        _PR_DestroyThreadPrivate(thred);
+        rv = pthread_setspecific(pt_book.key, NULL);
+        PR_ASSERT(0 == rv);
+    }
+
+    return NULL;
+}  /* _pt_root */
+
+static PRThread* pt_AttachThread(void)
+{
+    PRThread *thred = NULL;
+
+    /*
+     * NSPR must have been initialized when PR_AttachThread is called.
+     * We cannot have PR_AttachThread call implicit initialization
+     * because if multiple threads call PR_AttachThread simultaneously,
+     * NSPR may be initialized more than once.
+     * We can't call any function that calls PR_GetCurrentThread()
+     * either (e.g., PR_SetError()) as that will result in infinite
+     * recursion.
+     */
+    if (!_pr_initialized) return NULL;
+
+    /* PR_NEWZAP must not call PR_GetCurrentThread() */
+    thred = PR_NEWZAP(PRThread);
+    if (NULL != thred)
+    {
+        int rv;
+
+        thred->priority = PR_PRIORITY_NORMAL;
+        thred->id = pthread_self();
+        rv = pthread_setspecific(pt_book.key, thred);
+        PR_ASSERT(0 == rv);
+
+        thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN;
+        PR_Lock(pt_book.ml);
+
+        /* then put it into the list */
+        thred->prev = pt_book.last;
+        if (pt_book.last)
+            pt_book.last->next = thred;
+        else
+            pt_book.first = thred;
+        thred->next = NULL;
+        pt_book.last = thred;
+        PR_Unlock(pt_book.ml);
+
+    }
+    return thred;  /* may be NULL */
+}  /* pt_AttachThread */
+
+static PRThread* _PR_CreateThread(
+    PRThreadType type, void (*start)(void *arg),
+    void *arg, PRThreadPriority priority, PRThreadScope scope,
+    PRThreadState state, PRUint32 stackSize, PRBool isGCAble)
+{
+    int rv;
+    PRThread *thred;
+    pthread_attr_t tattr;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if ((PRIntn)PR_PRIORITY_FIRST > (PRIntn)priority)
+        priority = PR_PRIORITY_FIRST;
+    else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)priority)
+        priority = PR_PRIORITY_LAST;
+
+    rv = _PT_PTHREAD_ATTR_INIT(&tattr);
+    PR_ASSERT(0 == rv);
+
+    if (EPERM != pt_schedpriv)
+    {
+#if !defined(_PR_DCETHREADS) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+        struct sched_param schedule;
+#endif
+
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+        rv = pthread_attr_setinheritsched(&tattr, PTHREAD_EXPLICIT_SCHED);
+        PR_ASSERT(0 == rv);
+#endif
+
+        /* Use the default scheduling policy */
+
+#if defined(_PR_DCETHREADS)
+        rv = pthread_attr_setprio(&tattr, pt_PriorityMap(priority));
+        PR_ASSERT(0 == rv);
+#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+        rv = pthread_attr_getschedparam(&tattr, &schedule);
+        PR_ASSERT(0 == rv);
+        schedule.sched_priority = pt_PriorityMap(priority);
+        rv = pthread_attr_setschedparam(&tattr, &schedule);
+        PR_ASSERT(0 == rv);
+#ifdef NTO
+        rv = pthread_attr_setschedpolicy(&tattr, SCHED_RR); /* Round Robin */
+        PR_ASSERT(0 == rv);
+#endif
+#endif /* !defined(_PR_DCETHREADS) */
+    }
+
+    /*
+     * DCE threads can't set detach state before creating the thread.
+     * AIX can't set detach late. Why can't we all just get along?
+     */
+#if !defined(_PR_DCETHREADS)
+    rv = pthread_attr_setdetachstate(&tattr,
+        ((PR_JOINABLE_THREAD == state) ?
+            PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
+    PR_ASSERT(0 == rv);
+#endif /* !defined(_PR_DCETHREADS) */
+
+    /*
+     * If stackSize is 0, we use the default pthread stack size.
+     */
+    if (stackSize)
+    {
+#ifdef _MD_MINIMUM_STACK_SIZE
+        if (stackSize < _MD_MINIMUM_STACK_SIZE)
+            stackSize = _MD_MINIMUM_STACK_SIZE;
+#endif
+        rv = pthread_attr_setstacksize(&tattr, stackSize);
+        PR_ASSERT(0 == rv);
+    }
+
+    thred = PR_NEWZAP(PRThread);
+    if (NULL == thred)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, errno);
+        goto done;
+    }
+    else
+    {
+        pthread_t id;
+
+        thred->arg = arg;
+        thred->startFunc = start;
+        thred->priority = priority;
+        if (PR_UNJOINABLE_THREAD == state)
+            thred->state |= PT_THREAD_DETACHED;
+
+        if (PR_LOCAL_THREAD == scope)
+        	scope = PR_GLOBAL_THREAD;
+			
+        if (PR_GLOBAL_BOUND_THREAD == scope) {
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+    		rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
+			if (rv) {
+				/*
+				 * system scope not supported
+				 */
+        		scope = PR_GLOBAL_THREAD;
+				/*
+				 * reset scope
+				 */
+    			rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS);
+    			PR_ASSERT(0 == rv);
+			}
+#endif
+		}
+        if (PR_GLOBAL_THREAD == scope)
+            thred->state |= PT_THREAD_GLOBAL;
+        else if (PR_GLOBAL_BOUND_THREAD == scope)
+            thred->state |= (PT_THREAD_GLOBAL | PT_THREAD_BOUND);
+		else	/* force it global */
+            thred->state |= PT_THREAD_GLOBAL;
+        if (PR_SYSTEM_THREAD == type)
+            thred->state |= PT_THREAD_SYSTEM;
+
+        thred->suspend =(isGCAble) ? PT_THREAD_SETGCABLE : 0;
+
+        thred->stack = PR_NEWZAP(PRThreadStack);
+        if (thred->stack == NULL) {
+            PRIntn oserr = errno;
+            PR_Free(thred);  /* all that work ... poof! */
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, oserr);
+            thred = NULL;  /* and for what? */
+            goto done;
+        }
+        thred->stack->stackSize = stackSize;
+        thred->stack->thr = thred;
+
+#ifdef PT_NO_SIGTIMEDWAIT
+        pthread_mutex_init(&thred->suspendResumeMutex,NULL);
+        pthread_cond_init(&thred->suspendResumeCV,NULL);
+#endif
+
+        /* make the thread counted to the rest of the runtime */
+        PR_Lock(pt_book.ml);
+        if (PR_SYSTEM_THREAD == type)
+            pt_book.system += 1;
+        else pt_book.user += 1;
+        PR_Unlock(pt_book.ml);
+
+        /*
+         * We pass a pointer to a local copy (instead of thred->id)
+         * to pthread_create() because who knows what wacky things
+         * pthread_create() may be doing to its argument.
+         */
+        rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred);
+
+#if !defined(_PR_DCETHREADS)
+        if (EPERM == rv)
+        {
+#if defined(IRIX)
+        	if (PR_GLOBAL_BOUND_THREAD == scope) {
+				/*
+				 * SCOPE_SYSTEM requires appropriate privilege
+				 * reset to process scope and try again
+				 */
+    			rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS);
+    			PR_ASSERT(0 == rv);
+            	thred->state &= ~PT_THREAD_BOUND;
+			}
+#else
+            /* Remember that we don't have thread scheduling privilege. */
+            pt_schedpriv = EPERM;
+            PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+                ("_PR_CreateThread: no thread scheduling privilege"));
+            /* Try creating the thread again without setting priority. */
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+            rv = pthread_attr_setinheritsched(&tattr, PTHREAD_INHERIT_SCHED);
+            PR_ASSERT(0 == rv);
+#endif
+#endif	/* IRIX */
+            rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred);
+        }
+#endif
+
+        if (0 != rv)
+        {
+#if defined(_PR_DCETHREADS)
+            PRIntn oserr = errno;
+#else
+            PRIntn oserr = rv;
+#endif
+            PR_Lock(pt_book.ml);
+            if (thred->state & PT_THREAD_SYSTEM)
+                pt_book.system -= 1;
+            else if (--pt_book.user == pt_book.this_many)
+                PR_NotifyAllCondVar(pt_book.cv);
+            PR_Unlock(pt_book.ml);
+
+            PR_Free(thred->stack);
+            PR_Free(thred);  /* all that work ... poof! */
+            PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, oserr);
+            thred = NULL;  /* and for what? */
+            goto done;
+        }
+
+        /*
+         * Both the parent thread and this new thread set thred->id.
+         * The parent thread must ensure that thred->id is set before
+         * PR_CreateThread() returns.  (See comments in _pt_root().)
+         */
+        thred->id = id;
+
+        /*
+         * If the new thread is detached, tell it that PR_CreateThread()
+         * has set thred->id so it's ok to delete thred.
+         */
+        if (PR_UNJOINABLE_THREAD == state)
+        {
+            PR_Lock(pt_book.ml);
+            thred->okToDelete = PR_TRUE;
+            PR_NotifyAllCondVar(pt_book.cv);
+            PR_Unlock(pt_book.ml);
+        }
+    }
+
+done:
+    rv = _PT_PTHREAD_ATTR_DESTROY(&tattr);
+    PR_ASSERT(0 == rv);
+
+    return thred;
+}  /* _PR_CreateThread */
+
+PR_IMPLEMENT(PRThread*) PR_CreateThread(
+    PRThreadType type, void (*start)(void *arg), void *arg,
+    PRThreadPriority priority, PRThreadScope scope,
+    PRThreadState state, PRUint32 stackSize)
+{
+    return _PR_CreateThread(
+        type, start, arg, priority, scope, state, stackSize, PR_FALSE);
+} /* PR_CreateThread */
+
+PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble(
+    PRThreadType type, void (*start)(void *arg), void *arg, 
+    PRThreadPriority priority, PRThreadScope scope,
+    PRThreadState state, PRUint32 stackSize)
+{
+    return _PR_CreateThread(
+        type, start, arg, priority, scope, state, stackSize, PR_TRUE);
+}  /* PR_CreateThreadGCAble */
+
+PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thred)
+{
+    return thred->environment;
+}  /* GetExecutionEnvironment */
+ 
+PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thred, void *env)
+{
+    thred->environment = env;
+}  /* SetExecutionEnvironment */
+
+PR_IMPLEMENT(PRThread*) PR_AttachThread(
+    PRThreadType type, PRThreadPriority priority, PRThreadStack *stack)
+{
+    return PR_GetCurrentThread();
+}  /* PR_AttachThread */
+
+
+PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thred)
+{
+    int rv = -1;
+    void *result = NULL;
+    PR_ASSERT(thred != NULL);
+
+    if ((0xafafafaf == thred->state)
+    || (PT_THREAD_DETACHED == (PT_THREAD_DETACHED & thred->state))
+    || (PT_THREAD_FOREIGN == (PT_THREAD_FOREIGN & thred->state)))
+    {
+        /*
+         * This might be a bad address, but if it isn't, the state should
+         * either be an unjoinable thread or it's already had the object
+         * deleted. However, the client that called join on a detached
+         * thread deserves all the rath I can muster....
+         */
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        PR_LogPrint(
+            "PR_JoinThread: %p not joinable | already smashed\n", thred);
+    }
+    else
+    {
+        pthread_t id = thred->id;
+        rv = pthread_join(id, &result);
+        PR_ASSERT(rv == 0 && result == NULL);
+        if (0 == rv)
+        {
+#ifdef _PR_DCETHREADS
+            rv = pthread_detach(&id);
+            PR_ASSERT(0 == rv);
+#endif
+            /*
+             * PR_FALSE, because the thread already called the TPD
+             * destructors before exiting _pt_root.
+             */
+            _pt_thread_death_internal(thred, PR_FALSE);
+        }
+        else
+        {
+            PRErrorCode prerror;
+            switch (rv)
+            {
+                case EINVAL:  /* not a joinable thread */
+                case ESRCH:   /* no thread with given ID */
+                    prerror = PR_INVALID_ARGUMENT_ERROR;
+                    break;
+                case EDEADLK: /* a thread joining with itself */
+                    prerror = PR_DEADLOCK_ERROR;
+                    break;
+                default:
+                    prerror = PR_UNKNOWN_ERROR;
+                    break;
+            }
+            PR_SetError(prerror, rv);
+        }
+    }
+    return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+}  /* PR_JoinThread */
+
+PR_IMPLEMENT(void) PR_DetachThread(void)
+{
+    void *thred;
+    int rv;
+
+    _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred);
+    if (NULL == thred) return;
+    _pt_thread_death(thred);
+    rv = pthread_setspecific(pt_book.key, NULL);
+    PR_ASSERT(0 == rv);
+}  /* PR_DetachThread */
+
+PR_IMPLEMENT(PRThread*) PR_GetCurrentThread(void)
+{
+    void *thred;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred);
+    if (NULL == thred) thred = pt_AttachThread();
+    PR_ASSERT(NULL != thred);
+    return (PRThread*)thred;
+}  /* PR_GetCurrentThread */
+
+PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thred)
+{
+    return (thred->state & PT_THREAD_BOUND) ?
+        PR_GLOBAL_BOUND_THREAD : PR_GLOBAL_THREAD;
+}  /* PR_GetThreadScope() */
+
+PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thred)
+{
+    return (thred->state & PT_THREAD_SYSTEM) ?
+        PR_SYSTEM_THREAD : PR_USER_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thred)
+{
+    return (thred->state & PT_THREAD_DETACHED) ?
+        PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD;
+}  /* PR_GetThreadState */
+
+PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thred)
+{
+    PR_ASSERT(thred != NULL);
+    return thred->priority;
+}  /* PR_GetThreadPriority */
+
+PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred, PRThreadPriority newPri)
+{
+    PRIntn rv = -1;
+
+    PR_ASSERT(NULL != thred);
+
+    if ((PRIntn)PR_PRIORITY_FIRST > (PRIntn)newPri)
+        newPri = PR_PRIORITY_FIRST;
+    else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)newPri)
+        newPri = PR_PRIORITY_LAST;
+
+#if defined(_PR_DCETHREADS)
+    rv = pthread_setprio(thred->id, pt_PriorityMap(newPri));
+    /* pthread_setprio returns the old priority */
+#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+    if (EPERM != pt_schedpriv)
+    {
+        int policy;
+        struct sched_param schedule;
+
+        rv = pthread_getschedparam(thred->id, &policy, &schedule);
+        if(0 == rv) {
+			schedule.sched_priority = pt_PriorityMap(newPri);
+			rv = pthread_setschedparam(thred->id, policy, &schedule);
+			if (EPERM == rv)
+			{
+				pt_schedpriv = EPERM;
+				PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+					("PR_SetThreadPriority: no thread scheduling privilege"));
+			}
+		}
+		if (rv != 0)
+			rv = -1;
+    }
+#endif
+
+    thred->priority = newPri;
+}  /* PR_SetThreadPriority */
+
+PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred)
+{
+    /*
+    ** If the target thread indicates that it's waiting,
+    ** find the condition and broadcast to it. Broadcast
+    ** since we don't know which thread (if there are more
+    ** than one). This sounds risky, but clients must
+    ** test their invariants when resumed from a wait and
+    ** I don't expect very many threads to be waiting on
+    ** a single condition and I don't expect interrupt to
+    ** be used very often.
+    **
+    ** I don't know why I thought this would work. Must have
+    ** been one of those weaker momements after I'd been
+    ** smelling the vapors.
+    **
+    ** Even with the followng changes it is possible that
+    ** the pointer to the condition variable is pointing
+    ** at a bogus value. Will the unerlying code detect
+    ** that?
+    */
+    PRCondVar *cv;
+    PR_ASSERT(NULL != thred);
+    if (NULL == thred) return PR_FAILURE;
+
+    thred->state |= PT_THREAD_ABORTED;
+
+    cv = thred->waiting;
+    if ((NULL != cv) && !thred->interrupt_blocked)
+    {
+        PRIntn rv;
+        (void)PR_ATOMIC_INCREMENT(&cv->notify_pending);
+        rv = pthread_cond_broadcast(&cv->cv);
+        PR_ASSERT(0 == rv);
+        if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending))
+            PR_DestroyCondVar(cv);
+    }
+    return PR_SUCCESS;
+}  /* PR_Interrupt */
+
+PR_IMPLEMENT(void) PR_ClearInterrupt(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    me->state &= ~PT_THREAD_ABORTED;
+}  /* PR_ClearInterrupt */
+
+PR_IMPLEMENT(void) PR_BlockInterrupt(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    _PT_THREAD_BLOCK_INTERRUPT(me);
+}  /* PR_BlockInterrupt */
+
+PR_IMPLEMENT(void) PR_UnblockInterrupt(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    _PT_THREAD_UNBLOCK_INTERRUPT(me);
+}  /* PR_UnblockInterrupt */
+
+PR_IMPLEMENT(PRStatus) PR_Yield(void)
+{
+    static PRBool warning = PR_TRUE;
+    if (warning) warning = _PR_Obsolete(
+        "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)");
+    return PR_Sleep(PR_INTERVAL_NO_WAIT);
+}
+
+PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (PR_INTERVAL_NO_WAIT == ticks)
+    {
+        _PT_PTHREAD_YIELD();
+    }
+    else
+    {
+        PRCondVar *cv;
+        PRIntervalTime timein;
+
+        timein = PR_IntervalNow();
+        cv = PR_NewCondVar(_pr_sleeplock);
+        PR_ASSERT(cv != NULL);
+        PR_Lock(_pr_sleeplock);
+        do
+        {
+            PRIntervalTime now = PR_IntervalNow();
+            PRIntervalTime delta = now - timein;
+            if (delta > ticks) break;
+            rv = PR_WaitCondVar(cv, ticks - delta);
+        } while (PR_SUCCESS == rv);
+        PR_Unlock(_pr_sleeplock);
+        PR_DestroyCondVar(cv);
+    }
+    return rv;
+}  /* PR_Sleep */
+
+static void _pt_thread_death(void *arg)
+{
+    /* PR_TRUE for: call destructors */ 
+    _pt_thread_death_internal(arg, PR_TRUE);
+}
+
+static void _pt_thread_death_internal(void *arg, PRBool callDestructors)
+{
+    PRThread *thred = (PRThread*)arg;
+
+    if (thred->state & (PT_THREAD_FOREIGN|PT_THREAD_PRIMORD))
+    {
+        PR_Lock(pt_book.ml);
+        if (NULL == thred->prev)
+            pt_book.first = thred->next;
+        else
+            thred->prev->next = thred->next;
+        if (NULL == thred->next)
+            pt_book.last = thred->prev;
+        else
+            thred->next->prev = thred->prev;
+        PR_Unlock(pt_book.ml);
+    }
+    if (callDestructors)
+        _PR_DestroyThreadPrivate(thred);
+    PR_Free(thred->privateData);
+    if (NULL != thred->errorString)
+        PR_Free(thred->errorString);
+    PR_Free(thred->stack);
+    if (NULL != thred->syspoll_list)
+        PR_Free(thred->syspoll_list);
+#if defined(_PR_POLL_WITH_SELECT)
+    if (NULL != thred->selectfd_list)
+        PR_Free(thred->selectfd_list);
+#endif
+#if defined(DEBUG)
+    memset(thred, 0xaf, sizeof(PRThread));
+#endif /* defined(DEBUG) */
+    PR_Free(thred);
+}  /* _pt_thread_death */
+
+void _PR_InitThreads(
+    PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs)
+{
+    int rv;
+    PRThread *thred;
+
+#ifdef _PR_NEED_PTHREAD_INIT
+    /*
+     * On BSD/OS (3.1 and 4.0), the pthread subsystem is lazily
+     * initialized, but pthread_self() fails to initialize
+     * pthreads and hence returns a null thread ID if invoked
+     * by the primordial thread before any other pthread call.
+     * So we explicitly initialize pthreads here.
+     */
+    pthread_init();
+#endif
+
+#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+#if defined(FREEBSD)
+    {
+    pthread_attr_t attr;
+    int policy;
+    /* get the min and max priorities of the default policy */
+    pthread_attr_init(&attr);
+    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+    pthread_attr_getschedpolicy(&attr, &policy);
+    pt_book.minPrio = sched_get_priority_min(policy);
+    PR_ASSERT(-1 != pt_book.minPrio);
+    pt_book.maxPrio = sched_get_priority_max(policy);
+    PR_ASSERT(-1 != pt_book.maxPrio);
+    pthread_attr_destroy(&attr);
+    }
+#else
+    /*
+    ** These might be function evaluations
+    */
+    pt_book.minPrio = PT_PRIO_MIN;
+    pt_book.maxPrio = PT_PRIO_MAX;
+#endif
+#endif
+    
+    PR_ASSERT(NULL == pt_book.ml);
+    pt_book.ml = PR_NewLock();
+    PR_ASSERT(NULL != pt_book.ml);
+    pt_book.cv = PR_NewCondVar(pt_book.ml);
+    PR_ASSERT(NULL != pt_book.cv);
+    thred = PR_NEWZAP(PRThread);
+    PR_ASSERT(NULL != thred);
+    thred->arg = NULL;
+    thred->startFunc = NULL;
+    thred->priority = priority;
+    thred->id = pthread_self();
+
+    thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD);
+    if (PR_SYSTEM_THREAD == type)
+    {
+        thred->state |= PT_THREAD_SYSTEM;
+        pt_book.system += 1;
+	    pt_book.this_many = 0;
+    }
+    else
+    {
+	    pt_book.user += 1;
+	    pt_book.this_many = 1;
+    }
+    thred->next = thred->prev = NULL;
+    pt_book.first = pt_book.last = thred;
+
+    thred->stack = PR_NEWZAP(PRThreadStack);
+    PR_ASSERT(thred->stack != NULL);
+    thred->stack->stackSize = 0;
+    thred->stack->thr = thred;
+	_PR_InitializeStack(thred->stack);
+
+    /*
+     * Create a key for our use to store a backpointer in the pthread
+     * to our PRThread object. This object gets deleted when the thread
+     * returns from its root in the case of a detached thread. Other
+     * threads delete the objects in Join.
+     *
+     * NB: The destructor logic seems to have a bug so it isn't used.
+     * NBB: Oh really? I'm going to give it a spin - AOF 19 June 1998.
+     * More info - the problem is that pthreads calls the destructor
+     * eagerly as the thread returns from its root, rather than lazily
+     * after the thread is joined. Therefore, threads that are joining
+     * and holding PRThread references are actually holding pointers to
+     * nothing.
+     */
+    rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death);
+    PR_ASSERT(0 == rv);
+    rv = pthread_setspecific(pt_book.key, thred);
+    PR_ASSERT(0 == rv);    
+    PR_SetThreadPriority(thred, priority);
+}  /* _PR_InitThreads */
+
+#ifdef __GNUC__
+/*
+ * GCC supports the constructor and destructor attributes as of
+ * version 2.5.
+ */
+static void _PR_Fini(void) __attribute__ ((destructor));
+#elif defined(__SUNPRO_C)
+/*
+ * Sun Studio compiler
+ */
+#pragma fini(_PR_Fini)
+static void _PR_Fini(void);
+#elif defined(HPUX)
+/*
+ * Current versions of HP C compiler define __HP_cc.
+ * HP C compiler A.11.01.20 doesn't define __HP_cc.
+ */
+#if defined(__ia64) || defined(_LP64)
+#pragma FINI "_PR_Fini"
+static void _PR_Fini(void);
+#else
+/*
+ * Only HP-UX 10.x style initializers are supported in 32-bit links.
+ * Need to use the +I PR_HPUX10xInit linker option.
+ */
+#include <dl.h>
+
+static void _PR_Fini(void);
+
+void PR_HPUX10xInit(shl_t handle, int loading)
+{
+    /*
+     * This function is called when a shared library is loaded as well
+     * as when the shared library is unloaded.  Note that it may not
+     * be called when the user's program terminates.
+     *
+     * handle is the shl_load API handle for the shared library being
+     * initialized.
+     *
+     * loading is non-zero at startup and zero at termination.
+     */
+    if (loading) {
+	/* ... do some initializations ... */
+    } else {
+	_PR_Fini();
+    }
+}
+#endif
+#elif defined(AIX)
+/* Need to use the -binitfini::_PR_Fini linker option. */
+#endif
+
+void _PR_Fini(void)
+{
+    void *thred;
+    int rv;
+
+    if (!_pr_initialized) return;
+
+    _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred);
+    if (NULL != thred)
+    {
+        /*
+         * PR_FALSE, because it is unsafe to call back to the 
+         * thread private data destructors at final cleanup.
+         */
+        _pt_thread_death_internal(thred, PR_FALSE);
+        rv = pthread_setspecific(pt_book.key, NULL);
+        PR_ASSERT(0 == rv);
+    }
+    /* TODO: free other resources used by NSPR */
+    /* _pr_initialized = PR_FALSE; */
+}  /* _PR_Fini */
+
+PR_IMPLEMENT(PRStatus) PR_Cleanup(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    int rv;
+    PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR"));
+    PR_ASSERT(me->state & PT_THREAD_PRIMORD);
+    if (me->state & PT_THREAD_PRIMORD)
+    {
+        PR_Lock(pt_book.ml);
+        while (pt_book.user > pt_book.this_many)
+            PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT);
+        if (me->state & PT_THREAD_SYSTEM)
+            pt_book.system -= 1;
+        else
+            pt_book.user -= 1;
+        PR_Unlock(pt_book.ml);
+
+        _PR_MD_EARLY_CLEANUP();
+
+        _PR_CleanupMW();
+        _PR_CleanupTime();
+        _PR_CleanupDtoa();
+        _PR_CleanupCallOnce();
+        _PR_ShutdownLinker();
+        _PR_LogCleanup();
+        _PR_CleanupNet();
+        /* Close all the fd's before calling _PR_CleanupIO */
+        _PR_CleanupIO();
+        _PR_CleanupCMon();
+
+        _pt_thread_death(me);
+        rv = pthread_setspecific(pt_book.key, NULL);
+        PR_ASSERT(0 == rv);
+        /*
+         * I am not sure if it's safe to delete the cv and lock here,
+         * since there may still be "system" threads around. If this
+         * call isn't immediately prior to exiting, then there's a
+         * problem.
+         */
+        if (0 == pt_book.system)
+        {
+            PR_DestroyCondVar(pt_book.cv); pt_book.cv = NULL;
+            PR_DestroyLock(pt_book.ml); pt_book.ml = NULL;
+        }
+        PR_DestroyLock(_pr_sleeplock);
+        _pr_sleeplock = NULL;
+        _PR_CleanupLayerCache();
+        _PR_CleanupEnv();
+#ifdef _PR_ZONE_ALLOCATOR
+        _PR_DestroyZones();
+#endif
+        _pr_initialized = PR_FALSE;
+        return PR_SUCCESS;
+    }
+    return PR_FAILURE;
+}  /* PR_Cleanup */
+
+PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status)
+{
+    _exit(status);
+}
+
+PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thred)
+{
+#if defined(_PR_DCETHREADS)
+    return (PRUint32)&thred->id;  /* this is really a sham! */
+#else
+    return (PRUint32)thred->id;  /* and I don't know what they will do with it */
+#endif
+}
+
+/*
+ * $$$
+ * The following two thread-to-processor affinity functions are not
+ * yet implemented for pthreads.  By the way, these functions should return
+ * PRStatus rather than PRInt32 to indicate the success/failure status.
+ * $$$
+ */
+
+PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask)
+{
+    return 0;  /* not implemented */
+}
+
+PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask )
+{
+    return 0;  /* not implemented */
+}
+
+PR_IMPLEMENT(void)
+PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg)
+{
+    thread->dump = dump;
+    thread->dumpArg = arg;
+}
+
+/* 
+ * Garbage collection support follows.
+ */
+
+#if defined(_PR_DCETHREADS)
+
+/*
+ * statics for Garbage Collection support.  We don't need to protect these
+ * signal masks since the garbage collector itself is protected by a lock
+ * and multiple threads will not be garbage collecting at the same time.
+ */
+static sigset_t javagc_vtalarm_sigmask;
+static sigset_t javagc_intsoff_sigmask;
+
+#else /* defined(_PR_DCETHREADS) */
+
+/* a bogus signal mask for forcing a timed wait */
+/* Not so bogus in AIX as we really do a sigwait */
+static sigset_t sigwait_set;
+
+static struct timespec onemillisec = {0, 1000000L};
+#ifndef PT_NO_SIGTIMEDWAIT
+static struct timespec hundredmillisec = {0, 100000000L};
+#endif
+
+static void suspend_signal_handler(PRIntn sig);
+
+#ifdef PT_NO_SIGTIMEDWAIT
+static void null_signal_handler(PRIntn sig);
+#endif
+
+#endif /* defined(_PR_DCETHREADS) */
+
+/*
+ * Linux pthreads use SIGUSR1 and SIGUSR2 internally, which
+ * conflict with the use of these two signals in our GC support.
+ * So we don't know how to support GC on Linux pthreads.
+ */
+static void init_pthread_gc_support(void)
+{
+#ifndef SYMBIAN
+    PRIntn rv;
+
+#if defined(_PR_DCETHREADS)
+	rv = sigemptyset(&javagc_vtalarm_sigmask);
+    PR_ASSERT(0 == rv);
+	rv = sigaddset(&javagc_vtalarm_sigmask, SIGVTALRM);
+    PR_ASSERT(0 == rv);
+#else  /* defined(_PR_DCETHREADS) */
+	{
+	    struct sigaction sigact_usr2;
+
+	    sigact_usr2.sa_handler = suspend_signal_handler;
+	    sigact_usr2.sa_flags = SA_RESTART;
+	    sigemptyset (&sigact_usr2.sa_mask);
+
+        rv = sigaction (SIGUSR2, &sigact_usr2, NULL);
+        PR_ASSERT(0 == rv);
+
+        sigemptyset (&sigwait_set);
+#if defined(PT_NO_SIGTIMEDWAIT)
+        sigaddset (&sigwait_set, SIGUSR1);
+#else
+        sigaddset (&sigwait_set, SIGUSR2);
+#endif  /* defined(PT_NO_SIGTIMEDWAIT) */
+	}
+#if defined(PT_NO_SIGTIMEDWAIT)
+	{
+	    struct sigaction sigact_null;
+	    sigact_null.sa_handler = null_signal_handler;
+	    sigact_null.sa_flags = SA_RESTART;
+	    sigemptyset (&sigact_null.sa_mask);
+        rv = sigaction (SIGUSR1, &sigact_null, NULL);
+	    PR_ASSERT(0 ==rv); 
+    }
+#endif  /* defined(PT_NO_SIGTIMEDWAIT) */
+#endif /* defined(_PR_DCETHREADS) */
+#endif /* SYMBIAN */
+}
+
+PR_IMPLEMENT(void) PR_SetThreadGCAble(void)
+{
+    PR_Lock(pt_book.ml);
+	PR_GetCurrentThread()->state |= PT_THREAD_GCABLE;
+    PR_Unlock(pt_book.ml);
+}
+
+PR_IMPLEMENT(void) PR_ClearThreadGCAble(void)
+{
+    PR_Lock(pt_book.ml);
+	PR_GetCurrentThread()->state &= (~PT_THREAD_GCABLE);
+    PR_Unlock(pt_book.ml);
+}
+
+#if defined(DEBUG)
+static PRBool suspendAllOn = PR_FALSE;
+#endif
+
+static PRBool suspendAllSuspended = PR_FALSE;
+
+PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg)
+{
+    PRIntn count = 0;
+    PRStatus rv = PR_SUCCESS;
+    PRThread* thred = pt_book.first;
+
+#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
+#if !defined(_PR_DCETHREADS)
+    PRThread *me = PR_GetCurrentThread();
+#endif
+#endif
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_EnumerateThreads\n"));
+    /*
+     * $$$
+     * Need to suspend all threads other than me before doing this.
+     * This is really a gross and disgusting thing to do. The only
+     * good thing is that since all other threads are suspended, holding
+     * the lock during a callback seems like child's play.
+     * $$$
+     */
+    PR_ASSERT(suspendAllOn);
+
+    while (thred != NULL)
+    {
+        /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking
+         * qp->next after applying the function "func".  In particular, "func"
+         * might remove the thread from the queue and put it into another one in
+         * which case qp->next no longer points to the next entry in the original
+         * queue.
+         *
+         * To get around this problem, we save qp->next in qp_next before applying
+         * "func" and use that saved value as the next value after applying "func".
+         */
+        PRThread* next = thred->next;
+
+        if (_PT_IS_GCABLE_THREAD(thred))
+        {
+#if !defined(_PR_DCETHREADS)
+            PR_ASSERT((thred == me) || (thred->suspend & PT_THREAD_SUSPENDED));
+#endif
+            PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+                   ("In PR_EnumerateThreads callback thread %p thid = %X\n", 
+                    thred, thred->id));
+
+            rv = func(thred, count++, arg);
+            if (rv != PR_SUCCESS)
+                return rv;
+        }
+        thred = next;
+    }
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("End PR_EnumerateThreads count = %d \n", count));
+    return rv;
+}  /* PR_EnumerateThreads */
+
+/*
+ * PR_SuspendAll and PR_ResumeAll are called during garbage collection.  The strategy 
+ * we use is to send a SIGUSR2 signal to every gc able thread that we intend to suspend.
+ * The signal handler will record the stack pointer and will block until resumed by
+ * the resume call.  Since the signal handler is the last routine called for the
+ * suspended thread, the stack pointer will also serve as a place where all the
+ * registers have been saved on the stack for the previously executing routines.
+ *
+ * Through global variables, we also make sure that PR_Suspend and PR_Resume does not
+ * proceed until the thread is suspended or resumed.
+ */
+
+#if !defined(_PR_DCETHREADS)
+
+/*
+ * In the signal handler, we can not use condition variable notify or wait.
+ * This does not work consistently across all pthread platforms.  We also can not 
+ * use locking since that does not seem to work reliably across platforms.
+ * Only thing we can do is yielding while testing for a global condition
+ * to change.  This does work on pthread supported platforms.  We may have
+ * to play with priortities if there are any problems detected.
+ */
+
+ /* 
+  * In AIX, you cannot use ANY pthread calls in the signal handler except perhaps
+  * pthread_yield. But that is horribly inefficient. Hence we use only sigwait, no
+  * sigtimedwait is available. We need to use another user signal, SIGUSR1. Actually
+  * SIGUSR1 is also used by exec in Java. So our usage here breaks the exec in Java,
+  * for AIX. You cannot use pthread_cond_wait or pthread_delay_np in the signal
+  * handler as all synchronization mechanisms just break down. 
+  */
+
+#if defined(PT_NO_SIGTIMEDWAIT)
+static void null_signal_handler(PRIntn sig)
+{
+	return;
+}
+#endif
+
+static void suspend_signal_handler(PRIntn sig)
+{
+	PRThread *me = PR_GetCurrentThread();
+
+	PR_ASSERT(me != NULL);
+	PR_ASSERT(_PT_IS_GCABLE_THREAD(me));
+	PR_ASSERT((me->suspend & PT_THREAD_SUSPENDED) == 0);
+
+	PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+        ("Begin suspend_signal_handler thred %p thread id = %X\n", 
+		me, me->id));
+
+	/*
+	 * save stack pointer
+	 */
+	me->sp = &me;
+
+	/* 
+	   At this point, the thread's stack pointer has been saved,
+	   And it is going to enter a wait loop until it is resumed.
+	   So it is _really_ suspended 
+	*/
+
+	me->suspend |= PT_THREAD_SUSPENDED;
+
+	/*
+	 * now, block current thread
+	 */
+#if defined(PT_NO_SIGTIMEDWAIT)
+	pthread_cond_signal(&me->suspendResumeCV);
+	while (me->suspend & PT_THREAD_SUSPENDED)
+	{
+#if !defined(FREEBSD) && !defined(NETBSD) && !defined(OPENBSD) \
+    && !defined(BSDI) && !defined(UNIXWARE) \
+    && !defined(DARWIN) && !defined(RISCOS) \
+    && !defined(SYMBIAN) /*XXX*/
+        PRIntn rv;
+	    sigwait(&sigwait_set, &rv);
+#endif
+	}
+	me->suspend |= PT_THREAD_RESUMED;
+	pthread_cond_signal(&me->suspendResumeCV);
+#else /* defined(PT_NO_SIGTIMEDWAIT) */
+	while (me->suspend & PT_THREAD_SUSPENDED)
+	{
+		PRIntn rv = sigtimedwait(&sigwait_set, NULL, &hundredmillisec);
+    	PR_ASSERT(-1 == rv);
+	}
+	me->suspend |= PT_THREAD_RESUMED;
+#endif
+
+    /*
+     * At this point, thread has been resumed, so set a global condition.
+     * The ResumeAll needs to know that this has really been resumed. 
+     * So the signal handler sets a flag which PR_ResumeAll will reset. 
+     * The PR_ResumeAll must reset this flag ...
+     */
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+        ("End suspend_signal_handler thred = %p tid = %X\n", me, me->id));
+}  /* suspend_signal_handler */
+
+static void pt_SuspendSet(PRThread *thred)
+{
+    PRIntn rv;
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("pt_SuspendSet thred %p thread id = %X\n", thred, thred->id));
+
+
+    /*
+     * Check the thread state and signal the thread to suspend
+     */
+
+    PR_ASSERT((thred->suspend & PT_THREAD_SUSPENDED) == 0);
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("doing pthread_kill in pt_SuspendSet thred %p tid = %X\n",
+	   thred, thred->id));
+#if defined(SYMBIAN)
+    /* All signal group functions are not implemented in Symbian OS */
+    rv = 0;
+#else
+    rv = pthread_kill (thred->id, SIGUSR2);
+#endif
+    PR_ASSERT(0 == rv);
+}
+
+static void pt_SuspendTest(PRThread *thred)
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("Begin pt_SuspendTest thred %p thread id = %X\n", thred, thred->id));
+
+
+    /*
+     * Wait for the thread to be really suspended. This happens when the
+     * suspend signal handler stores the stack pointer and sets the state
+     * to suspended. 
+     */
+
+#if defined(PT_NO_SIGTIMEDWAIT)
+    pthread_mutex_lock(&thred->suspendResumeMutex);
+    while ((thred->suspend & PT_THREAD_SUSPENDED) == 0)
+    {
+	    pthread_cond_timedwait(
+	        &thred->suspendResumeCV, &thred->suspendResumeMutex, &onemillisec);
+	}
+	pthread_mutex_unlock(&thred->suspendResumeMutex);
+#else
+    while ((thred->suspend & PT_THREAD_SUSPENDED) == 0)
+    {
+		PRIntn rv = sigtimedwait(&sigwait_set, NULL, &onemillisec);
+    	PR_ASSERT(-1 == rv);
+	}
+#endif
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,
+        ("End pt_SuspendTest thred %p tid %X\n", thred, thred->id));
+}  /* pt_SuspendTest */
+
+static void pt_ResumeSet(PRThread *thred)
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("pt_ResumeSet thred %p thread id = %X\n", thred, thred->id));
+
+    /*
+     * Clear the global state and set the thread state so that it will
+     * continue past yield loop in the suspend signal handler
+     */
+
+    PR_ASSERT(thred->suspend & PT_THREAD_SUSPENDED);
+
+
+    thred->suspend &= ~PT_THREAD_SUSPENDED;
+
+#if defined(PT_NO_SIGTIMEDWAIT)
+#if defined(SYMBIAN) 
+	/* All signal group functions are not implemented in Symbian OS */
+#else
+	pthread_kill(thred->id, SIGUSR1);
+#endif
+#endif
+
+}  /* pt_ResumeSet */
+
+static void pt_ResumeTest(PRThread *thred)
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("Begin pt_ResumeTest thred %p thread id = %X\n", thred, thred->id));
+
+    /*
+     * Wait for the threads resume state to change
+     * to indicate it is really resumed 
+     */
+#if defined(PT_NO_SIGTIMEDWAIT)
+    pthread_mutex_lock(&thred->suspendResumeMutex);
+    while ((thred->suspend & PT_THREAD_RESUMED) == 0)
+    {
+	    pthread_cond_timedwait(
+	        &thred->suspendResumeCV, &thred->suspendResumeMutex, &onemillisec);
+    }
+    pthread_mutex_unlock(&thred->suspendResumeMutex);
+#else
+    while ((thred->suspend & PT_THREAD_RESUMED) == 0) {
+		PRIntn rv = sigtimedwait(&sigwait_set, NULL, &onemillisec);
+    	PR_ASSERT(-1 == rv);
+	}
+#endif
+
+    thred->suspend &= ~PT_THREAD_RESUMED;
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, (
+        "End pt_ResumeTest thred %p tid %X\n", thred, thred->id));
+}  /* pt_ResumeTest */
+
+static pthread_once_t pt_gc_support_control = PTHREAD_ONCE_INIT;
+
+PR_IMPLEMENT(void) PR_SuspendAll(void)
+{
+#ifdef DEBUG
+    PRIntervalTime stime, etime;
+#endif
+    PRThread* thred = pt_book.first;
+    PRThread *me = PR_GetCurrentThread();
+    int rv;
+
+    rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support);
+    PR_ASSERT(0 == rv);
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n"));
+    /*
+     * Stop all threads which are marked GC able.
+     */
+    PR_Lock(pt_book.ml);
+#ifdef DEBUG
+    suspendAllOn = PR_TRUE;
+    stime = PR_IntervalNow();
+#endif
+    while (thred != NULL)
+    {
+	    if ((thred != me) && _PT_IS_GCABLE_THREAD(thred))
+    		pt_SuspendSet(thred);
+        thred = thred->next;
+    }
+
+    /* Wait till they are really suspended */
+    thred = pt_book.first;
+    while (thred != NULL)
+    {
+	    if ((thred != me) && _PT_IS_GCABLE_THREAD(thred))
+            pt_SuspendTest(thred);
+        thred = thred->next;
+    }
+
+    suspendAllSuspended = PR_TRUE;
+
+#ifdef DEBUG
+    etime = PR_IntervalNow();
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,\
+        ("End PR_SuspendAll (time %dms)\n",
+        PR_IntervalToMilliseconds(etime - stime)));
+#endif
+}  /* PR_SuspendAll */
+
+PR_IMPLEMENT(void) PR_ResumeAll(void)
+{
+#ifdef DEBUG
+    PRIntervalTime stime, etime;
+#endif
+    PRThread* thred = pt_book.first;
+    PRThread *me = PR_GetCurrentThread();
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n"));
+    /*
+     * Resume all previously suspended GC able threads.
+     */
+    suspendAllSuspended = PR_FALSE;
+#ifdef DEBUG
+    stime = PR_IntervalNow();
+#endif
+
+    while (thred != NULL)
+    {
+	    if ((thred != me) && _PT_IS_GCABLE_THREAD(thred))
+    	    pt_ResumeSet(thred);
+        thred = thred->next;
+    }
+
+    thred = pt_book.first;
+    while (thred != NULL)
+    {
+	    if ((thred != me) && _PT_IS_GCABLE_THREAD(thred))
+    	    pt_ResumeTest(thred);
+        thred = thred->next;
+    }
+
+    PR_Unlock(pt_book.ml);
+#ifdef DEBUG
+    suspendAllOn = PR_FALSE;
+    etime = PR_IntervalNow();
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,
+        ("End PR_ResumeAll (time %dms)\n",
+        PR_IntervalToMilliseconds(etime - stime)));
+#endif
+}  /* PR_ResumeAll */
+
+/* Return the stack pointer for the given thread- used by the GC */
+PR_IMPLEMENT(void *)PR_GetSP(PRThread *thred)
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	    ("in PR_GetSP thred %p thid = %X, sp = %p\n", 
+	    thred, thred->id, thred->sp));
+    return thred->sp;
+}  /* PR_GetSP */
+
+#else /* !defined(_PR_DCETHREADS) */
+
+static pthread_once_t pt_gc_support_control = pthread_once_init;
+
+/*
+ * For DCE threads, there is no pthread_kill or a way of suspending or resuming a
+ * particular thread.  We will just disable the preemption (virtual timer alarm) and
+ * let the executing thread finish the garbage collection.  This stops all other threads
+ * (GC able or not) and is very inefficient but there is no other choice.
+ */
+PR_IMPLEMENT(void) PR_SuspendAll()
+{
+    PRIntn rv;
+
+    rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support);
+    PR_ASSERT(0 == rv);  /* returns -1 on failure */
+#ifdef DEBUG
+    suspendAllOn = PR_TRUE;
+#endif
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n"));
+    /* 
+     * turn off preemption - i.e add virtual alarm signal to the set of 
+     * blocking signals 
+     */
+    rv = sigprocmask(
+        SIG_BLOCK, &javagc_vtalarm_sigmask, &javagc_intsoff_sigmask);
+    PR_ASSERT(0 == rv);
+    suspendAllSuspended = PR_TRUE;
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_SuspendAll\n"));
+}  /* PR_SuspendAll */
+
+PR_IMPLEMENT(void) PR_ResumeAll()
+{
+    PRIntn rv;
+    
+    suspendAllSuspended = PR_FALSE;
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n"));
+    /* turn on preemption - i.e re-enable virtual alarm signal */
+
+    rv = sigprocmask(SIG_SETMASK, &javagc_intsoff_sigmask, (sigset_t *)NULL);
+    PR_ASSERT(0 == rv);
+#ifdef DEBUG
+    suspendAllOn = PR_FALSE;
+#endif
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_ResumeAll\n"));
+}  /* PR_ResumeAll */
+
+/* Return the stack pointer for the given thread- used by the GC */
+PR_IMPLEMENT(void*)PR_GetSP(PRThread *thred)
+{
+	pthread_t tid = thred->id;
+	char *thread_tcb, *top_sp;
+
+	/*
+	 * For HPUX DCE threads, pthread_t is a struct with the
+	 * following three fields (see pthread.h, dce/cma.h):
+	 *     cma_t_address       field1;
+	 *     short int           field2;
+	 *     short int           field3;
+	 * where cma_t_address is typedef'd to be either void*
+	 * or char*.
+	 */
+	PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_GetSP\n"));
+	thread_tcb = (char*)tid.field1;
+	top_sp = *(char**)(thread_tcb + 128);
+	PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_GetSP %p \n", top_sp));
+	return top_sp;
+}  /* PR_GetSP */
+
+#endif /* !defined(_PR_DCETHREADS) */
+
+#endif  /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */
+
+/* ptthread.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/Makefile.in
new file mode 100644
index 0000000..5e6731c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/Makefile.in
@@ -0,0 +1,94 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifdef USE_PTHREADS
+    DIRS =
+else
+ifdef USE_BTHREADS
+    DIRS =
+else
+    DIRS = combined
+endif
+endif
+
+ifdef USE_PTHREADS
+CSRCS = \
+	prcmon.c \
+	prrwlock.c   \
+	prtpd.c \
+	$(NULL)
+else
+ifdef USE_BTHREADS
+CSRCS = \
+	prcmon.c \
+	prrwlock.c   \
+	prtpd.c \
+	$(NULL)
+else
+CSRCS =	\
+	prcmon.c  \
+	prdump.c  \
+	prmon.c   \
+	prsem.c   \
+	prrwlock.c   \
+	prcthr.c \
+	prtpd.c \
+	$(NULL)
+endif
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/Makefile.in
new file mode 100644
index 0000000..476c6c9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/Makefile.in
@@ -0,0 +1,79 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+# Disable optimization of the nspr on SunOS4.1.3
+ifeq ($(OS_ARCH),SunOS)
+ifeq ($(OS_RELEASE),4.1.3_U1)
+OPTIMIZER =
+endif
+endif
+
+ifdef USE_PTHREADS
+CSRCS =         \
+	$(NULL)
+else
+CSRCS =         \
+    prucpu.c      \
+	prucv.c      \
+	prulock.c    \
+	pruthr.c     \
+    prustack.c    \
+	$(NULL)
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/README b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/README
new file mode 100644
index 0000000..aa26665
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/README
@@ -0,0 +1,62 @@
+NSPR 2.0 evolution
+------------------
+
+
+Phase 1- today
+
+Currently (Oct 10, 1996) NSPR 2.0 has two modes.  Either _PR_NTHREAD 
+is defined, in which case the PR_CreateThread() call always creates a 
+native kernel thread, or _PR_NTHREAD is not defined and PR_CreateThread() 
+always creates user level threads within the single, original process.  This 
+source code is reflected in two directories, nspr20/pr/src/threads/native, and 
+nspr20/pr/src/threads/user.  Although the PR_CreateThread() function has
+a paramter to specify the "scope" of a thread, this parameter is not yet 
+used- except on solaris where it uses it to specify bound vs unbound threads.
+
+Phase 2 - next week
+
+The next step is to provide a combination of user and native threads.  The
+idea, of course, is to have some small number of native threads and each of 
+those threads be able to run user level threads.  The number of native
+threads created will most likely be proportional to the number of CPUs in
+the system.  For this reason, the specific set of native threads which are
+used to run the user-level threads will be called "CPU" threads.  
+
+The user level threads which will be run on the CPU threads are able to
+run on any of the CPU threads available, and over the course of a user-level
+thread's lifetime, it may drift from one CPU thread to another.  All 
+user-level threads will compete for processing time via a single run queue.
+
+Creation of a CPU thread will be primarily controlled by NSPR itself or by
+the user running a function PR_Concurrency().  The details of PR_Concurrency()
+have not yet been worked out; but the idea is that the user can specify to 
+NSPR how many CPU threads are desired.
+
+In this system, user-level threads are created by using PR_CreateThread() and
+specifying the PR_LOCAL_SCOPE option.  LOCAL_SCOPE indicates that the thread
+will be under the control of the "local" scheduler.  Creating threads with
+GLOBAL_SCOPE, on the other hand will create a thread which is under the 
+control of the system's scheduler.  In otherwords, this creates a native thread
+which is not a CPU thread; it runs a single thread task and never has more 
+than one task to run.  LOCAL_SCOPE is much like creating a Solaris unbound 
+thread, while GLOBAL_SCOPE is similar to creating a Solaris bound thread.
+
+To implement this architecture, the source code will still maintain the "user"
+and "native" directories which is has today.  However a third directory 
+"combined" will also exist.  To compile a version of NSPR which only creates
+native threads, the user can define _PR_NTHREAD.  For exclusive user-level
+threads, do not define _PR_NTHREAD.  To get the combined threads, define
+_PR_NTHREAD and _PR_USE_CPUS.
+
+
+Phase 3 - later than next week
+
+The goal is to eliminate the 3 directories.  Once these three models are in
+place, the remaining work will be to eliminate the native and user thread
+directories for all platforms, so that the entire thread model is contained
+within what is today called the "combined" model.  This new and glorious
+source code will attempt to make the "combined" model on any platforms which
+provide the necessary underlying native threading, but will also be 
+capable of using exclusive user-level threads on systems which don't have
+native threads.
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prucpu.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prucpu.c
new file mode 100644
index 0000000..3a3596b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prucpu.c
@@ -0,0 +1,437 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+_PRCPU *_pr_primordialCPU = NULL;
+
+PRInt32 _pr_md_idle_cpus;       /* number of idle cpus */
+/*
+ * The idle threads in MxN models increment/decrement _pr_md_idle_cpus.
+ * If _PR_HAVE_ATOMIC_OPS is not defined, they can't use the atomic
+ * increment/decrement routines (which are based on PR_Lock/PR_Unlock),
+ * because PR_Lock asserts that the calling thread is not an idle thread.
+ * So we use a _MDLock to protect _pr_md_idle_cpus.
+ */
+#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
+#ifndef _PR_HAVE_ATOMIC_OPS
+static _MDLock _pr_md_idle_cpus_lock;
+#endif
+#endif
+PRUintn _pr_numCPU;
+PRInt32 _pr_cpus_exit;
+PRInt32 _pr_cpu_affinity_mask = 0;
+
+#if !defined (_PR_GLOBAL_THREADS_ONLY)
+
+static PRUintn _pr_cpuID;
+
+static void PR_CALLBACK _PR_CPU_Idle(void *);
+
+static _PRCPU *_PR_CreateCPU(void);
+static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread);
+
+#if !defined(_PR_LOCAL_THREADS_ONLY)
+static void _PR_RunCPU(void *arg);
+#endif
+
+void  _PR_InitCPUs()
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_native_threads_only)
+        return;
+
+    _pr_cpuID = 0;
+    _MD_NEW_LOCK( &_pr_cpuLock);
+#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
+#ifndef _PR_HAVE_ATOMIC_OPS
+    _MD_NEW_LOCK(&_pr_md_idle_cpus_lock);
+#endif
+#endif
+
+#ifdef _PR_LOCAL_THREADS_ONLY
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me);
+#endif
+
+    /* Now start the first CPU. */
+    _pr_primordialCPU = _PR_CreateCPU();
+    _pr_numCPU = 1;
+    _PR_StartCPU(_pr_primordialCPU, me);
+
+    _PR_MD_SET_CURRENT_CPU(_pr_primordialCPU);
+
+    /* Initialize cpu for current thread (could be different from me) */
+    _PR_MD_CURRENT_THREAD()->cpu = _pr_primordialCPU;
+
+    _PR_MD_SET_LAST_THREAD(me);
+
+#else /* Combined MxN model */
+
+    _pr_primordialCPU = _PR_CreateCPU();
+    _pr_numCPU = 1;
+    _PR_CreateThread(PR_SYSTEM_THREAD,
+                     _PR_RunCPU,
+                     _pr_primordialCPU,
+                     PR_PRIORITY_NORMAL,
+                     PR_GLOBAL_THREAD,
+                     PR_UNJOINABLE_THREAD,
+                     0,
+                     _PR_IDLE_THREAD);
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+    _PR_MD_INIT_CPUS();
+}
+
+#ifdef WINNT
+/*
+ * Right now this function merely stops the CPUs and does
+ * not do any other cleanup.
+ *
+ * It is only implemented for WINNT because bug 161998 only
+ * affects the WINNT version of NSPR, but it would be nice
+ * to implement this function for other platforms too.
+ */
+void _PR_CleanupCPUs(void)
+{
+    PRUintn i;
+    PRCList *qp;
+    _PRCPU *cpu;
+
+    _pr_cpus_exit = 1;
+    for (i = 0; i < _pr_numCPU; i++) {
+        _PR_MD_WAKEUP_WAITER(NULL);
+    }
+    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
+        cpu = _PR_CPU_PTR(qp);
+        _PR_MD_JOIN_THREAD(&cpu->thread->md);
+    }
+}
+#endif
+
+static _PRCPUQueue *_PR_CreateCPUQueue(void)
+{
+    PRInt32 index;
+    _PRCPUQueue *cpuQueue;
+    cpuQueue = PR_NEWZAP(_PRCPUQueue);
+ 
+    _MD_NEW_LOCK( &cpuQueue->runQLock );
+    _MD_NEW_LOCK( &cpuQueue->sleepQLock );
+    _MD_NEW_LOCK( &cpuQueue->miscQLock );
+
+    for (index = 0; index < PR_PRIORITY_LAST + 1; index++)
+        PR_INIT_CLIST( &(cpuQueue->runQ[index]) );
+    PR_INIT_CLIST( &(cpuQueue->sleepQ) );
+    PR_INIT_CLIST( &(cpuQueue->pauseQ) );
+    PR_INIT_CLIST( &(cpuQueue->suspendQ) );
+    PR_INIT_CLIST( &(cpuQueue->waitingToJoinQ) );
+
+    cpuQueue->numCPUs = 1;
+
+    return cpuQueue;
+}
+
+/*
+ * Create a new CPU.
+ *
+ * This function initializes enough of the _PRCPU structure so
+ * that it can be accessed safely by a global thread or another
+ * CPU.  This function does not create the native thread that
+ * will run the CPU nor does it initialize the parts of _PRCPU
+ * that must be initialized by that native thread.
+ *
+ * The reason we cannot simply have the native thread create
+ * and fully initialize a new CPU is that we need to be able to
+ * create a usable _pr_primordialCPU in _PR_InitCPUs without
+ * assuming that the primordial CPU thread we created can run
+ * during NSPR initialization.  For example, on Windows while
+ * new threads can be created by DllMain, they won't be able
+ * to run during DLL initialization.  If NSPR is initialized
+ * by DllMain, the primordial CPU thread won't run until DLL
+ * initialization is finished.
+ */
+static _PRCPU *_PR_CreateCPU(void)
+{
+    _PRCPU *cpu;
+
+    cpu = PR_NEWZAP(_PRCPU);
+    if (cpu) {
+        cpu->queue = _PR_CreateCPUQueue();
+        if (!cpu->queue) {
+            PR_DELETE(cpu);
+            return NULL;
+        }
+    }
+    return cpu;
+}
+
+/*
+ * Start a new CPU.
+ *
+ * 'cpu' is a _PRCPU structure created by _PR_CreateCPU().
+ * 'thread' is the native thread that will run the CPU.
+ *
+ * If this function fails, 'cpu' is destroyed.
+ */
+static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread)
+{
+    /*
+    ** Start a new cpu. The assumption this code makes is that the
+    ** underlying operating system creates a stack to go with the new
+    ** native thread. That stack will be used by the cpu when pausing.
+    */
+
+    PR_ASSERT(!_native_threads_only);
+
+    cpu->last_clock = PR_IntervalNow();
+
+    /* Before we create any threads on this CPU we have to
+     * set the current CPU 
+     */
+    _PR_MD_SET_CURRENT_CPU(cpu);
+    _PR_MD_INIT_RUNNING_CPU(cpu);
+    thread->cpu = cpu;
+
+    cpu->idle_thread = _PR_CreateThread(PR_SYSTEM_THREAD,
+                                        _PR_CPU_Idle,
+                                        (void *)cpu,
+                                        PR_PRIORITY_NORMAL,
+                                        PR_LOCAL_THREAD,
+                                        PR_UNJOINABLE_THREAD,
+                                        0,
+                                        _PR_IDLE_THREAD);
+
+    if (!cpu->idle_thread) {
+        /* didn't clean up CPU queue XXXMB */
+        PR_DELETE(cpu);
+        return PR_FAILURE;
+    } 
+    PR_ASSERT(cpu->idle_thread->cpu == cpu);
+
+    cpu->idle_thread->no_sched = 0;
+
+    cpu->thread = thread;
+
+    if (_pr_cpu_affinity_mask)
+        PR_SetThreadAffinityMask(thread, _pr_cpu_affinity_mask);
+
+    /* Created and started a new CPU */
+    _PR_CPU_LIST_LOCK();
+    cpu->id = _pr_cpuID++;
+    PR_APPEND_LINK(&cpu->links, &_PR_CPUQ());
+    _PR_CPU_LIST_UNLOCK();
+
+    return PR_SUCCESS;
+}
+
+#if !defined(_PR_GLOBAL_THREADS_ONLY) && !defined(_PR_LOCAL_THREADS_ONLY)
+/*
+** This code is used during a cpu's initial creation.
+*/
+static void _PR_RunCPU(void *arg)
+{
+    _PRCPU *cpu = (_PRCPU *)arg;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(NULL != me);
+
+    /*
+     * _PR_StartCPU calls _PR_CreateThread to create the
+     * idle thread.  Because _PR_CreateThread calls PR_Lock,
+     * the current thread has to remain a global thread
+     * during the _PR_StartCPU call so that it can wait for
+     * the lock if the lock is held by another thread.  If
+     * we clear the _PR_GLOBAL_SCOPE flag in
+     * _PR_MD_CREATE_PRIMORDIAL_THREAD, the current thread
+     * will be treated as a local thread and have trouble
+     * waiting for the lock because the CPU is not fully
+     * constructed yet.
+     *
+     * After the CPU is started, it is safe to mark the
+     * current thread as a local thread.
+     */
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me);
+#endif
+
+    me->no_sched = 1;
+    _PR_StartCPU(cpu, me);
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+    me->flags &= (~_PR_GLOBAL_SCOPE);
+#endif
+
+    _PR_MD_SET_CURRENT_CPU(cpu);
+    _PR_MD_SET_CURRENT_THREAD(cpu->thread);
+    me->cpu = cpu;
+
+    while(1) {
+        PRInt32 is;
+        if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+	    _PR_MD_START_INTERRUPTS();
+        _PR_MD_SWITCH_CONTEXT(me);
+    }
+}
+#endif
+
+static void PR_CALLBACK _PR_CPU_Idle(void *_cpu)
+{
+    _PRCPU *cpu = (_PRCPU *)_cpu;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(NULL != me);
+
+    me->cpu = cpu;
+    cpu->idle_thread = me;
+    if (_MD_LAST_THREAD())
+        _MD_LAST_THREAD()->no_sched = 0;
+    if (!_PR_IS_NATIVE_THREAD(me)) _PR_MD_SET_INTSOFF(0);
+    while(1) {
+        PRInt32 is;
+        PRIntervalTime timeout;
+        if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+
+        _PR_RUNQ_LOCK(cpu);
+#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
+#ifdef _PR_HAVE_ATOMIC_OPS
+        _PR_MD_ATOMIC_INCREMENT(&_pr_md_idle_cpus);
+#else
+        _PR_MD_LOCK(&_pr_md_idle_cpus_lock);
+        _pr_md_idle_cpus++;
+        _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock);
+#endif /* _PR_HAVE_ATOMIC_OPS */
+#endif
+        /* If someone on runq; do a nonblocking PAUSECPU */
+        if (_PR_RUNQREADYMASK(me->cpu) != 0) {
+            _PR_RUNQ_UNLOCK(cpu);
+            timeout = PR_INTERVAL_NO_WAIT;
+        } else {
+            _PR_RUNQ_UNLOCK(cpu);
+
+            _PR_SLEEPQ_LOCK(cpu);
+            if (PR_CLIST_IS_EMPTY(&_PR_SLEEPQ(me->cpu))) {
+                timeout = PR_INTERVAL_NO_TIMEOUT;
+            } else {
+                PRThread *wakeThread;
+                wakeThread = _PR_THREAD_PTR(_PR_SLEEPQ(me->cpu).next);
+                timeout = wakeThread->sleep;
+            }
+            _PR_SLEEPQ_UNLOCK(cpu);
+        }
+
+        /* Wait for an IO to complete */
+        (void)_PR_MD_PAUSE_CPU(timeout);
+
+#ifdef WINNT
+        if (_pr_cpus_exit) {
+            /* _PR_CleanupCPUs tells us to exit */
+            _PR_MD_END_THREAD();
+        }
+#endif
+
+#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
+#ifdef _PR_HAVE_ATOMIC_OPS
+        _PR_MD_ATOMIC_DECREMENT(&_pr_md_idle_cpus);
+#else
+        _PR_MD_LOCK(&_pr_md_idle_cpus_lock);
+        _pr_md_idle_cpus--;
+        _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock);
+#endif /* _PR_HAVE_ATOMIC_OPS */
+#endif
+
+		_PR_ClockInterrupt();
+
+		/* Now schedule any thread that is on the runq
+		 * INTS must be OFF when calling PR_Schedule()
+		 */
+		me->state = _PR_RUNNABLE;
+		_PR_MD_SWITCH_CONTEXT(me);
+		if (!_PR_IS_NATIVE_THREAD(me)) _PR_FAST_INTSON(is);
+    }
+}
+#endif /* _PR_GLOBAL_THREADS_ONLY */
+
+PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs)
+{
+#if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_LOCAL_THREADS_ONLY)
+
+    /* do nothing */
+
+#else /* combined, MxN thread model */
+
+    PRUintn newCPU;
+    _PRCPU *cpu;
+    PRThread *thr;
+
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	if (_native_threads_only)
+		return;
+    
+    _PR_CPU_LIST_LOCK();
+    if (_pr_numCPU < numCPUs) {
+        newCPU = numCPUs - _pr_numCPU;
+        _pr_numCPU = numCPUs;
+    } else newCPU = 0;
+    _PR_CPU_LIST_UNLOCK();
+
+    for (; newCPU; newCPU--) {
+        cpu = _PR_CreateCPU();
+        thr = _PR_CreateThread(PR_SYSTEM_THREAD,
+                              _PR_RunCPU,
+                              cpu,
+                              PR_PRIORITY_NORMAL,
+                              PR_GLOBAL_THREAD,
+                              PR_UNJOINABLE_THREAD,
+                              0,
+                              _PR_IDLE_THREAD);
+    }
+#endif
+}
+
+PR_IMPLEMENT(_PRCPU *) _PR_GetPrimordialCPU(void)
+{
+    if (_pr_primordialCPU)
+        return _pr_primordialCPU;
+    else
+        return _PR_MD_CURRENT_CPU();
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prucv.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prucv.c
new file mode 100644
index 0000000..6d5d668
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prucv.c
@@ -0,0 +1,677 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "primpl.h"
+#include "prinrval.h"
+#include "prtypes.h"
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+
+/*
+** Notify one thread that it has finished waiting on a condition variable
+** Caller must hold the _PR_CVAR_LOCK(cv)
+*/
+PRBool _PR_NotifyThread (PRThread *thread, PRThread *me)
+{
+    PRBool rv;
+
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+    _PR_THREAD_LOCK(thread);
+    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+    if ( !_PR_IS_NATIVE_THREAD(thread) ) {
+        if (thread->wait.cvar != NULL) {
+            thread->wait.cvar = NULL;
+
+            _PR_SLEEPQ_LOCK(thread->cpu);
+            /* The notify and timeout can collide; in which case both may
+             * attempt to delete from the sleepQ; only let one do it.
+             */
+            if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))
+                _PR_DEL_SLEEPQ(thread, PR_TRUE);
+            _PR_SLEEPQ_UNLOCK(thread->cpu);
+
+	    if (thread->flags & _PR_SUSPENDING) {
+		/*
+		 * set thread state to SUSPENDED; a Resume operation
+		 * on the thread will move it to the runQ
+		 */
+            	thread->state = _PR_SUSPENDED;
+		_PR_MISCQ_LOCK(thread->cpu);
+		_PR_ADD_SUSPENDQ(thread, thread->cpu);
+		_PR_MISCQ_UNLOCK(thread->cpu);
+            	_PR_THREAD_UNLOCK(thread);
+	    } else {
+            	/* Make thread runnable */
+            	thread->state = _PR_RUNNABLE;
+            	_PR_THREAD_UNLOCK(thread);
+
+                _PR_AddThreadToRunQ(me, thread);
+                _PR_MD_WAKEUP_WAITER(thread);
+            }
+
+            rv = PR_TRUE;
+        } else {
+            /* Thread has already been notified */
+            _PR_THREAD_UNLOCK(thread);
+            rv = PR_FALSE;
+        }
+    } else { /* If the thread is a native thread */
+        if (thread->wait.cvar) {
+            thread->wait.cvar = NULL;
+
+	    if (thread->flags & _PR_SUSPENDING) {
+		/*
+		 * set thread state to SUSPENDED; a Resume operation
+		 * on the thread will enable the thread to run
+		 */
+            	thread->state = _PR_SUSPENDED;
+	     } else
+            	thread->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(thread);
+            _PR_MD_WAKEUP_WAITER(thread);
+            rv = PR_TRUE;
+        } else {
+            _PR_THREAD_UNLOCK(thread);
+            rv = PR_FALSE;
+        }    
+    }    
+
+    return rv;
+}
+
+/*
+ * Notify thread waiting on cvar; called when thread is interrupted
+ * 	The thread lock is held on entry and released before return
+ */
+void _PR_NotifyLockedThread (PRThread *thread)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRCondVar *cvar;
+    PRThreadPriority pri;
+
+    if ( !_PR_IS_NATIVE_THREAD(me))
+    	PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
+
+    cvar = thread->wait.cvar;
+    thread->wait.cvar = NULL;
+    _PR_THREAD_UNLOCK(thread);
+
+    _PR_CVAR_LOCK(cvar);
+    _PR_THREAD_LOCK(thread);
+
+    if (!_PR_IS_NATIVE_THREAD(thread)) {
+            _PR_SLEEPQ_LOCK(thread->cpu);
+            /* The notify and timeout can collide; in which case both may
+             * attempt to delete from the sleepQ; only let one do it.
+             */
+            if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))
+                _PR_DEL_SLEEPQ(thread, PR_TRUE);
+            _PR_SLEEPQ_UNLOCK(thread->cpu);
+
+	    /* Make thread runnable */
+	    pri = thread->priority;
+	    thread->state = _PR_RUNNABLE;
+
+	    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+
+            _PR_AddThreadToRunQ(me, thread);
+            _PR_THREAD_UNLOCK(thread);
+
+            _PR_MD_WAKEUP_WAITER(thread);
+    } else {
+	    if (thread->flags & _PR_SUSPENDING) {
+		/*
+		 * set thread state to SUSPENDED; a Resume operation
+		 * on the thread will enable the thread to run
+		 */
+            	thread->state = _PR_SUSPENDED;
+	     } else
+            	thread->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(thread);
+            _PR_MD_WAKEUP_WAITER(thread);
+    }    
+
+    _PR_CVAR_UNLOCK(cvar);
+    return;
+}
+
+/*
+** Make the given thread wait for the given condition variable
+*/
+PRStatus _PR_WaitCondVar(
+    PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout)
+{
+    PRIntn is;
+    PRStatus rv = PR_SUCCESS;
+
+    PR_ASSERT(thread == _PR_MD_CURRENT_THREAD());
+    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    if (_PR_PENDING_INTERRUPT(thread)) {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        thread->flags &= ~_PR_INTERRUPT;
+        return PR_FAILURE;
+    }
+
+    thread->wait.cvar = cvar;
+    lock->owner = NULL;
+    _PR_MD_WAIT_CV(&cvar->md,&lock->ilock, timeout);
+    thread->wait.cvar = NULL;
+    lock->owner = thread;
+    if (_PR_PENDING_INTERRUPT(thread)) {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        thread->flags &= ~_PR_INTERRUPT;
+        return PR_FAILURE;
+    }
+
+    return PR_SUCCESS;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+    if ( !_PR_IS_NATIVE_THREAD(thread))
+    	_PR_INTSOFF(is);
+
+    _PR_CVAR_LOCK(cvar);
+    _PR_THREAD_LOCK(thread);
+
+    if (_PR_PENDING_INTERRUPT(thread)) {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        thread->flags &= ~_PR_INTERRUPT;
+    	_PR_CVAR_UNLOCK(cvar);
+    	_PR_THREAD_UNLOCK(thread);
+    	if ( !_PR_IS_NATIVE_THREAD(thread))
+    		_PR_INTSON(is);
+        return PR_FAILURE;
+    }
+
+    thread->state = _PR_COND_WAIT;
+    thread->wait.cvar = cvar;
+
+    /*
+    ** Put the caller thread on the condition variable's wait Q
+    */
+    PR_APPEND_LINK(&thread->waitQLinks, &cvar->condQ);
+
+    /* Note- for global scope threads, we don't put them on the
+     *       global sleepQ, so each global thread must put itself
+     *       to sleep only for the time it wants to.
+     */
+    if ( !_PR_IS_NATIVE_THREAD(thread) ) {
+        _PR_SLEEPQ_LOCK(thread->cpu);
+        _PR_ADD_SLEEPQ(thread, timeout);
+        _PR_SLEEPQ_UNLOCK(thread->cpu);
+    }
+    _PR_CVAR_UNLOCK(cvar);
+    _PR_THREAD_UNLOCK(thread);
+   
+    /* 
+    ** Release lock protecting the condition variable and thereby giving time 
+    ** to the next thread which can potentially notify on the condition variable
+    */
+    PR_Unlock(lock);
+
+    PR_LOG(_pr_cvar_lm, PR_LOG_MIN,
+	   ("PR_Wait: cvar=%p waiting for %d", cvar, timeout));
+
+    rv = _PR_MD_WAIT(thread, timeout);
+
+    _PR_CVAR_LOCK(cvar);
+    PR_REMOVE_LINK(&thread->waitQLinks);
+    _PR_CVAR_UNLOCK(cvar);
+
+    PR_LOG(_pr_cvar_lm, PR_LOG_MIN,
+	   ("PR_Wait: cvar=%p done waiting", cvar));
+
+    if ( !_PR_IS_NATIVE_THREAD(thread))
+    	_PR_INTSON(is);
+
+    /* Acquire lock again that we had just relinquished */
+    PR_Lock(lock);
+
+    if (_PR_PENDING_INTERRUPT(thread)) {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        thread->flags &= ~_PR_INTERRUPT;
+        return PR_FAILURE;
+    }
+
+    return rv;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me)
+{
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    _PR_MD_NOTIFY_CV(&cvar->md, &cvar->lock->ilock);
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+    PRCList *q;
+    PRIntn is;
+
+    if ( !_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+    _PR_CVAR_LOCK(cvar);
+    q = cvar->condQ.next;
+    while (q != &cvar->condQ) {
+        PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar));
+        if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar)  {
+            if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE)
+                break;
+        }
+        q = q->next;
+    }
+    _PR_CVAR_UNLOCK(cvar);
+
+    if ( !_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSON(is);
+
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/*
+** Cndition variable debugging log info.
+*/
+PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen)
+{
+    PRUint32 nb;
+
+    if (cvar->lock->owner) {
+	nb = PR_snprintf(buf, buflen, "[%p] owner=%ld[%p]",
+			 cvar, cvar->lock->owner->id, cvar->lock->owner);
+    } else {
+	nb = PR_snprintf(buf, buflen, "[%p]", cvar);
+    }
+    return nb;
+}
+
+/*
+** Expire condition variable waits that are ready to expire. "now" is the current
+** time.
+*/
+void _PR_ClockInterrupt(void)
+{
+    PRThread *thread, *me = _PR_MD_CURRENT_THREAD();
+    _PRCPU *cpu = me->cpu;
+    PRIntervalTime elapsed, now;
+ 
+    PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
+    /* Figure out how much time elapsed since the last clock tick */
+    now = PR_IntervalNow();
+    elapsed = now - cpu->last_clock;
+    cpu->last_clock = now;
+
+    PR_LOG(_pr_clock_lm, PR_LOG_MAX,
+	   ("ExpireWaits: elapsed=%lld usec", elapsed));
+
+    while(1) {
+        _PR_SLEEPQ_LOCK(cpu);
+        if (_PR_SLEEPQ(cpu).next == &_PR_SLEEPQ(cpu)) {
+            _PR_SLEEPQ_UNLOCK(cpu);
+            break;
+        }
+
+        thread = _PR_THREAD_PTR(_PR_SLEEPQ(cpu).next);
+        PR_ASSERT(thread->cpu == cpu);
+
+        if (elapsed < thread->sleep) {
+            thread->sleep -= elapsed;
+            _PR_SLEEPQMAX(thread->cpu) -= elapsed;
+            _PR_SLEEPQ_UNLOCK(cpu);
+            break;
+        }
+        _PR_SLEEPQ_UNLOCK(cpu);
+
+        PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));
+
+        _PR_THREAD_LOCK(thread);
+
+        if (thread->cpu != cpu) {
+            /*
+            ** The thread was switched to another CPU
+            ** between the time we unlocked the sleep
+            ** queue and the time we acquired the thread
+            ** lock, so it is none of our business now.
+            */
+            _PR_THREAD_UNLOCK(thread);
+            continue;
+        }
+
+        /*
+        ** Consume this sleeper's amount of elapsed time from the elapsed
+        ** time value. The next remaining piece of elapsed time will be
+        ** available for the next sleeping thread's timer.
+        */
+        _PR_SLEEPQ_LOCK(cpu);
+        PR_ASSERT(!(thread->flags & _PR_ON_PAUSEQ));
+        if (thread->flags & _PR_ON_SLEEPQ) {
+            _PR_DEL_SLEEPQ(thread, PR_FALSE);
+            elapsed -= thread->sleep;
+            _PR_SLEEPQ_UNLOCK(cpu);
+        } else {
+            /* Thread was already handled; Go get another one */
+            _PR_SLEEPQ_UNLOCK(cpu);
+            _PR_THREAD_UNLOCK(thread);
+            continue;
+        }
+
+        /* Notify the thread waiting on the condition variable */
+        if (thread->flags & _PR_SUSPENDING) {
+		PR_ASSERT((thread->state == _PR_IO_WAIT) ||
+				(thread->state == _PR_COND_WAIT));
+            /*
+            ** Thread is suspended and its condition timeout
+            ** expired. Transfer thread from sleepQ to suspendQ.
+            */
+            thread->wait.cvar = NULL;
+            _PR_MISCQ_LOCK(cpu);
+            thread->state = _PR_SUSPENDED;
+            _PR_ADD_SUSPENDQ(thread, cpu);
+            _PR_MISCQ_UNLOCK(cpu);
+        } else {
+            if (thread->wait.cvar) {
+                PRThreadPriority pri;
+
+                /* Do work very similar to what _PR_NotifyThread does */
+                PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
+
+                /* Make thread runnable */
+                pri = thread->priority;
+                thread->state = _PR_RUNNABLE;
+                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+
+                PR_ASSERT(thread->cpu == cpu);
+                _PR_RUNQ_LOCK(cpu);
+                _PR_ADD_RUNQ(thread, cpu, pri);
+                _PR_RUNQ_UNLOCK(cpu);
+
+                if (pri > me->priority)
+                    _PR_SET_RESCHED_FLAG();
+
+                thread->wait.cvar = NULL;
+
+                _PR_MD_WAKEUP_WAITER(thread);
+
+            } else if (thread->io_pending == PR_TRUE) {
+                /* Need to put IO sleeper back on runq */
+                int pri = thread->priority;
+
+                thread->io_suspended = PR_TRUE;
+#ifdef WINNT
+				/*
+				 * For NT, record the cpu on which I/O was issued
+				 * I/O cancellation is done on the same cpu
+				 */
+                thread->md.thr_bound_cpu = cpu;
+#endif
+
+				PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+                PR_ASSERT(thread->cpu == cpu);
+                thread->state = _PR_RUNNABLE;
+                _PR_RUNQ_LOCK(cpu);
+                _PR_ADD_RUNQ(thread, cpu, pri);
+                _PR_RUNQ_UNLOCK(cpu);
+            }
+        }
+        _PR_THREAD_UNLOCK(thread);
+    }
+}
+
+/************************************************************************/
+
+/*
+** Create a new condition variable.
+** 	"lock" is the lock to use with the condition variable.
+**
+** Condition variables are synchronization objects that threads can use
+** to wait for some condition to occur.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low.
+*/
+PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock)
+{
+    PRCondVar *cvar;
+
+    PR_ASSERT(lock != NULL);
+
+    cvar = PR_NEWZAP(PRCondVar);
+    if (cvar) {
+#ifdef _PR_GLOBAL_THREADS_ONLY
+	if(_PR_MD_NEW_CV(&cvar->md)) {
+		PR_DELETE(cvar);
+		PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+		return NULL;
+	}
+#endif
+        if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) {
+		PR_DELETE(cvar);
+		PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+		return NULL;
+	}
+    cvar->lock = lock;
+	PR_INIT_CLIST(&cvar->condQ);
+
+    } else {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return cvar;
+}
+
+/*
+** Destroy a condition variable. There must be no thread
+** waiting on the condvar. The caller is responsible for guaranteeing
+** that the condvar is no longer in use.
+**
+*/
+PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar)
+{
+    PR_ASSERT(cvar->condQ.next == &cvar->condQ);
+
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    _PR_MD_FREE_CV(&cvar->md);
+#endif
+    _PR_MD_FREE_LOCK(&(cvar->ilock));
+ 
+    PR_DELETE(cvar);
+}
+
+/*
+** Wait for a notify on the condition variable. Sleep for "tiemout" amount
+** of ticks (if "timeout" is zero then the sleep is indefinite). While
+** the thread is waiting it unlocks lock. When the wait has
+** finished the thread regains control of the condition variable after
+** locking the associated lock.
+**
+** The thread waiting on the condvar will be resumed when the condvar is
+** notified (assuming the thread is the next in line to receive the
+** notify) or when the timeout elapses.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable or the thread has been interrupted.
+*/
+extern PRThread *suspendAllThread;
+PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	PR_ASSERT(cvar->lock->owner == me);
+	PR_ASSERT(me != suspendAllThread);
+    	if (cvar->lock->owner != me) return PR_FAILURE;
+
+	return _PR_WaitCondVar(me, cvar, cvar->lock, timeout);
+}
+
+/*
+** Notify the highest priority thread waiting on the condition
+** variable. If a thread is waiting on the condition variable (using
+** PR_Wait) then it is awakened and begins waiting on the lock.
+*/
+PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(cvar->lock->owner == me);
+    PR_ASSERT(me != suspendAllThread);
+    if (cvar->lock->owner != me) return PR_FAILURE;
+
+    _PR_NotifyCondVar(cvar, me);
+    return PR_SUCCESS;
+}
+
+/*
+** Notify all of the threads waiting on the condition variable. All of
+** threads are notified in turn. The highest priority thread will
+** probably acquire the lock.
+*/
+PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar)
+{
+    PRCList *q;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(cvar->lock->owner == me);
+    if (cvar->lock->owner != me) return PR_FAILURE;
+
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    _PR_MD_NOTIFYALL_CV(&cvar->md, &cvar->lock->ilock);
+    return PR_SUCCESS;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+    if ( !_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+    _PR_CVAR_LOCK(cvar);
+    q = cvar->condQ.next;
+    while (q != &cvar->condQ) {
+		PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar));
+		_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
+		q = q->next;
+    }
+    _PR_CVAR_UNLOCK(cvar);
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSON(is);
+
+    return PR_SUCCESS;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+
+/*********************************************************************/
+/*********************************************************************/
+/********************ROUTINES FOR DCE EMULATION***********************/
+/*********************************************************************/
+/*********************************************************************/
+#include "prpdce.h"
+
+PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void)
+{
+    PRCondVar *cvar = PR_NEWZAP(PRCondVar);
+    if (NULL != cvar)
+    {
+        if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE)
+        {
+		    PR_DELETE(cvar); cvar = NULL;
+	    }
+	    else
+	    {
+	        PR_INIT_CLIST(&cvar->condQ);
+            cvar->lock = _PR_NAKED_CV_LOCK;
+	    }
+
+    }
+    return cvar;
+}
+
+PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar)
+{
+    PR_ASSERT(cvar->condQ.next == &cvar->condQ);
+    PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
+
+    _PR_MD_FREE_LOCK(&(cvar->ilock));
+ 
+    PR_DELETE(cvar);
+}
+
+PR_IMPLEMENT(PRStatus) PRP_NakedWait(
+	PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
+	return _PR_WaitCondVar(me, cvar, lock, timeout);
+}  /* PRP_NakedWait */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
+
+    _PR_NotifyCondVar(cvar, me);
+
+    return PR_SUCCESS;
+}  /* PRP_NakedNotify */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar)
+{
+    PRCList *q;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
+
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+	_PR_MD_LOCK( &(cvar->ilock) );
+    q = cvar->condQ.next;
+    while (q != &cvar->condQ) {
+		PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar));
+		_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
+		q = q->next;
+    }
+	_PR_MD_UNLOCK( &(cvar->ilock) );
+    if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+
+    return PR_SUCCESS;
+}  /* PRP_NakedBroadcast */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prulock.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prulock.c
new file mode 100644
index 0000000..b188ed5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prulock.c
@@ -0,0 +1,465 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+
+void _PR_InitLocks(void)
+{
+	_PR_MD_INIT_LOCKS();
+}
+
+/*
+** Deal with delayed interrupts/requested reschedule during interrupt
+** re-enables.
+*/
+void _PR_IntsOn(_PRCPU *cpu)
+{
+    PRUintn missed, pri, i;
+    _PRInterruptTable *it;
+    PRThread *me;
+
+    PR_ASSERT(cpu);   /* Global threads don't have CPUs */
+    PR_ASSERT(_PR_MD_GET_INTSOFF() > 0);
+	me = _PR_MD_CURRENT_THREAD();
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+
+    /*
+    ** Process delayed interrupts. This logic is kinda scary because we
+    ** need to avoid losing an interrupt (it's ok to delay an interrupt
+    ** until later).
+    **
+    ** There are two missed state words. _pr_ints.where indicates to the
+    ** interrupt handler which state word is currently safe for
+    ** modification.
+    **
+    ** This code scans both interrupt state words, using the where flag
+    ** to indicate to the interrupt which state word is safe for writing.
+    ** If an interrupt comes in during a scan the other word will be
+    ** modified. This modification will be noticed during the next
+    ** iteration of the loop or during the next call to this routine.
+    */
+    for (i = 0; i < 2; i++) {
+        cpu->where = (1 - i);
+        missed = cpu->u.missed[i];
+        if (missed != 0) {
+            cpu->u.missed[i] = 0;
+            for (it = _pr_interruptTable; it->name; it++) {
+                if (missed & it->missed_bit) {
+                    PR_LOG(_pr_sched_lm, PR_LOG_MIN,
+                           ("IntsOn[0]: %s intr", it->name));
+                    (*it->handler)();
+                }
+            }
+        }
+    }
+
+    if (cpu->u.missed[3] != 0) {
+        _PRCPU *cpu;
+
+		_PR_THREAD_LOCK(me);
+        me->state = _PR_RUNNABLE;
+        pri = me->priority;
+
+        cpu = me->cpu;
+		_PR_RUNQ_LOCK(cpu);
+        _PR_ADD_RUNQ(me, cpu, pri);
+		_PR_RUNQ_UNLOCK(cpu);
+		_PR_THREAD_UNLOCK(me);
+        _PR_MD_SWITCH_CONTEXT(me);
+    }
+}
+
+/*
+** Unblock the first runnable waiting thread. Skip over
+** threads that are trying to be suspended
+** Note: Caller must hold _PR_LOCK_LOCK()
+*/
+void _PR_UnblockLockWaiter(PRLock *lock)
+{
+    PRThread *t = NULL;
+    PRThread *me;
+    PRCList *q;
+
+    q = lock->waitQ.next;
+    PR_ASSERT(q != &lock->waitQ);
+    while (q != &lock->waitQ) {
+        /* Unblock first waiter */
+        t = _PR_THREAD_CONDQ_PTR(q);
+
+		/* 
+		** We are about to change the thread's state to runnable and for local
+		** threads, we are going to assign a cpu to it.  So, protect thread's
+		** data structure.
+		*/
+        _PR_THREAD_LOCK(t);
+
+        if (t->flags & _PR_SUSPENDING) {
+            q = q->next;
+            _PR_THREAD_UNLOCK(t);
+            continue;
+        }
+
+        /* Found a runnable thread */
+	    PR_ASSERT(t->state == _PR_LOCK_WAIT);
+	    PR_ASSERT(t->wait.lock == lock);
+        t->wait.lock = 0;
+        PR_REMOVE_LINK(&t->waitQLinks);         /* take it off lock's waitQ */
+
+		/*
+		** If this is a native thread, nothing else to do except to wake it
+		** up by calling the machine dependent wakeup routine.
+		**
+		** If this is a local thread, we need to assign it a cpu and
+		** put the thread on that cpu's run queue.  There are two cases to
+		** take care of.  If the currently running thread is also a local
+		** thread, we just assign our own cpu to that thread and put it on
+		** the cpu's run queue.  If the the currently running thread is a
+		** native thread, we assign the primordial cpu to it (on NT,
+		** MD_WAKEUP handles the cpu assignment).  
+		*/
+		
+        if ( !_PR_IS_NATIVE_THREAD(t) ) {
+
+            t->state = _PR_RUNNABLE;
+
+            me = _PR_MD_CURRENT_THREAD();
+
+            _PR_AddThreadToRunQ(me, t);
+            _PR_THREAD_UNLOCK(t);
+        } else {
+            t->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(t);
+        }
+        _PR_MD_WAKEUP_WAITER(t);
+        break;
+    }
+    return;
+}
+
+/************************************************************************/
+
+
+PR_IMPLEMENT(PRLock*) PR_NewLock(void)
+{
+    PRLock *lock;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    lock = PR_NEWZAP(PRLock);
+    if (lock) {
+        if (_PR_MD_NEW_LOCK(&lock->ilock) == PR_FAILURE) {
+		PR_DELETE(lock);
+		return(NULL);
+	}
+        PR_INIT_CLIST(&lock->links);
+        PR_INIT_CLIST(&lock->waitQ);
+    }
+    return lock;
+}
+
+/*
+** Destroy the given lock "lock". There is no point in making this race
+** free because if some other thread has the pointer to this lock all
+** bets are off.
+*/
+PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock)
+{
+    PR_ASSERT(lock->owner == 0);
+	_PR_MD_FREE_LOCK(&lock->ilock);
+    PR_DELETE(lock);
+}
+
+extern PRThread *suspendAllThread;
+/*
+** Lock the lock.
+*/
+PR_IMPLEMENT(void) PR_Lock(PRLock *lock)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntn is;
+    PRThread *t;
+    PRCList *q;
+
+    PR_ASSERT(me != suspendAllThread); 
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+    PR_ASSERT(lock != NULL);
+#ifdef _PR_GLOBAL_THREADS_ONLY 
+    PR_ASSERT(lock->owner != me);
+    _PR_MD_LOCK(&lock->ilock);
+    lock->owner = me;
+    return;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+	if (_native_threads_only) {
+		PR_ASSERT(lock->owner != me);
+		_PR_MD_LOCK(&lock->ilock);
+		lock->owner = me;
+		return;
+	}
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+retry:
+    _PR_LOCK_LOCK(lock);
+    if (lock->owner == 0) {
+        /* Just got the lock */
+        lock->owner = me;
+        lock->priority = me->priority;
+		/* Add the granted lock to this owning thread's lock list */
+        PR_APPEND_LINK(&lock->links, &me->lockList);
+        _PR_LOCK_UNLOCK(lock);
+    	if (!_PR_IS_NATIVE_THREAD(me))
+        	_PR_FAST_INTSON(is);
+        return;
+    }
+
+    /* If this thread already owns this lock, then it is a deadlock */
+    PR_ASSERT(lock->owner != me);
+
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+#if 0
+    if (me->priority > lock->owner->priority) {
+        /*
+        ** Give the lock owner a priority boost until we get the
+        ** lock. Record the priority we boosted it to.
+        */
+        lock->boostPriority = me->priority;
+        _PR_SetThreadPriority(lock->owner, me->priority);
+    }
+#endif
+
+    /* 
+    Add this thread to the asked for lock's list of waiting threads.  We
+    add this thread thread in the right priority order so when the unlock
+    occurs, the thread with the higher priority will get the lock.
+    */
+    q = lock->waitQ.next;
+    if (q == &lock->waitQ || _PR_THREAD_CONDQ_PTR(q)->priority ==
+      	_PR_THREAD_CONDQ_PTR(lock->waitQ.prev)->priority) {
+		/*
+		 * If all the threads in the lock waitQ have the same priority,
+		 * then avoid scanning the list:  insert the element at the end.
+		 */
+		q = &lock->waitQ;
+    } else {
+		/* Sort thread into lock's waitQ at appropriate point */
+		/* Now scan the list for where to insert this entry */
+		while (q != &lock->waitQ) {
+			t = _PR_THREAD_CONDQ_PTR(lock->waitQ.next);
+			if (me->priority > t->priority) {
+				/* Found a lower priority thread to insert in front of */
+				break;
+			}
+			q = q->next;
+		}
+	}
+    PR_INSERT_BEFORE(&me->waitQLinks, q);
+
+	/* 
+	Now grab the threadLock since we are about to change the state.  We have
+	to do this since a PR_Suspend or PR_SetThreadPriority type call that takes
+	a PRThread* as an argument could be changing the state of this thread from
+	a thread running on a different cpu.
+	*/
+
+    _PR_THREAD_LOCK(me);
+    me->state = _PR_LOCK_WAIT;
+    me->wait.lock = lock;
+    _PR_THREAD_UNLOCK(me);
+
+    _PR_LOCK_UNLOCK(lock);
+
+    _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+	goto retry;
+
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/*
+** Unlock the lock.
+*/
+PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock)
+{
+    PRCList *q;
+    PRThreadPriority pri, boost;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(lock != NULL);
+    PR_ASSERT(lock->owner == me);
+    PR_ASSERT(me != suspendAllThread); 
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+    if (lock->owner != me) {
+        return PR_FAILURE;
+    }
+
+#ifdef _PR_GLOBAL_THREADS_ONLY 
+    lock->owner = 0;
+    _PR_MD_UNLOCK(&lock->ilock);
+    return PR_SUCCESS;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+	if (_native_threads_only) {
+		lock->owner = 0;
+		_PR_MD_UNLOCK(&lock->ilock);
+		return PR_SUCCESS;
+	}
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+    _PR_LOCK_LOCK(lock);
+
+	/* Remove the lock from the owning thread's lock list */
+    PR_REMOVE_LINK(&lock->links);
+    pri = lock->priority;
+    boost = lock->boostPriority;
+    if (boost > pri) {
+        /*
+        ** We received a priority boost during the time we held the lock.
+        ** We need to figure out what priority to move to by scanning
+        ** down our list of lock's that we are still holding and using
+        ** the highest boosted priority found.
+        */
+        q = me->lockList.next;
+        while (q != &me->lockList) {
+            PRLock *ll = _PR_LOCK_PTR(q);
+            if (ll->boostPriority > pri) {
+                pri = ll->boostPriority;
+            }
+            q = q->next;
+        }
+        if (pri != me->priority) {
+            _PR_SetThreadPriority(me, pri);
+        }
+    }
+
+    /* Unblock the first waiting thread */
+    q = lock->waitQ.next;
+    if (q != &lock->waitQ)
+        _PR_UnblockLockWaiter(lock);
+    lock->boostPriority = PR_PRIORITY_LOW;
+    lock->owner = 0;
+    _PR_LOCK_UNLOCK(lock);
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSON(is);
+    return PR_SUCCESS;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/*
+**  If the current thread owns |lock|, this assertion is guaranteed to
+**  succeed.  Otherwise, the behavior of this function is undefined.
+*/
+PR_IMPLEMENT(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PR_ASSERT(lock->owner == me);
+}
+
+/*
+** Test and then lock the lock if it's not already locked by some other
+** thread. Return PR_FALSE if some other thread owned the lock at the
+** time of the call.
+*/
+PR_IMPLEMENT(PRBool) PR_TestAndLock(PRLock *lock)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRBool rv = PR_FALSE;
+    PRIntn is;
+
+#ifdef _PR_GLOBAL_THREADS_ONLY 
+    is = _PR_MD_TEST_AND_LOCK(&lock->ilock);
+    if (is == 0) {
+        lock->owner = me;
+        return PR_TRUE;
+    }
+    return PR_FALSE;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+#ifndef _PR_LOCAL_THREADS_ONLY
+	if (_native_threads_only) {
+		is = _PR_MD_TEST_AND_LOCK(&lock->ilock);
+		if (is == 0) {
+			lock->owner = me;
+			return PR_TRUE;
+		}
+    	return PR_FALSE;
+	}
+#endif
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+
+    _PR_LOCK_LOCK(lock);
+    if (lock->owner == 0) {
+        /* Just got the lock */
+        lock->owner = me;
+        lock->priority = me->priority;
+		/* Add the granted lock to this owning thread's lock list */
+        PR_APPEND_LINK(&lock->links, &me->lockList);
+        rv = PR_TRUE;
+    }
+    _PR_LOCK_UNLOCK(lock);
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSON(is);
+    return rv;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/************************************************************************/
+/************************************************************************/
+/***********************ROUTINES FOR DCE EMULATION***********************/
+/************************************************************************/
+/************************************************************************/
+PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock)
+    { return (PR_TestAndLock(lock)) ? PR_SUCCESS : PR_FAILURE; }
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prustack.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prustack.c
new file mode 100644
index 0000000..fe15843
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/prustack.c
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+/* List of free stack virtual memory chunks */
+PRLock *_pr_stackLock;
+PRCList _pr_freeStacks = PR_INIT_STATIC_CLIST(&_pr_freeStacks);
+PRIntn _pr_numFreeStacks;
+PRIntn _pr_maxFreeStacks = 4;
+
+#ifdef DEBUG
+/*
+** A variable that can be set via the debugger...
+*/
+PRBool _pr_debugStacks = PR_FALSE;
+#endif
+
+/* How much space to leave between the stacks, at each end */
+#define REDZONE		(2 << _pr_pageShift)
+
+#define _PR_THREAD_STACK_PTR(_qp) \
+    ((PRThreadStack*) ((char*) (_qp) - offsetof(PRThreadStack,links)))
+
+void _PR_InitStacks(void)
+{
+    _pr_stackLock = PR_NewLock();
+}
+
+void _PR_CleanupStacks(void)
+{
+    if (_pr_stackLock) {
+        PR_DestroyLock(_pr_stackLock);
+        _pr_stackLock = NULL;
+    }
+}
+
+/*
+** Allocate a stack for a thread.
+*/
+PRThreadStack *_PR_NewStack(PRUint32 stackSize)
+{
+    PRCList *qp;
+    PRThreadStack *ts;
+    PRThread *thr;
+
+    /*
+    ** Trim the list of free stacks. Trim it backwards, tossing out the
+    ** oldest stack found first (this way more recent stacks have a
+    ** chance of being present in the data cache).
+    */
+    PR_Lock(_pr_stackLock);
+    qp = _pr_freeStacks.prev;
+    while ((_pr_numFreeStacks > _pr_maxFreeStacks) && (qp != &_pr_freeStacks)) {
+	ts = _PR_THREAD_STACK_PTR(qp);
+	thr = _PR_THREAD_STACK_TO_PTR(ts);
+	qp = qp->prev;
+	/*
+	 * skip stacks which are still being used
+	 */
+	if (thr->no_sched)
+		continue;
+	PR_REMOVE_LINK(&ts->links);
+
+	/* Give platform OS to clear out the stack for debugging */
+	_PR_MD_CLEAR_STACK(ts);
+
+	_pr_numFreeStacks--;
+	_PR_DestroySegment(ts->seg);
+	PR_DELETE(ts);
+    }
+
+    /*
+    ** Find a free thread stack. This searches the list of free'd up
+    ** virtually mapped thread stacks.
+    */
+    qp = _pr_freeStacks.next;
+    ts = 0;
+    while (qp != &_pr_freeStacks) {
+	ts = _PR_THREAD_STACK_PTR(qp);
+	thr = _PR_THREAD_STACK_TO_PTR(ts);
+	qp = qp->next;
+	/*
+	 * skip stacks which are still being used
+	 */
+	if ((!(thr->no_sched)) && ((ts->allocSize - 2*REDZONE) >= stackSize)) {
+	    /*
+	    ** Found a stack that is not in use and is big enough. Change
+	    ** stackSize to fit it.
+	    */
+	    stackSize = ts->allocSize - 2*REDZONE;
+	    PR_REMOVE_LINK(&ts->links);
+	    _pr_numFreeStacks--;
+	    ts->links.next = 0;
+	    ts->links.prev = 0;
+	    PR_Unlock(_pr_stackLock);
+	    goto done;
+	}
+	ts = 0;
+    }
+    PR_Unlock(_pr_stackLock);
+
+    if (!ts) {
+	/* Make a new thread stack object. */
+	ts = PR_NEWZAP(PRThreadStack);
+	if (!ts) {
+	    return NULL;
+	}
+
+	/*
+	** Assign some of the virtual space to the new stack object. We
+	** may not get that piece of VM, but if nothing else we will
+	** advance the pointer so we don't collide (unless the OS screws
+	** up).
+	*/
+	ts->allocSize = stackSize + 2*REDZONE;
+	ts->seg = _PR_NewSegment(ts->allocSize, 0);
+	if (!ts->seg) {
+	    PR_DELETE(ts);
+	    return NULL;
+	}
+	}
+
+  done:
+    ts->allocBase = (char*)ts->seg->vaddr;
+    ts->flags = _PR_STACK_MAPPED;
+    ts->stackSize = stackSize;
+
+#ifdef HAVE_STACK_GROWING_UP
+    ts->stackTop = ts->allocBase + REDZONE;
+    ts->stackBottom = ts->stackTop + stackSize;
+#else
+    ts->stackBottom = ts->allocBase + REDZONE;
+    ts->stackTop = ts->stackBottom + stackSize;
+#endif
+
+    PR_LOG(_pr_thread_lm, PR_LOG_NOTICE,
+	   ("thread stack: base=0x%x limit=0x%x bottom=0x%x top=0x%x\n",
+	    ts->allocBase, ts->allocBase + ts->allocSize - 1,
+	    ts->allocBase + REDZONE,
+	    ts->allocBase + REDZONE + stackSize - 1));
+	    
+    _PR_MD_INIT_STACK(ts,REDZONE);
+
+    return ts;
+}
+
+/*
+** Free the stack for the current thread
+*/
+void _PR_FreeStack(PRThreadStack *ts)
+{
+    if (!ts) {
+	return;
+    }
+    if (ts->flags & _PR_STACK_PRIMORDIAL) {
+	PR_DELETE(ts);
+	return;
+    }
+
+    /*
+    ** Put the stack on the free list. This is done because we are still
+    ** using the stack. Next time a thread is created we will trim the
+    ** list down; it's safe to do it then because we will have had to
+    ** context switch to a live stack before another thread can be
+    ** created.
+    */
+    PR_Lock(_pr_stackLock);
+    PR_APPEND_LINK(&ts->links, _pr_freeStacks.prev);
+    _pr_numFreeStacks++;
+    PR_Unlock(_pr_stackLock);
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/pruthr.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/pruthr.c
new file mode 100644
index 0000000..86c8276
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/combined/pruthr.c
@@ -0,0 +1,1895 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include <signal.h>
+#include <string.h>
+
+#if defined(WIN95)                                                                         
+/*
+** Some local variables report warnings on Win95 because the code paths
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+**
+*/
+#pragma warning(disable : 4101)
+#endif          
+
+/* _pr_activeLock protects the following global variables */
+PRLock *_pr_activeLock;
+PRInt32 _pr_primordialExitCount;   /* In PR_Cleanup(), the primordial thread
+                    * waits until all other user (non-system)
+                    * threads have terminated before it exits.
+                    * So whenever we decrement _pr_userActive,
+                    * it is compared with
+                    * _pr_primordialExitCount.
+                    * If the primordial thread is a system
+                    * thread, then _pr_primordialExitCount
+                    * is 0.  If the primordial thread is
+                    * itself a user thread, then 
+                    * _pr_primordialThread is 1.
+                    */
+PRCondVar *_pr_primordialExitCVar; /* When _pr_userActive is decremented to
+                    * _pr_primordialExitCount, this condition
+                    * variable is notified.
+                    */
+
+PRLock *_pr_deadQLock;
+PRUint32 _pr_numNativeDead;
+PRUint32 _pr_numUserDead;
+PRCList _pr_deadNativeQ;
+PRCList _pr_deadUserQ;
+
+PRUint32 _pr_join_counter;
+
+PRUint32 _pr_local_threads;
+PRUint32 _pr_global_threads;
+
+PRBool suspendAllOn = PR_FALSE;
+PRThread *suspendAllThread = NULL;
+
+extern PRCList _pr_active_global_threadQ;
+extern PRCList _pr_active_local_threadQ;
+
+static void _PR_DecrActiveThreadCount(PRThread *thread);
+static PRThread *_PR_AttachThread(PRThreadType, PRThreadPriority, PRThreadStack *);
+static void _PR_InitializeNativeStack(PRThreadStack *ts);
+static void _PR_InitializeRecycledThread(PRThread *thread);
+static void _PR_UserRunThread(void);
+
+void _PR_InitThreads(PRThreadType type, PRThreadPriority priority,
+    PRUintn maxPTDs)
+{
+    PRThread *thread;
+    PRThreadStack *stack;
+
+    _pr_terminationCVLock = PR_NewLock();
+    _pr_activeLock = PR_NewLock();
+
+#ifndef HAVE_CUSTOM_USER_THREADS
+    stack = PR_NEWZAP(PRThreadStack);
+#ifdef HAVE_STACK_GROWING_UP
+    stack->stackTop = (char*) ((((long)&type) >> _pr_pageShift)
+                  << _pr_pageShift);
+#else
+#if defined(SOLARIS) || defined (UNIXWARE) && defined (USR_SVR4_THREADS)
+    stack->stackTop = (char*) &thread;
+#else
+    stack->stackTop = (char*) ((((long)&type + _pr_pageSize - 1)
+                >> _pr_pageShift) << _pr_pageShift);
+#endif
+#endif
+#else
+    /* If stack is NULL, we're using custom user threads like NT fibers. */
+    stack = PR_NEWZAP(PRThreadStack);
+    if (stack) {
+        stack->stackSize = 0;
+        _PR_InitializeNativeStack(stack);
+    }
+#endif /* HAVE_CUSTOM_USER_THREADS */
+
+    thread = _PR_AttachThread(type, priority, stack);
+    if (thread) {
+        _PR_MD_SET_CURRENT_THREAD(thread);
+
+        if (type == PR_SYSTEM_THREAD) {
+            thread->flags = _PR_SYSTEM;
+            _pr_systemActive++;
+            _pr_primordialExitCount = 0;
+        } else {
+            _pr_userActive++;
+            _pr_primordialExitCount = 1;
+        }
+    thread->no_sched = 1;
+    _pr_primordialExitCVar = PR_NewCondVar(_pr_activeLock);
+    }
+
+    if (!thread) PR_Abort();
+#ifdef _PR_LOCAL_THREADS_ONLY
+    thread->flags |= _PR_PRIMORDIAL;
+#else
+    thread->flags |= _PR_PRIMORDIAL | _PR_GLOBAL_SCOPE;
+#endif
+
+    /*
+     * Needs _PR_PRIMORDIAL flag set before calling
+     * _PR_MD_INIT_THREAD()
+     */
+    if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
+        /*
+         * XXX do what?
+         */
+    }
+
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ());
+        _pr_global_threads++;
+    } else {
+        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ());
+        _pr_local_threads++;
+    }
+
+    _pr_recycleThreads = 0;
+    _pr_deadQLock = PR_NewLock();
+    _pr_numNativeDead = 0;
+    _pr_numUserDead = 0;
+    PR_INIT_CLIST(&_pr_deadNativeQ);
+    PR_INIT_CLIST(&_pr_deadUserQ);
+}
+
+void _PR_CleanupThreads(void)
+{
+    if (_pr_terminationCVLock) {
+        PR_DestroyLock(_pr_terminationCVLock);
+        _pr_terminationCVLock = NULL;
+    }
+    if (_pr_activeLock) {
+        PR_DestroyLock(_pr_activeLock);
+        _pr_activeLock = NULL;
+    }
+    if (_pr_primordialExitCVar) {
+        PR_DestroyCondVar(_pr_primordialExitCVar);
+        _pr_primordialExitCVar = NULL;
+    }
+    /* TODO _pr_dead{Native,User}Q need to be deleted */
+    if (_pr_deadQLock) {
+        PR_DestroyLock(_pr_deadQLock);
+        _pr_deadQLock = NULL;
+    }
+}
+
+/*
+** Initialize a stack for a native thread
+*/
+static void _PR_InitializeNativeStack(PRThreadStack *ts)
+{
+    if( ts && (ts->stackTop == 0) ) {
+        ts->allocSize = ts->stackSize;
+
+        /*
+        ** Setup stackTop and stackBottom values.
+        */
+#ifdef HAVE_STACK_GROWING_UP
+    ts->allocBase = (char*) ((((long)&ts) >> _pr_pageShift)
+                  << _pr_pageShift);
+        ts->stackBottom = ts->allocBase + ts->stackSize;
+        ts->stackTop = ts->allocBase;
+#else
+        ts->allocBase = (char*) ((((long)&ts + _pr_pageSize - 1)
+                >> _pr_pageShift) << _pr_pageShift);
+        ts->stackTop    = ts->allocBase;
+        ts->stackBottom = ts->allocBase - ts->stackSize;
+#endif
+    }
+}
+
+void _PR_NotifyJoinWaiters(PRThread *thread)
+{
+    /*
+    ** Handle joinable threads.  Change the state to waiting for join.
+    ** Remove from our run Q and put it on global waiting to join Q.
+    ** Notify on our "termination" condition variable so that joining
+    ** thread will know about our termination.  Switch our context and
+    ** come back later on to continue the cleanup.
+    */    
+    PR_ASSERT(thread == _PR_MD_CURRENT_THREAD());
+    if (thread->term != NULL) {
+        PR_Lock(_pr_terminationCVLock);
+        _PR_THREAD_LOCK(thread);
+        thread->state = _PR_JOIN_WAIT;
+        if ( !_PR_IS_NATIVE_THREAD(thread) ) {
+            _PR_MISCQ_LOCK(thread->cpu);
+            _PR_ADD_JOINQ(thread, thread->cpu);
+            _PR_MISCQ_UNLOCK(thread->cpu);
+        }
+        _PR_THREAD_UNLOCK(thread);
+        PR_NotifyCondVar(thread->term);
+        PR_Unlock(_pr_terminationCVLock);
+        _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT);
+        PR_ASSERT(thread->state != _PR_JOIN_WAIT);
+    }
+
+}
+
+/*
+ * Zero some of the data members of a recycled thread.
+ *
+ * Note that we can do this either when a dead thread is added to
+ * the dead thread queue or when it is reused.  Here, we are doing
+ * this lazily, when the thread is reused in _PR_CreateThread().
+ */
+static void _PR_InitializeRecycledThread(PRThread *thread)
+{
+    /*
+     * Assert that the following data members are already zeroed
+     * by _PR_CleanupThread().
+     */
+#ifdef DEBUG
+    if (thread->privateData) {
+        unsigned int i;
+        for (i = 0; i < thread->tpdLength; i++) {
+            PR_ASSERT(thread->privateData[i] == NULL);
+        }
+    }
+#endif
+    PR_ASSERT(thread->dumpArg == 0 && thread->dump == 0);
+    PR_ASSERT(thread->errorString == 0 && thread->errorStringSize == 0);
+    PR_ASSERT(thread->errorStringLength == 0);
+
+    /* Reset data members in thread structure */
+    thread->errorCode = thread->osErrorCode = 0;
+    thread->io_pending = thread->io_suspended = PR_FALSE;
+    thread->environment = 0;
+    PR_INIT_CLIST(&thread->lockList);
+}
+
+PRStatus _PR_RecycleThread(PRThread *thread)
+{
+    if ( _PR_IS_NATIVE_THREAD(thread) &&
+            _PR_NUM_DEADNATIVE < _pr_recycleThreads) {
+        _PR_DEADQ_LOCK;
+        PR_APPEND_LINK(&thread->links, &_PR_DEADNATIVEQ);
+        _PR_INC_DEADNATIVE;
+        _PR_DEADQ_UNLOCK;
+    return (PR_SUCCESS);
+    } else if ( !_PR_IS_NATIVE_THREAD(thread) &&
+                _PR_NUM_DEADUSER < _pr_recycleThreads) {
+        _PR_DEADQ_LOCK;
+        PR_APPEND_LINK(&thread->links, &_PR_DEADUSERQ);
+        _PR_INC_DEADUSER;
+        _PR_DEADQ_UNLOCK;
+    return (PR_SUCCESS);
+    }
+    return (PR_FAILURE);
+}
+
+/*
+ * Decrement the active thread count, either _pr_systemActive or
+ * _pr_userActive, depending on whether the thread is a system thread
+ * or a user thread.  If all the user threads, except possibly
+ * the primordial thread, have terminated, we notify the primordial
+ * thread of this condition.
+ *
+ * Since this function will lock _pr_activeLock, do not call this
+ * function while holding the _pr_activeLock lock, as this will result
+ * in a deadlock.
+ */
+
+static void
+_PR_DecrActiveThreadCount(PRThread *thread)
+{
+    PR_Lock(_pr_activeLock);
+    if (thread->flags & _PR_SYSTEM) {
+        _pr_systemActive--;
+    } else {
+        _pr_userActive--;
+        if (_pr_userActive == _pr_primordialExitCount) {
+            PR_NotifyCondVar(_pr_primordialExitCVar);
+        }
+    }
+    PR_Unlock(_pr_activeLock);
+}
+
+/*
+** Detach thread structure
+*/
+static void
+_PR_DestroyThread(PRThread *thread)
+{
+    _PR_MD_FREE_LOCK(&thread->threadLock);
+    PR_DELETE(thread);
+}
+
+void
+_PR_NativeDestroyThread(PRThread *thread)
+{
+    if(thread->term) {
+        PR_DestroyCondVar(thread->term);
+        thread->term = 0;
+    }
+    if (NULL != thread->privateData) {
+        PR_ASSERT(0 != thread->tpdLength);
+        PR_DELETE(thread->privateData);
+        thread->tpdLength = 0;
+    }
+    PR_DELETE(thread->stack);
+    _PR_DestroyThread(thread);
+}
+
+void
+_PR_UserDestroyThread(PRThread *thread)
+{
+    if(thread->term) {
+        PR_DestroyCondVar(thread->term);
+        thread->term = 0;
+    }
+    if (NULL != thread->privateData) {
+        PR_ASSERT(0 != thread->tpdLength);
+        PR_DELETE(thread->privateData);
+        thread->tpdLength = 0;
+    }
+    _PR_MD_FREE_LOCK(&thread->threadLock);
+    if (thread->threadAllocatedOnStack == 1) {
+        _PR_MD_CLEAN_THREAD(thread);
+        /*
+         *  Because the no_sched field is set, this thread/stack will
+         *  will not be re-used until the flag is cleared by the thread
+         *  we will context switch to.
+         */
+        _PR_FreeStack(thread->stack);
+    } else {
+#ifdef WINNT
+        _PR_MD_CLEAN_THREAD(thread);
+#else
+        /*
+         * This assertion does not apply to NT.  On NT, every fiber
+         * has its threadAllocatedOnStack equal to 0.  Elsewhere,
+         * only the primordial thread has its threadAllocatedOnStack
+         * equal to 0.
+         */
+        PR_ASSERT(thread->flags & _PR_PRIMORDIAL);
+#endif
+    }
+}
+
+
+/*
+** Run a thread's start function. When the start function returns the
+** thread is done executing and no longer needs the CPU. If there are no
+** more user threads running then we can exit the program.
+*/
+void _PR_NativeRunThread(void *arg)
+{
+    PRThread *thread = (PRThread *)arg;
+
+    _PR_MD_SET_CURRENT_THREAD(thread);
+
+    _PR_MD_SET_CURRENT_CPU(NULL);
+
+    /* Set up the thread stack information */
+    _PR_InitializeNativeStack(thread->stack);
+
+    /* Set up the thread md information */
+    if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
+        /*
+         * thread failed to initialize itself, possibly due to
+         * failure to allocate per-thread resources
+         */
+        return;
+    }
+
+    while(1) {
+        thread->state = _PR_RUNNING;
+
+        /*
+         * Add to list of active threads
+         */
+        PR_Lock(_pr_activeLock);
+        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ());
+        _pr_global_threads++;
+        PR_Unlock(_pr_activeLock);
+
+        (*thread->startFunc)(thread->arg);
+
+        /*
+         * The following two assertions are meant for NT asynch io.
+         *
+         * The thread should have no asynch io in progress when it
+         * exits, otherwise the overlapped buffer, which is part of
+         * the thread structure, would become invalid.
+         */
+        PR_ASSERT(thread->io_pending == PR_FALSE);
+        /*
+         * This assertion enforces the programming guideline that
+         * if an io function times out or is interrupted, the thread
+         * should close the fd to force the asynch io to abort
+         * before it exits.  Right now, closing the fd is the only
+         * way to clear the io_suspended flag.
+         */
+        PR_ASSERT(thread->io_suspended == PR_FALSE);
+
+        /*
+         * remove thread from list of active threads
+         */
+        PR_Lock(_pr_activeLock);
+        PR_REMOVE_LINK(&thread->active);
+        _pr_global_threads--;
+        PR_Unlock(_pr_activeLock);
+
+        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting"));
+
+        /* All done, time to go away */
+        _PR_CleanupThread(thread);
+
+        _PR_NotifyJoinWaiters(thread);
+
+        _PR_DecrActiveThreadCount(thread);
+
+        thread->state = _PR_DEAD_STATE;
+
+        if (!_pr_recycleThreads || (_PR_RecycleThread(thread) ==
+                        PR_FAILURE)) {
+            /*
+             * thread not recycled
+             * platform-specific thread exit processing
+             *        - for stuff like releasing native-thread resources, etc.
+             */
+            _PR_MD_EXIT_THREAD(thread);
+            /*
+             * Free memory allocated for the thread
+             */
+            _PR_NativeDestroyThread(thread);
+            /*
+             * thread gone, cannot de-reference thread now
+             */
+            return;
+        }
+
+        /* Now wait for someone to activate us again... */
+        _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT);
+    }
+}
+
+static void _PR_UserRunThread(void)
+{
+    PRThread *thread = _PR_MD_CURRENT_THREAD();
+    PRIntn is;
+
+    if (_MD_LAST_THREAD())
+    _MD_LAST_THREAD()->no_sched = 0;
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+    if (thread->stack == NULL) {
+        thread->stack = PR_NEWZAP(PRThreadStack);
+        _PR_InitializeNativeStack(thread->stack);
+    }
+#endif /* HAVE_CUSTOM_USER_THREADS */
+
+    while(1) {
+        /* Run thread main */
+        if ( !_PR_IS_NATIVE_THREAD(thread)) _PR_MD_SET_INTSOFF(0);
+
+    /*
+     * Add to list of active threads
+     */
+    if (!(thread->flags & _PR_IDLE_THREAD)) {
+        PR_Lock(_pr_activeLock);
+        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ());
+        _pr_local_threads++;
+        PR_Unlock(_pr_activeLock);
+    }
+
+        (*thread->startFunc)(thread->arg);
+
+        /*
+         * The following two assertions are meant for NT asynch io.
+         *
+         * The thread should have no asynch io in progress when it
+         * exits, otherwise the overlapped buffer, which is part of
+         * the thread structure, would become invalid.
+         */
+        PR_ASSERT(thread->io_pending == PR_FALSE);
+        /*
+         * This assertion enforces the programming guideline that
+         * if an io function times out or is interrupted, the thread
+         * should close the fd to force the asynch io to abort
+         * before it exits.  Right now, closing the fd is the only
+         * way to clear the io_suspended flag.
+         */
+        PR_ASSERT(thread->io_suspended == PR_FALSE);
+
+        PR_Lock(_pr_activeLock);
+    /*
+     * remove thread from list of active threads
+     */
+    if (!(thread->flags & _PR_IDLE_THREAD)) {
+           PR_REMOVE_LINK(&thread->active);
+        _pr_local_threads--;
+    }
+    PR_Unlock(_pr_activeLock);
+        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting"));
+
+        /* All done, time to go away */
+        _PR_CleanupThread(thread);
+
+        _PR_INTSOFF(is);    
+
+        _PR_NotifyJoinWaiters(thread);
+
+    _PR_DecrActiveThreadCount(thread);
+
+        thread->state = _PR_DEAD_STATE;
+
+        if (!_pr_recycleThreads || (_PR_RecycleThread(thread) ==
+                        PR_FAILURE)) {
+            /*
+            ** Destroy the thread resources
+            */
+        _PR_UserDestroyThread(thread);
+        }
+
+        /*
+        ** Find another user thread to run. This cpu has finished the
+        ** previous threads main and is now ready to run another thread.
+        */
+        {
+            PRInt32 is;
+            _PR_INTSOFF(is);
+            _PR_MD_SWITCH_CONTEXT(thread);
+        }
+
+        /* Will land here when we get scheduled again if we are recycling... */
+    }
+}
+
+void _PR_SetThreadPriority(PRThread *thread, PRThreadPriority newPri)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntn is;
+
+    if ( _PR_IS_NATIVE_THREAD(thread) ) {
+        _PR_MD_SET_PRIORITY(&(thread->md), newPri);
+        return;
+    }
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(thread);
+    if (newPri != thread->priority) {
+    _PRCPU *cpu = thread->cpu;
+
+    switch (thread->state) {
+      case _PR_RUNNING:
+        /* Change my priority */
+
+            _PR_RUNQ_LOCK(cpu);
+        thread->priority = newPri;
+        if (_PR_RUNQREADYMASK(cpu) >> (newPri + 1)) {
+            if (!_PR_IS_NATIVE_THREAD(me))
+                    _PR_SET_RESCHED_FLAG();
+        }
+            _PR_RUNQ_UNLOCK(cpu);
+        break;
+
+      case _PR_RUNNABLE:
+
+        _PR_RUNQ_LOCK(cpu);
+            /* Move to different runQ */
+            _PR_DEL_RUNQ(thread);
+            thread->priority = newPri;
+            PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+            _PR_ADD_RUNQ(thread, cpu, newPri);
+        _PR_RUNQ_UNLOCK(cpu);
+
+            if (newPri > me->priority) {
+            if (!_PR_IS_NATIVE_THREAD(me))
+                    _PR_SET_RESCHED_FLAG();
+            }
+
+        break;
+
+      case _PR_LOCK_WAIT:
+      case _PR_COND_WAIT:
+      case _PR_IO_WAIT:
+      case _PR_SUSPENDED:
+
+        thread->priority = newPri;
+        break;
+    }
+    }
+    _PR_THREAD_UNLOCK(thread);
+    if (!_PR_IS_NATIVE_THREAD(me))
+    _PR_INTSON(is);
+}
+
+/*
+** Suspend the named thread and copy its gc registers into regBuf
+*/
+static void _PR_Suspend(PRThread *thread)
+{
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(thread != me);
+    PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread) || (!thread->cpu));
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(thread);
+    switch (thread->state) {
+      case _PR_RUNNABLE:
+        if (!_PR_IS_NATIVE_THREAD(thread)) {
+            _PR_RUNQ_LOCK(thread->cpu);
+            _PR_DEL_RUNQ(thread);
+            _PR_RUNQ_UNLOCK(thread->cpu);
+
+            _PR_MISCQ_LOCK(thread->cpu);
+            _PR_ADD_SUSPENDQ(thread, thread->cpu);
+            _PR_MISCQ_UNLOCK(thread->cpu);
+        } else {
+            /*
+             * Only LOCAL threads are suspended by _PR_Suspend
+             */
+             PR_ASSERT(0);
+        }
+        thread->state = _PR_SUSPENDED;
+        break;
+
+      case _PR_RUNNING:
+        /*
+         * The thread being suspended should be a LOCAL thread with
+         * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state
+         */
+        PR_ASSERT(0);
+        break;
+
+      case _PR_LOCK_WAIT:
+      case _PR_IO_WAIT:
+      case _PR_COND_WAIT:
+        if (_PR_IS_NATIVE_THREAD(thread)) {
+            _PR_MD_SUSPEND_THREAD(thread);
+    }
+        thread->flags |= _PR_SUSPENDING;
+        break;
+
+      default:
+        PR_Abort();
+    }
+    _PR_THREAD_UNLOCK(thread);
+    if (!_PR_IS_NATIVE_THREAD(me))
+    _PR_INTSON(is);
+}
+
+static void _PR_Resume(PRThread *thread)
+{
+    PRThreadPriority pri;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(thread);
+    switch (thread->state) {
+      case _PR_SUSPENDED:
+        thread->state = _PR_RUNNABLE;
+        thread->flags &= ~_PR_SUSPENDING;
+        if (!_PR_IS_NATIVE_THREAD(thread)) {
+            _PR_MISCQ_LOCK(thread->cpu);
+            _PR_DEL_SUSPENDQ(thread);
+            _PR_MISCQ_UNLOCK(thread->cpu);
+
+            pri = thread->priority;
+
+            _PR_RUNQ_LOCK(thread->cpu);
+            _PR_ADD_RUNQ(thread, thread->cpu, pri);
+            _PR_RUNQ_UNLOCK(thread->cpu);
+
+            if (pri > _PR_MD_CURRENT_THREAD()->priority) {
+                if (!_PR_IS_NATIVE_THREAD(me))
+                    _PR_SET_RESCHED_FLAG();
+            }
+        } else {
+            PR_ASSERT(0);
+        }
+        break;
+
+      case _PR_IO_WAIT:
+      case _PR_COND_WAIT:
+        thread->flags &= ~_PR_SUSPENDING;
+/*      PR_ASSERT(thread->wait.monitor->stickyCount == 0); */
+        break;
+
+      case _PR_LOCK_WAIT: 
+      {
+        PRLock *wLock = thread->wait.lock;
+
+        thread->flags &= ~_PR_SUSPENDING;
+ 
+        _PR_LOCK_LOCK(wLock);
+        if (thread->wait.lock->owner == 0) {
+            _PR_UnblockLockWaiter(thread->wait.lock);
+        }
+        _PR_LOCK_UNLOCK(wLock);
+        break;
+      }
+      case _PR_RUNNABLE:
+        break;
+      case _PR_RUNNING:
+        /*
+         * The thread being suspended should be a LOCAL thread with
+         * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state
+         */
+        PR_ASSERT(0);
+        break;
+
+      default:
+    /*
+     * thread should have been in one of the above-listed blocked states
+     * (_PR_JOIN_WAIT, _PR_IO_WAIT, _PR_UNBORN, _PR_DEAD_STATE)
+     */
+        PR_Abort();
+    }
+    _PR_THREAD_UNLOCK(thread);
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSON(is);
+
+}
+
+#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
+static PRThread *get_thread(_PRCPU *cpu, PRBool *wakeup_cpus)
+{
+    PRThread *thread;
+    PRIntn pri;
+    PRUint32 r;
+    PRCList *qp;
+    PRIntn priMin, priMax;
+
+    _PR_RUNQ_LOCK(cpu);
+    r = _PR_RUNQREADYMASK(cpu);
+    if (r==0) {
+        priMin = priMax = PR_PRIORITY_FIRST;
+    } else if (r == (1<<PR_PRIORITY_NORMAL) ) {
+        priMin = priMax = PR_PRIORITY_NORMAL;
+    } else {
+        priMin = PR_PRIORITY_FIRST;
+        priMax = PR_PRIORITY_LAST;
+    }
+    thread = NULL;
+    for (pri = priMax; pri >= priMin ; pri-- ) {
+    if (r & (1 << pri)) {
+            for (qp = _PR_RUNQ(cpu)[pri].next; 
+                 qp != &_PR_RUNQ(cpu)[pri];
+                 qp = qp->next) {
+                thread = _PR_THREAD_PTR(qp);
+                /*
+                * skip non-schedulable threads
+                */
+                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+                if (thread->no_sched) {
+                    thread = NULL;
+                    /*
+                     * Need to wakeup cpus to avoid missing a
+                     * runnable thread
+                     * Waking up all CPU's need happen only once.
+                     */
+
+                    *wakeup_cpus = PR_TRUE;
+                    continue;
+                } else if (thread->flags & _PR_BOUND_THREAD) {
+                    /*
+                     * Thread bound to cpu 0
+                     */
+
+                    thread = NULL;
+#ifdef IRIX
+					_PR_MD_WAKEUP_PRIMORDIAL_CPU();
+#endif
+                    continue;
+                } else if (thread->io_pending == PR_TRUE) {
+                    /*
+                     * A thread that is blocked for I/O needs to run
+                     * on the same cpu on which it was blocked. This is because
+                     * the cpu's ioq is accessed without lock protection and scheduling
+                     * the thread on a different cpu would preclude this optimization.
+                     */
+                    thread = NULL;
+                    continue;
+                } else {
+                    /* Pull thread off of its run queue */
+                    _PR_DEL_RUNQ(thread);
+                    _PR_RUNQ_UNLOCK(cpu);
+                    return(thread);
+                }
+            }
+        }
+        thread = NULL;
+    }
+    _PR_RUNQ_UNLOCK(cpu);
+    return(thread);
+}
+#endif /* !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) */
+
+/*
+** Schedule this native thread by finding the highest priority nspr
+** thread that is ready to run.
+**
+** Note- everyone really needs to call _PR_MD_SWITCH_CONTEXT (which calls
+**       PR_Schedule() rather than calling PR_Schedule.  Otherwise if there
+**       is initialization required for switching from SWITCH_CONTEXT,
+**       it will not get done!
+*/
+void _PR_Schedule(void)
+{
+    PRThread *thread, *me = _PR_MD_CURRENT_THREAD();
+    _PRCPU *cpu = _PR_MD_CURRENT_CPU();
+    PRIntn pri;
+    PRUint32 r;
+    PRCList *qp;
+    PRIntn priMin, priMax;
+#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
+    PRBool wakeup_cpus;
+#endif
+
+    /* Interrupts must be disabled */
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+    /* Since we are rescheduling, we no longer want to */
+    _PR_CLEAR_RESCHED_FLAG();
+
+    /*
+    ** Find highest priority thread to run. Bigger priority numbers are
+    ** higher priority threads
+    */
+    _PR_RUNQ_LOCK(cpu);
+    /*
+     *  if we are in SuspendAll mode, can schedule only the thread
+     *    that called PR_SuspendAll
+     *
+     *  The thread may be ready to run now, after completing an I/O
+     *  operation, for example
+     */
+    if ((thread = suspendAllThread) != 0) {
+    if ((!(thread->no_sched)) && (thread->state == _PR_RUNNABLE)) {
+            /* Pull thread off of its run queue */
+            _PR_DEL_RUNQ(thread);
+            _PR_RUNQ_UNLOCK(cpu);
+            goto found_thread;
+    } else {
+            thread = NULL;
+            _PR_RUNQ_UNLOCK(cpu);
+            goto idle_thread;
+    }
+    }
+    r = _PR_RUNQREADYMASK(cpu);
+    if (r==0) {
+        priMin = priMax = PR_PRIORITY_FIRST;
+    } else if (r == (1<<PR_PRIORITY_NORMAL) ) {
+        priMin = priMax = PR_PRIORITY_NORMAL;
+    } else {
+        priMin = PR_PRIORITY_FIRST;
+        priMax = PR_PRIORITY_LAST;
+    }
+    thread = NULL;
+    for (pri = priMax; pri >= priMin ; pri-- ) {
+    if (r & (1 << pri)) {
+            for (qp = _PR_RUNQ(cpu)[pri].next; 
+                 qp != &_PR_RUNQ(cpu)[pri];
+                 qp = qp->next) {
+                thread = _PR_THREAD_PTR(qp);
+                /*
+                * skip non-schedulable threads
+                */
+                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+                if ((thread->no_sched) && (me != thread)){
+                    thread = NULL;
+                    continue;
+                } else {
+                    /* Pull thread off of its run queue */
+                    _PR_DEL_RUNQ(thread);
+                    _PR_RUNQ_UNLOCK(cpu);
+                    goto found_thread;
+                }
+            }
+        }
+        thread = NULL;
+    }
+    _PR_RUNQ_UNLOCK(cpu);
+
+#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
+
+    wakeup_cpus = PR_FALSE;
+    _PR_CPU_LIST_LOCK();
+    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
+        if (cpu != _PR_CPU_PTR(qp)) {
+            if ((thread = get_thread(_PR_CPU_PTR(qp), &wakeup_cpus))
+                                        != NULL) {
+                thread->cpu = cpu;
+                _PR_CPU_LIST_UNLOCK();
+                if (wakeup_cpus == PR_TRUE)
+                    _PR_MD_WAKEUP_CPUS();
+                goto found_thread;
+            }
+        }
+    }
+    _PR_CPU_LIST_UNLOCK();
+    if (wakeup_cpus == PR_TRUE)
+        _PR_MD_WAKEUP_CPUS();
+
+#endif        /* _PR_LOCAL_THREADS_ONLY */
+
+idle_thread:
+   /*
+    ** There are no threads to run. Switch to the idle thread
+    */
+    PR_LOG(_pr_sched_lm, PR_LOG_MAX, ("pausing"));
+    thread = _PR_MD_CURRENT_CPU()->idle_thread;
+
+found_thread:
+    PR_ASSERT((me == thread) || ((thread->state == _PR_RUNNABLE) &&
+                    (!(thread->no_sched))));
+
+    /* Resume the thread */
+    PR_LOG(_pr_sched_lm, PR_LOG_MAX,
+       ("switching to %d[%p]", thread->id, thread));
+    PR_ASSERT(thread->state != _PR_RUNNING);
+    thread->state = _PR_RUNNING;
+ 
+    /* If we are on the runq, it just means that we went to sleep on some
+     * resource, and by the time we got here another real native thread had
+     * already given us the resource and put us back on the runqueue 
+     */
+	PR_ASSERT(thread->cpu == _PR_MD_CURRENT_CPU());
+    if (thread != me) 
+        _PR_MD_RESTORE_CONTEXT(thread);
+#if 0
+    /* XXXMB; with setjmp/longjmp it is impossible to land here, but 
+     * it is not with fibers... Is this a bad thing?  I believe it is 
+     * still safe.
+     */
+    PR_NOT_REACHED("impossible return from schedule");
+#endif
+}
+
+/*
+** Attaches a thread.  
+** Does not set the _PR_MD_CURRENT_THREAD.  
+** Does not specify the scope of the thread.
+*/
+static PRThread *
+_PR_AttachThread(PRThreadType type, PRThreadPriority priority,
+    PRThreadStack *stack)
+{
+    PRThread *thread;
+    char *mem;
+
+    if (priority > PR_PRIORITY_LAST) {
+        priority = PR_PRIORITY_LAST;
+    } else if (priority < PR_PRIORITY_FIRST) {
+        priority = PR_PRIORITY_FIRST;
+    }
+
+    mem = (char*) PR_CALLOC(sizeof(PRThread));
+    if (mem) {
+        thread = (PRThread*) mem;
+        thread->priority = priority;
+        thread->stack = stack;
+        thread->state = _PR_RUNNING;
+        PR_INIT_CLIST(&thread->lockList);
+        if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) {
+        PR_DELETE(thread);
+        return 0;
+    }
+
+        return thread;
+    }
+    return 0;
+}
+
+
+
+PR_IMPLEMENT(PRThread*) 
+_PR_NativeCreateThread(PRThreadType type,
+                     void (*start)(void *arg),
+                     void *arg,
+                     PRThreadPriority priority,
+                     PRThreadScope scope,
+                     PRThreadState state,
+                     PRUint32 stackSize,
+                     PRUint32 flags)
+{
+    PRThread *thread;
+
+    thread = _PR_AttachThread(type, priority, NULL);
+
+    if (thread) {
+        PR_Lock(_pr_activeLock);
+        thread->flags = (flags | _PR_GLOBAL_SCOPE);
+        thread->id = ++_pr_utid;
+        if (type == PR_SYSTEM_THREAD) {
+            thread->flags |= _PR_SYSTEM;
+            _pr_systemActive++;
+        } else {
+            _pr_userActive++;
+        }
+        PR_Unlock(_pr_activeLock);
+
+        thread->stack = PR_NEWZAP(PRThreadStack);
+        if (!thread->stack) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            goto done;
+        }
+        thread->stack->stackSize = stackSize?stackSize:_MD_DEFAULT_STACK_SIZE;
+        thread->stack->thr = thread;
+        thread->startFunc = start;
+        thread->arg = arg;
+
+        /* 
+          Set thread flags related to scope and joinable state. If joinable
+          thread, allocate a "termination" conidition variable.
+         */
+        if (state == PR_JOINABLE_THREAD) {
+            thread->term = PR_NewCondVar(_pr_terminationCVLock);
+        if (thread->term == NULL) {
+        PR_DELETE(thread->stack);
+        goto done;
+        }
+        }
+
+    thread->state = _PR_RUNNING;
+        if (_PR_MD_CREATE_THREAD(thread, _PR_NativeRunThread, priority,
+            scope,state,stackSize) == PR_SUCCESS) {
+            return thread;
+        }
+        if (thread->term) {
+            PR_DestroyCondVar(thread->term);
+            thread->term = NULL;
+        }
+    PR_DELETE(thread->stack);
+    }
+
+done:
+    if (thread) {
+    _PR_DecrActiveThreadCount(thread);
+        _PR_DestroyThread(thread);
+    }
+    return NULL;
+}
+
+/************************************************************************/
+
+PR_IMPLEMENT(PRThread*) _PR_CreateThread(PRThreadType type,
+                     void (*start)(void *arg),
+                     void *arg,
+                     PRThreadPriority priority,
+                     PRThreadScope scope,
+                     PRThreadState state,
+                     PRUint32 stackSize,
+                     PRUint32 flags)
+{
+    PRThread *me;
+    PRThread *thread = NULL;
+    PRThreadStack *stack;
+    char *top;
+    PRIntn is;
+    PRIntn native = 0;
+    PRIntn useRecycled = 0;
+    PRBool status;
+
+    /* 
+    First, pin down the priority.  Not all compilers catch passing out of
+    range enum here.  If we let bad values thru, priority queues won't work.
+    */
+    if (priority > PR_PRIORITY_LAST) {
+        priority = PR_PRIORITY_LAST;
+    } else if (priority < PR_PRIORITY_FIRST) {
+        priority = PR_PRIORITY_FIRST;
+    }
+        
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (! (flags & _PR_IDLE_THREAD))
+        me = _PR_MD_CURRENT_THREAD();
+
+#if    defined(_PR_GLOBAL_THREADS_ONLY)
+	/*
+	 * can create global threads only
+	 */
+    if (scope == PR_LOCAL_THREAD)
+    	scope = PR_GLOBAL_THREAD;
+#endif
+
+	if (_native_threads_only)
+		scope = PR_GLOBAL_THREAD;
+
+    native = (((scope == PR_GLOBAL_THREAD)|| (scope == PR_GLOBAL_BOUND_THREAD))
+							&& _PR_IS_NATIVE_THREAD_SUPPORTED());
+
+    _PR_ADJUST_STACKSIZE(stackSize);
+
+    if (native) {
+    /*
+     * clear the IDLE_THREAD flag which applies to LOCAL
+     * threads only
+     */
+    flags &= ~_PR_IDLE_THREAD;
+        flags |= _PR_GLOBAL_SCOPE;
+        if (_PR_NUM_DEADNATIVE > 0) {
+            _PR_DEADQ_LOCK;
+
+            if (_PR_NUM_DEADNATIVE == 0) { /* Thread safe check */
+                _PR_DEADQ_UNLOCK;
+            } else {
+                thread = _PR_THREAD_PTR(_PR_DEADNATIVEQ.next);
+                PR_REMOVE_LINK(&thread->links);
+                _PR_DEC_DEADNATIVE;
+                _PR_DEADQ_UNLOCK;
+
+                _PR_InitializeRecycledThread(thread);
+                thread->startFunc = start;
+                thread->arg = arg;
+            thread->flags = (flags | _PR_GLOBAL_SCOPE);
+            if (type == PR_SYSTEM_THREAD)
+            {
+                thread->flags |= _PR_SYSTEM;
+                PR_ATOMIC_INCREMENT(&_pr_systemActive);
+            }
+            else PR_ATOMIC_INCREMENT(&_pr_userActive);
+
+            if (state == PR_JOINABLE_THREAD) {
+                if (!thread->term) 
+                       thread->term = PR_NewCondVar(_pr_terminationCVLock);
+            }
+        else {
+                if(thread->term) {
+                    PR_DestroyCondVar(thread->term);
+                        thread->term = 0;
+            }
+            }
+
+                thread->priority = priority;
+        _PR_MD_SET_PRIORITY(&(thread->md), priority);
+        /* XXX what about stackSize? */
+        thread->state = _PR_RUNNING;
+                _PR_MD_WAKEUP_WAITER(thread);
+        return thread;
+            }
+        }
+        thread = _PR_NativeCreateThread(type, start, arg, priority, 
+                                            scope, state, stackSize, flags);
+    } else {
+        if (_PR_NUM_DEADUSER > 0) {
+            _PR_DEADQ_LOCK;
+
+            if (_PR_NUM_DEADUSER == 0) {  /* thread safe check */
+                _PR_DEADQ_UNLOCK;
+            } else {
+                PRCList *ptr;
+
+                /* Go down list checking for a recycled thread with a 
+                 * large enough stack.  XXXMB - this has a bad degenerate case.
+                 */
+                ptr = _PR_DEADUSERQ.next;
+                while( ptr != &_PR_DEADUSERQ ) {
+                    thread = _PR_THREAD_PTR(ptr);
+                    if ((thread->stack->stackSize >= stackSize) &&
+                (!thread->no_sched)) {
+                        PR_REMOVE_LINK(&thread->links);
+                        _PR_DEC_DEADUSER;
+                        break;
+                    } else {
+                        ptr = ptr->next;
+                        thread = NULL;
+                    }
+                } 
+
+                _PR_DEADQ_UNLOCK;
+
+               if (thread) {
+                    _PR_InitializeRecycledThread(thread);
+                    thread->startFunc = start;
+                    thread->arg = arg;
+                    thread->priority = priority;
+            if (state == PR_JOINABLE_THREAD) {
+            if (!thread->term) 
+               thread->term = PR_NewCondVar(_pr_terminationCVLock);
+            } else {
+            if(thread->term) {
+               PR_DestroyCondVar(thread->term);
+                thread->term = 0;
+            }
+            }
+                    useRecycled++;
+                }
+            }
+        } 
+        if (thread == NULL) {
+#ifndef HAVE_CUSTOM_USER_THREADS
+            stack = _PR_NewStack(stackSize);
+            if (!stack) {
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                return NULL;
+            }
+
+            /* Allocate thread object and per-thread data off the top of the stack*/
+            top = stack->stackTop;
+#ifdef HAVE_STACK_GROWING_UP
+            thread = (PRThread*) top;
+            top = top + sizeof(PRThread);
+            /*
+             * Make stack 64-byte aligned
+             */
+            if ((PRUptrdiff)top & 0x3f) {
+                top = (char*)(((PRUptrdiff)top + 0x40) & ~0x3f);
+            }
+#else
+            top = top - sizeof(PRThread);
+            thread = (PRThread*) top;
+            /*
+             * Make stack 64-byte aligned
+             */
+            if ((PRUptrdiff)top & 0x3f) {
+                top = (char*)((PRUptrdiff)top & ~0x3f);
+            }
+#endif
+#if defined(GC_LEAK_DETECTOR)
+            /*
+             * sorry, it is not safe to allocate the thread on the stack,
+             * because we assign to this object before the GC can learn
+             * about this thread. we'll just leak thread objects instead.
+             */
+            thread = PR_NEW(PRThread);
+#endif
+            stack->thr = thread;
+            memset(thread, 0, sizeof(PRThread));
+            thread->threadAllocatedOnStack = 1;
+#else
+            thread = _PR_MD_CREATE_USER_THREAD(stackSize, start, arg);
+            if (!thread) {
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                return NULL;
+            }
+            thread->threadAllocatedOnStack = 0;
+            stack = NULL;
+            top = NULL;
+#endif
+
+            /* Initialize thread */
+            thread->tpdLength = 0;
+            thread->privateData = NULL;
+            thread->stack = stack;
+            thread->priority = priority;
+            thread->startFunc = start;
+            thread->arg = arg;
+            PR_INIT_CLIST(&thread->lockList);
+
+            if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
+                if (thread->threadAllocatedOnStack == 1)
+                    _PR_FreeStack(thread->stack);
+                else {
+                    PR_DELETE(thread);
+                }
+                PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+                return NULL;
+            }
+
+            if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) {
+                if (thread->threadAllocatedOnStack == 1)
+                    _PR_FreeStack(thread->stack);
+                else {
+                    PR_DELETE(thread->privateData);
+                    PR_DELETE(thread);
+                }
+                PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+                return NULL;
+            }
+
+            _PR_MD_INIT_CONTEXT(thread, top, _PR_UserRunThread, &status);
+
+            if (status == PR_FALSE) {
+                _PR_MD_FREE_LOCK(&thread->threadLock);
+                if (thread->threadAllocatedOnStack == 1)
+                    _PR_FreeStack(thread->stack);
+                else {
+                    PR_DELETE(thread->privateData);
+                    PR_DELETE(thread);
+                }
+                return NULL;
+            }
+
+            /* 
+              Set thread flags related to scope and joinable state. If joinable
+              thread, allocate a "termination" condition variable.
+            */
+            if (state == PR_JOINABLE_THREAD) {
+                thread->term = PR_NewCondVar(_pr_terminationCVLock);
+                if (thread->term == NULL) {
+                    _PR_MD_FREE_LOCK(&thread->threadLock);
+                    if (thread->threadAllocatedOnStack == 1)
+                        _PR_FreeStack(thread->stack);
+                    else {
+                        PR_DELETE(thread->privateData);
+                        PR_DELETE(thread);
+                    }
+                    return NULL;
+                }
+            }
+  
+        }
+  
+        /* Update thread type counter */
+        PR_Lock(_pr_activeLock);
+        thread->flags = flags;
+        thread->id = ++_pr_utid;
+        if (type == PR_SYSTEM_THREAD) {
+            thread->flags |= _PR_SYSTEM;
+            _pr_systemActive++;
+        } else {
+            _pr_userActive++;
+        }
+
+        /* Make thread runnable */
+        thread->state = _PR_RUNNABLE;
+    /*
+     * Add to list of active threads
+     */
+        PR_Unlock(_pr_activeLock);
+
+        if ((! (thread->flags & _PR_IDLE_THREAD)) && _PR_IS_NATIVE_THREAD(me) )
+            thread->cpu = _PR_GetPrimordialCPU();
+        else
+            thread->cpu = _PR_MD_CURRENT_CPU();
+
+        PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));
+
+        if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me)) {
+            _PR_INTSOFF(is);
+            _PR_RUNQ_LOCK(thread->cpu);
+            _PR_ADD_RUNQ(thread, thread->cpu, priority);
+            _PR_RUNQ_UNLOCK(thread->cpu);
+        }
+
+        if (thread->flags & _PR_IDLE_THREAD) {
+            /*
+            ** If the creating thread is a kernel thread, we need to
+            ** awaken the user thread idle thread somehow; potentially
+            ** it could be sleeping in its idle loop, and we need to poke
+            ** it.  To do so, wake the idle thread...  
+            */
+            _PR_MD_WAKEUP_WAITER(NULL);
+        } else if (_PR_IS_NATIVE_THREAD(me)) {
+            _PR_MD_WAKEUP_WAITER(thread);
+        }
+        if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me) )
+            _PR_INTSON(is);
+    }
+
+    return thread;
+}
+
+PR_IMPLEMENT(PRThread*) PR_CreateThread(PRThreadType type,
+                     void (*start)(void *arg),
+                     void *arg,
+                     PRThreadPriority priority,
+                     PRThreadScope scope,
+                     PRThreadState state,
+                     PRUint32 stackSize)
+{
+    return _PR_CreateThread(type, start, arg, priority, scope, state, 
+                            stackSize, 0);
+}
+
+/*
+** Associate a thread object with an existing native thread.
+**     "type" is the type of thread object to attach
+**     "priority" is the priority to assign to the thread
+**     "stack" defines the shape of the threads stack
+**
+** This can return NULL if some kind of error occurs, or if memory is
+** tight.
+**
+** This call is not normally needed unless you create your own native
+** thread. PR_Init does this automatically for the primordial thread.
+*/
+PRThread* _PRI_AttachThread(PRThreadType type,
+    PRThreadPriority priority, PRThreadStack *stack, PRUint32 flags)
+{
+    PRThread *thread;
+
+    if ((thread = _PR_MD_GET_ATTACHED_THREAD()) != NULL) {
+        return thread;
+    }
+    _PR_MD_SET_CURRENT_THREAD(NULL);
+
+    /* Clear out any state if this thread was attached before */
+    _PR_MD_SET_CURRENT_CPU(NULL);
+
+    thread = _PR_AttachThread(type, priority, stack);
+    if (thread) {
+        PRIntn is;
+
+        _PR_MD_SET_CURRENT_THREAD(thread);
+
+        thread->flags = flags | _PR_GLOBAL_SCOPE | _PR_ATTACHED;
+
+        if (!stack) {
+            thread->stack = PR_NEWZAP(PRThreadStack);
+            if (!thread->stack) {
+                _PR_DestroyThread(thread);
+                return NULL;
+            }
+            thread->stack->stackSize = _MD_DEFAULT_STACK_SIZE;
+        }
+        PR_INIT_CLIST(&thread->links);
+
+        if (_PR_MD_INIT_ATTACHED_THREAD(thread) == PR_FAILURE) {
+                PR_DELETE(thread->stack);
+                _PR_DestroyThread(thread);
+                return NULL;
+        }
+
+        _PR_MD_SET_CURRENT_CPU(NULL);
+
+        if (_PR_MD_CURRENT_CPU()) {
+            _PR_INTSOFF(is);
+            PR_Lock(_pr_activeLock);
+        }
+        if (type == PR_SYSTEM_THREAD) {
+            thread->flags |= _PR_SYSTEM;
+            _pr_systemActive++;
+        } else {
+            _pr_userActive++;
+        }
+        if (_PR_MD_CURRENT_CPU()) {
+            PR_Unlock(_pr_activeLock);
+            _PR_INTSON(is);
+        }
+    }
+    return thread;
+}
+
+PR_IMPLEMENT(PRThread*) PR_AttachThread(PRThreadType type,
+    PRThreadPriority priority, PRThreadStack *stack)
+{
+    return PR_GetCurrentThread();
+}
+
+PR_IMPLEMENT(void) PR_DetachThread(void)
+{
+    /*
+     * On IRIX, Solaris, and Windows, foreign threads are detached when
+     * they terminate.
+     */
+#if !defined(IRIX) && !defined(WIN32) \
+        && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
+    PRThread *me;
+    if (_pr_initialized) {
+        me = _PR_MD_GET_ATTACHED_THREAD();
+        if ((me != NULL) && (me->flags & _PR_ATTACHED))
+            _PRI_DetachThread();
+    }
+#endif
+}
+
+void _PRI_DetachThread(void)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (me->flags & _PR_PRIMORDIAL) {
+		/*
+		 * ignore, if primordial thread
+		 */
+		return;
+	}
+    PR_ASSERT(me->flags & _PR_ATTACHED);
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me));
+    _PR_CleanupThread(me);
+    PR_DELETE(me->privateData);
+
+    _PR_DecrActiveThreadCount(me);
+
+    _PR_MD_CLEAN_THREAD(me);
+    _PR_MD_SET_CURRENT_THREAD(NULL);
+    if (!me->threadAllocatedOnStack) 
+        PR_DELETE(me->stack);
+    _PR_MD_FREE_LOCK(&me->threadLock);
+    PR_DELETE(me);
+}
+
+/*
+** Wait for thread termination:
+**     "thread" is the target thread 
+**
+** This can return PR_FAILURE if no joinable thread could be found 
+** corresponding to the specified target thread.
+**
+** The calling thread is suspended until the target thread completes.
+** Several threads cannot wait for the same thread to complete; one thread
+** will complete successfully and others will terminate with an error PR_FAILURE.
+** The calling thread will not be blocked if the target thread has already
+** terminated.
+*/
+PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thread)
+{
+    PRIntn is;
+    PRCondVar *term;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSOFF(is);
+    term = thread->term;
+    /* can't join a non-joinable thread */
+    if (term == NULL) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        goto ErrorExit;
+    }
+
+    /* multiple threads can't wait on the same joinable thread */
+    if (term->condQ.next != &term->condQ) {
+        goto ErrorExit;
+    }
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSON(is);
+
+    /* wait for the target thread's termination cv invariant */
+    PR_Lock (_pr_terminationCVLock);
+    while (thread->state != _PR_JOIN_WAIT) {
+        (void) PR_WaitCondVar(term, PR_INTERVAL_NO_TIMEOUT);
+    }
+    (void) PR_Unlock (_pr_terminationCVLock);
+    
+    /* 
+     Remove target thread from global waiting to join Q; make it runnable
+     again and put it back on its run Q.  When it gets scheduled later in
+     _PR_RunThread code, it will clean up its stack.
+    */    
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSOFF(is);
+    thread->state = _PR_RUNNABLE;
+    if ( !_PR_IS_NATIVE_THREAD(thread) ) {
+        _PR_THREAD_LOCK(thread);
+
+        _PR_MISCQ_LOCK(thread->cpu);
+        _PR_DEL_JOINQ(thread);
+        _PR_MISCQ_UNLOCK(thread->cpu);
+
+        _PR_AddThreadToRunQ(me, thread);
+        _PR_THREAD_UNLOCK(thread);
+    }
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSON(is);
+
+    _PR_MD_WAKEUP_WAITER(thread);
+
+    return PR_SUCCESS;
+
+ErrorExit:
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+    return PR_FAILURE;   
+}
+
+PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thread,
+    PRThreadPriority newPri)
+{
+
+    /* 
+    First, pin down the priority.  Not all compilers catch passing out of
+    range enum here.  If we let bad values thru, priority queues won't work.
+    */
+    if ((PRIntn)newPri > (PRIntn)PR_PRIORITY_LAST) {
+        newPri = PR_PRIORITY_LAST;
+    } else if ((PRIntn)newPri < (PRIntn)PR_PRIORITY_FIRST) {
+        newPri = PR_PRIORITY_FIRST;
+    }
+        
+    if ( _PR_IS_NATIVE_THREAD(thread) ) {
+        thread->priority = newPri;
+        _PR_MD_SET_PRIORITY(&(thread->md), newPri);
+    } else _PR_SetThreadPriority(thread, newPri);
+}
+
+
+/*
+** This routine prevents all other threads from running. This call is needed by 
+** the garbage collector.
+*/
+PR_IMPLEMENT(void) PR_SuspendAll(void)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRCList *qp;
+
+    /*
+     * Stop all user and native threads which are marked GC able.
+     */
+    PR_Lock(_pr_activeLock);
+    suspendAllOn = PR_TRUE;
+    suspendAllThread = _PR_MD_CURRENT_THREAD();
+    _PR_MD_BEGIN_SUSPEND_ALL();
+    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
+        qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
+        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && 
+            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) {
+            _PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp));
+                PR_ASSERT((_PR_ACTIVE_THREAD_PTR(qp))->state != _PR_RUNNING);
+            }
+    }
+    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
+        qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
+        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) &&
+            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp)))
+            /* PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp)); */
+                _PR_MD_SUSPEND_THREAD(_PR_ACTIVE_THREAD_PTR(qp)); 
+    }
+    _PR_MD_END_SUSPEND_ALL();
+}
+
+/*
+** This routine unblocks all other threads that were suspended from running by 
+** PR_SuspendAll(). This call is needed by the garbage collector.
+*/
+PR_IMPLEMENT(void) PR_ResumeAll(void)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRCList *qp;
+
+    /*
+     * Resume all user and native threads which are marked GC able.
+     */
+    _PR_MD_BEGIN_RESUME_ALL();
+    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
+        qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
+        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && 
+            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp)))
+            _PR_Resume(_PR_ACTIVE_THREAD_PTR(qp));
+    }
+    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
+        qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
+        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) &&
+            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp)))
+                _PR_MD_RESUME_THREAD(_PR_ACTIVE_THREAD_PTR(qp));
+    }
+    _PR_MD_END_RESUME_ALL();
+    suspendAllThread = NULL;
+    suspendAllOn = PR_FALSE;
+    PR_Unlock(_pr_activeLock);
+}
+
+PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg)
+{
+    PRCList *qp, *qp_next;
+    PRIntn i = 0;
+    PRStatus rv = PR_SUCCESS;
+    PRThread* t;
+
+    /*
+    ** Currently Enumerate threads happen only with suspension and
+    ** pr_activeLock held
+    */
+    PR_ASSERT(suspendAllOn);
+
+    /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking
+     * qp->next after applying the function "func".  In particular, "func"
+     * might remove the thread from the queue and put it into another one in
+     * which case qp->next no longer points to the next entry in the original
+     * queue.
+     *
+     * To get around this problem, we save qp->next in qp_next before applying
+     * "func" and use that saved value as the next value after applying "func".
+     */
+
+    /*
+     * Traverse the list of local and global threads
+     */
+    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
+         qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp_next)
+    {
+        qp_next = qp->next;
+        t = _PR_ACTIVE_THREAD_PTR(qp);
+        if (_PR_IS_GCABLE_THREAD(t))
+        {
+            rv = (*func)(t, i, arg);
+            if (rv != PR_SUCCESS)
+                return rv;
+            i++;
+        }
+    }
+    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
+         qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp_next)
+    {
+        qp_next = qp->next;
+        t = _PR_ACTIVE_THREAD_PTR(qp);
+        if (_PR_IS_GCABLE_THREAD(t))
+        {
+            rv = (*func)(t, i, arg);
+            if (rv != PR_SUCCESS)
+                return rv;
+            i++;
+        }
+    }
+    return rv;
+}
+
+/* FUNCTION: _PR_AddSleepQ
+** DESCRIPTION:
+**    Adds a thread to the sleep/pauseQ.
+** RESTRICTIONS:
+**    Caller must have the RUNQ lock.
+**    Caller must be a user level thread
+*/
+PR_IMPLEMENT(void)
+_PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout)
+{
+    _PRCPU *cpu = thread->cpu;
+
+    if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+        /* append the thread to the global pause Q */
+        PR_APPEND_LINK(&thread->links, &_PR_PAUSEQ(thread->cpu));
+        thread->flags |= _PR_ON_PAUSEQ;
+    } else {
+        PRIntervalTime sleep;
+        PRCList *q;
+        PRThread *t;
+
+        /* sort onto global sleepQ */
+        sleep = timeout;
+
+        /* Check if we are longest timeout */
+        if (timeout >= _PR_SLEEPQMAX(cpu)) {
+            PR_INSERT_BEFORE(&thread->links, &_PR_SLEEPQ(cpu));
+            thread->sleep = timeout - _PR_SLEEPQMAX(cpu);
+            _PR_SLEEPQMAX(cpu) = timeout;
+        } else {
+            /* Sort thread into global sleepQ at appropriate point */
+            q = _PR_SLEEPQ(cpu).next;
+
+            /* Now scan the list for where to insert this entry */
+            while (q != &_PR_SLEEPQ(cpu)) {
+                t = _PR_THREAD_PTR(q);
+                if (sleep < t->sleep) {
+                    /* Found sleeper to insert in front of */
+                    break;
+                }
+                sleep -= t->sleep;
+                q = q->next;
+            }
+            thread->sleep = sleep;
+            PR_INSERT_BEFORE(&thread->links, q);
+
+            /*
+            ** Subtract our sleep time from the sleeper that follows us (there
+            ** must be one) so that they remain relative to us.
+            */
+            PR_ASSERT (thread->links.next != &_PR_SLEEPQ(cpu));
+          
+            t = _PR_THREAD_PTR(thread->links.next);
+            PR_ASSERT(_PR_THREAD_PTR(t->links.prev) == thread);
+            t->sleep -= sleep;
+        }
+
+        thread->flags |= _PR_ON_SLEEPQ;
+    }
+}
+
+/* FUNCTION: _PR_DelSleepQ
+** DESCRIPTION:
+**    Removes a thread from the sleep/pauseQ.
+** INPUTS:
+**    If propogate_time is true, then the thread following the deleted
+**    thread will be get the time from the deleted thread.  This is used
+**    when deleting a sleeper that has not timed out.
+** RESTRICTIONS:
+**    Caller must have the RUNQ lock.
+**    Caller must be a user level thread
+*/
+PR_IMPLEMENT(void)
+_PR_DelSleepQ(PRThread *thread, PRBool propogate_time)
+{
+    _PRCPU *cpu = thread->cpu;
+
+    /* Remove from pauseQ/sleepQ */
+    if (thread->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+        if (thread->flags & _PR_ON_SLEEPQ) {
+            PRCList *q = thread->links.next;
+            if (q != &_PR_SLEEPQ(cpu)) {
+                if (propogate_time == PR_TRUE) {
+                    PRThread *after = _PR_THREAD_PTR(q);
+                    after->sleep += thread->sleep;
+                } else 
+                    _PR_SLEEPQMAX(cpu) -= thread->sleep;
+            } else {
+                /* Check if prev is the beggining of the list; if so,
+                 * we are the only element on the list.  
+                 */
+                if (thread->links.prev != &_PR_SLEEPQ(cpu))
+                    _PR_SLEEPQMAX(cpu) -= thread->sleep;
+                else
+                    _PR_SLEEPQMAX(cpu) = 0;
+            }
+            thread->flags &= ~_PR_ON_SLEEPQ;
+        } else {
+            thread->flags &= ~_PR_ON_PAUSEQ;
+        }
+        PR_REMOVE_LINK(&thread->links);
+    } else 
+        PR_ASSERT(0);
+}
+
+void
+_PR_AddThreadToRunQ(
+    PRThread *me,     /* the current thread */
+    PRThread *thread) /* the local thread to be added to a run queue */
+{
+    PRThreadPriority pri = thread->priority;
+    _PRCPU *cpu = thread->cpu;
+
+    PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));
+
+#if defined(WINNT)
+    /*
+     * On NT, we can only reliably know that the current CPU
+     * is not idle.  We add the awakened thread to the run
+     * queue of its CPU if its CPU is the current CPU.
+     * For any other CPU, we don't really know whether it
+     * is busy or idle.  So in all other cases, we just
+     * "post" the awakened thread to the IO completion port
+     * for the next idle CPU to execute (this is done in
+     * _PR_MD_WAKEUP_WAITER).
+	 * Threads with a suspended I/O operation remain bound to
+	 * the same cpu until I/O is cancelled
+     *
+     * NOTE: the boolean expression below must be the exact
+     * opposite of the corresponding boolean expression in
+     * _PR_MD_WAKEUP_WAITER.
+     */
+    if ((!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) ||
+					(thread->md.thr_bound_cpu)) {
+		PR_ASSERT(!thread->md.thr_bound_cpu ||
+							(thread->md.thr_bound_cpu == cpu));
+        _PR_RUNQ_LOCK(cpu);
+        _PR_ADD_RUNQ(thread, cpu, pri);
+        _PR_RUNQ_UNLOCK(cpu);
+    }
+#else
+    _PR_RUNQ_LOCK(cpu);
+    _PR_ADD_RUNQ(thread, cpu, pri);
+    _PR_RUNQ_UNLOCK(cpu);
+    if (!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) {
+        if (pri > me->priority) {
+            _PR_SET_RESCHED_FLAG();
+        }
+    }
+#endif
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prcmon.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prcmon.c
new file mode 100644
index 0000000..67aee4c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prcmon.c
@@ -0,0 +1,463 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <stdlib.h>
+#include <stddef.h>
+
+/* Lock used to lock the monitor cache */
+#ifdef _PR_NO_PREEMPT
+#define _PR_NEW_LOCK_MCACHE()
+#define _PR_DESTROY_LOCK_MCACHE()
+#define _PR_LOCK_MCACHE()
+#define _PR_UNLOCK_MCACHE()
+#else
+#ifdef _PR_LOCAL_THREADS_ONLY
+#define _PR_NEW_LOCK_MCACHE()
+#define _PR_DESTROY_LOCK_MCACHE()
+#define _PR_LOCK_MCACHE() { PRIntn _is; _PR_INTSOFF(_is)
+#define _PR_UNLOCK_MCACHE() _PR_INTSON(_is); }
+#else
+PRLock *_pr_mcacheLock;
+#define _PR_NEW_LOCK_MCACHE() (_pr_mcacheLock = PR_NewLock())
+#define _PR_DESTROY_LOCK_MCACHE()               \
+    PR_BEGIN_MACRO                              \
+        if (_pr_mcacheLock) {                   \
+            PR_DestroyLock(_pr_mcacheLock);     \
+            _pr_mcacheLock = NULL;              \
+        }                                       \
+    PR_END_MACRO
+#define _PR_LOCK_MCACHE() PR_Lock(_pr_mcacheLock)
+#define _PR_UNLOCK_MCACHE() PR_Unlock(_pr_mcacheLock)
+#endif
+#endif
+
+/************************************************************************/
+
+typedef struct MonitorCacheEntryStr MonitorCacheEntry;
+
+struct MonitorCacheEntryStr {
+    MonitorCacheEntry*  next;
+    void*               address;
+    PRMonitor*          mon;
+    long                cacheEntryCount;
+};
+
+/*
+** An array of MonitorCacheEntry's, plus a pointer to link these
+** arrays together.
+*/
+
+typedef struct MonitorCacheEntryBlockStr MonitorCacheEntryBlock;
+
+struct MonitorCacheEntryBlockStr {
+    MonitorCacheEntryBlock* next;
+    MonitorCacheEntry entries[1];
+};
+
+static PRUint32 hash_mask;
+static PRUintn num_hash_buckets;
+static PRUintn num_hash_buckets_log2;
+static MonitorCacheEntry **hash_buckets;
+static MonitorCacheEntry *free_entries;
+static PRUintn num_free_entries;
+static PRBool expanding;
+static MonitorCacheEntryBlock *mcache_blocks;
+
+static void (*OnMonitorRecycle)(void *address);
+
+#define HASH(address)                               \
+    ((PRUint32) ( ((PRUptrdiff)(address) >> 2) ^    \
+                  ((PRUptrdiff)(address) >> 10) )   \
+     & hash_mask)
+
+/*
+** Expand the monitor cache. This grows the hash buckets and allocates a
+** new chunk of cache entries and throws them on the free list. We keep
+** as many hash buckets as there are entries.
+**
+** Because we call malloc and malloc may need the monitor cache, we must
+** ensure that there are several free monitor cache entries available for
+** malloc to get. FREE_THRESHOLD is used to prevent monitor cache
+** starvation during monitor cache expansion.
+*/
+
+#define FREE_THRESHOLD  5
+
+static PRStatus ExpandMonitorCache(PRUintn new_size_log2)
+{
+    MonitorCacheEntry **old_hash_buckets, *p;
+    PRUintn i, entries, old_num_hash_buckets, added;
+    MonitorCacheEntry **new_hash_buckets;
+    MonitorCacheEntryBlock *new_block;
+
+    entries = 1L << new_size_log2;
+
+    /*
+    ** Expand the monitor-cache-entry free list
+    */
+    new_block = (MonitorCacheEntryBlock*)
+        PR_CALLOC(sizeof(MonitorCacheEntryBlock)
+        + (entries - 1) * sizeof(MonitorCacheEntry));
+    if (NULL == new_block) return PR_FAILURE;
+
+    /*
+    ** Allocate system monitors for the new monitor cache entries. If we
+    ** run out of system monitors, break out of the loop.
+    */
+    for (i = 0, p = new_block->entries; i < entries; i++, p++) {
+        p->mon = PR_NewMonitor();
+        if (!p->mon)
+            break;
+    }
+    added = i;
+    if (added != entries) {
+        MonitorCacheEntryBlock *realloc_block;
+
+        if (added == 0) {
+            /* Totally out of system monitors. Lossage abounds */
+            PR_DELETE(new_block);
+            return PR_FAILURE;
+        }
+
+        /*
+        ** We were able to allocate some of the system monitors. Use
+        ** realloc to shrink down the new_block memory. If that fails,
+        ** carry on with the too-large new_block.
+        */
+        realloc_block = (MonitorCacheEntryBlock*)
+            PR_REALLOC(new_block, sizeof(MonitorCacheEntryBlock)
+            + (added - 1) * sizeof(MonitorCacheEntry));
+        if (realloc_block)
+            new_block = realloc_block;
+    }
+
+    /*
+    ** Now that we have allocated all of the system monitors, build up
+    ** the new free list. We can just update the free_list because we own
+    ** the mcache-lock and we aren't calling anyone who might want to use
+    ** it.
+    */
+    for (i = 0, p = new_block->entries; i < added - 1; i++, p++)
+        p->next = p + 1;
+    p->next = free_entries;
+    free_entries = new_block->entries;
+    num_free_entries += added;
+    new_block->next = mcache_blocks;
+    mcache_blocks = new_block;
+
+    /* Try to expand the hash table */
+    new_hash_buckets = (MonitorCacheEntry**)
+        PR_CALLOC(entries * sizeof(MonitorCacheEntry*));
+    if (NULL == new_hash_buckets) {
+        /*
+        ** Partial lossage. In this situation we don't get any more hash
+        ** buckets, which just means that the table lookups will take
+        ** longer. This is bad, but not fatal
+        */
+        PR_LOG(_pr_cmon_lm, PR_LOG_WARNING,
+               ("unable to grow monitor cache hash buckets"));
+        return PR_SUCCESS;
+    }
+
+    /*
+    ** Compute new hash mask value. This value is used to mask an address
+    ** until it's bits are in the right spot for indexing into the hash
+    ** table.
+    */
+    hash_mask = entries - 1;
+
+    /*
+    ** Expand the hash table. We have to rehash everything in the old
+    ** table into the new table.
+    */
+    old_hash_buckets = hash_buckets;
+    old_num_hash_buckets = num_hash_buckets;
+    for (i = 0; i < old_num_hash_buckets; i++) {
+        p = old_hash_buckets[i];
+        while (p) {
+            MonitorCacheEntry *next = p->next;
+
+            /* Hash based on new table size, and then put p in the new table */
+            PRUintn hash = HASH(p->address);
+            p->next = new_hash_buckets[hash];
+            new_hash_buckets[hash] = p;
+
+            p = next;
+        }
+    }
+
+    /*
+    ** Switch over to new hash table and THEN call free of the old
+    ** table. Since free might re-enter _pr_mcache_lock, things would
+    ** break terribly if it used the old hash table.
+    */
+    hash_buckets = new_hash_buckets;
+    num_hash_buckets = entries;
+    num_hash_buckets_log2 = new_size_log2;
+    PR_DELETE(old_hash_buckets);
+
+    PR_LOG(_pr_cmon_lm, PR_LOG_NOTICE,
+           ("expanded monitor cache to %d (buckets %d)",
+            num_free_entries, entries));
+
+    return PR_SUCCESS;
+}  /* ExpandMonitorCache */
+
+/*
+** Lookup a monitor cache entry by address. Return a pointer to the
+** pointer to the monitor cache entry on success, null on failure.
+*/
+static MonitorCacheEntry **LookupMonitorCacheEntry(void *address)
+{
+    PRUintn hash;
+    MonitorCacheEntry **pp, *p;
+
+    hash = HASH(address);
+    pp = hash_buckets + hash;
+    while ((p = *pp) != 0) {
+        if (p->address == address) {
+            if (p->cacheEntryCount > 0)
+                return pp;
+            return NULL;
+        }
+        pp = &p->next;
+    }
+    return NULL;
+}
+
+/*
+** Try to create a new cached monitor. If it's already in the cache,
+** great - return it. Otherwise get a new free cache entry and set it
+** up. If the cache free space is getting low, expand the cache.
+*/
+static PRMonitor *CreateMonitor(void *address)
+{
+    PRUintn hash;
+    MonitorCacheEntry **pp, *p;
+
+    hash = HASH(address);
+    pp = hash_buckets + hash;
+    while ((p = *pp) != 0) {
+        if (p->address == address) goto gotit;
+
+        pp = &p->next;
+    }
+
+    /* Expand the monitor cache if we have run out of free slots in the table */
+    if (num_free_entries < FREE_THRESHOLD) {
+        /* Expand monitor cache */
+
+        /*
+        ** This function is called with the lock held. So what's the 'expanding'
+        ** boolean all about? Seems a bit redundant.
+        */
+        if (!expanding) {
+            PRStatus rv;
+
+            expanding = PR_TRUE;
+            rv = ExpandMonitorCache(num_hash_buckets_log2 + 1);
+            expanding = PR_FALSE;
+            if (PR_FAILURE == rv)  return NULL;
+
+            /* redo the hash because it'll be different now */
+            hash = HASH(address);
+        } else {
+            /*
+            ** We are in process of expanding and we need a cache
+            ** monitor.  Make sure we have enough!
+            */
+            PR_ASSERT(num_free_entries > 0);
+        }
+    }
+
+    /* Make a new monitor */
+    p = free_entries;
+    free_entries = p->next;
+    num_free_entries--;
+    if (OnMonitorRecycle && p->address)
+        OnMonitorRecycle(p->address);
+    p->address = address;
+    p->next = hash_buckets[hash];
+    hash_buckets[hash] = p;
+    PR_ASSERT(p->cacheEntryCount == 0);
+
+  gotit:
+    p->cacheEntryCount++;
+    return p->mon;
+}
+
+/*
+** Initialize the monitor cache
+*/
+void _PR_InitCMon(void)
+{
+    _PR_NEW_LOCK_MCACHE();
+    ExpandMonitorCache(3);
+}
+
+/*
+** Destroy the monitor cache
+*/
+void _PR_CleanupCMon(void)
+{
+    _PR_DESTROY_LOCK_MCACHE();
+
+    while (free_entries) {
+        PR_DestroyMonitor(free_entries->mon);
+        free_entries = free_entries->next;
+    }
+    num_free_entries = 0;
+
+    while (mcache_blocks) {
+        MonitorCacheEntryBlock *block;
+
+        block = mcache_blocks;
+        mcache_blocks = block->next;
+        PR_DELETE(block);
+    }
+
+    PR_DELETE(hash_buckets);
+    hash_mask = 0;
+    num_hash_buckets = 0;
+    num_hash_buckets_log2 = 0;
+
+    expanding = PR_FALSE;
+    OnMonitorRecycle = NULL;
+}
+
+/*
+** Create monitor for address. Don't enter the monitor while we have the
+** mcache locked because we might block!
+*/
+PR_IMPLEMENT(PRMonitor*) PR_CEnterMonitor(void *address)
+{
+    PRMonitor *mon;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    _PR_LOCK_MCACHE();
+    mon = CreateMonitor(address);
+    _PR_UNLOCK_MCACHE();
+
+    if (!mon) return NULL;
+
+    PR_EnterMonitor(mon);
+    return mon;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CExitMonitor(void *address)
+{
+    MonitorCacheEntry **pp, *p;
+    PRStatus status = PR_SUCCESS;
+
+    _PR_LOCK_MCACHE();
+    pp = LookupMonitorCacheEntry(address);
+    if (pp != NULL) {
+        p = *pp;
+        if (--p->cacheEntryCount == 0) {
+            /*
+            ** Nobody is using the system monitor. Put it on the cached free
+            ** list. We are safe from somebody trying to use it because we
+            ** have the mcache locked.
+            */
+            p->address = 0;             /* defensive move */
+            *pp = p->next;              /* unlink from hash_buckets */
+            p->next = free_entries;     /* link into free list */
+            free_entries = p;
+            num_free_entries++;         /* count it as free */
+        }
+        status = PR_ExitMonitor(p->mon);
+    } else {
+        status = PR_FAILURE;
+    }
+    _PR_UNLOCK_MCACHE();
+
+    return status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CWait(void *address, PRIntervalTime ticks)
+{
+    MonitorCacheEntry **pp;
+    PRMonitor *mon;
+
+    _PR_LOCK_MCACHE();
+    pp = LookupMonitorCacheEntry(address);
+    mon = pp ? ((*pp)->mon) : NULL;
+    _PR_UNLOCK_MCACHE();
+
+    if (mon == NULL)
+        return PR_FAILURE;
+    return PR_Wait(mon, ticks);
+}
+
+PR_IMPLEMENT(PRStatus) PR_CNotify(void *address)
+{
+    MonitorCacheEntry **pp;
+    PRMonitor *mon;
+
+    _PR_LOCK_MCACHE();
+    pp = LookupMonitorCacheEntry(address);
+    mon = pp ? ((*pp)->mon) : NULL;
+    _PR_UNLOCK_MCACHE();
+
+    if (mon == NULL)
+        return PR_FAILURE;
+    return PR_Notify(mon);
+}
+
+PR_IMPLEMENT(PRStatus) PR_CNotifyAll(void *address)
+{
+    MonitorCacheEntry **pp;
+    PRMonitor *mon;
+
+    _PR_LOCK_MCACHE();
+    pp = LookupMonitorCacheEntry(address);
+    mon = pp ? ((*pp)->mon) : NULL;
+    _PR_UNLOCK_MCACHE();
+
+    if (mon == NULL)
+        return PR_FAILURE;
+    return PR_NotifyAll(mon);
+}
+
+PR_IMPLEMENT(void)
+PR_CSetOnMonitorRecycle(void (*callback)(void *address))
+{
+    OnMonitorRecycle = callback;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prcthr.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prcthr.c
new file mode 100644
index 0000000..7c3e627
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prcthr.c
@@ -0,0 +1,426 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+
+extern PRLock *_pr_sleeplock;  /* allocated and initialized in prinit */
+/* 
+** Routines common to both native and user threads.
+**
+**
+** Clean up a thread object, releasing all of the attached data. Do not
+** free the object itself (it may not have been malloc'd)
+*/
+void _PR_CleanupThread(PRThread *thread)
+{
+    /* Free up per-thread-data */
+    _PR_DestroyThreadPrivate(thread);
+
+    /* Free any thread dump procs */
+    if (thread->dumpArg) {
+        PR_DELETE(thread->dumpArg);
+    }
+    thread->dump = 0;
+
+    PR_DELETE(thread->errorString);
+    thread->errorStringSize = 0;
+    thread->errorStringLength = 0;
+    thread->environment = NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_Yield()
+{
+    static PRBool warning = PR_TRUE;
+    if (warning) warning = _PR_Obsolete(
+        "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)");
+    return (PR_Sleep(PR_INTERVAL_NO_WAIT));
+}
+
+/*
+** Make the current thread sleep until "timeout" ticks amount of time
+** has expired. If "timeout" is PR_INTERVAL_NO_WAIT then the call is
+** equivalent to a yield. Waiting for an infinite amount of time is
+** allowed in the expectation that another thread will interrupt().
+**
+** A single lock is used for all threads calling sleep. Each caller
+** does get its own condition variable since each is expected to have
+** a unique 'timeout'.
+*/
+PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime timeout)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (PR_INTERVAL_NO_WAIT == timeout)
+    {
+        /*
+        ** This is a simple yield, nothing more, nothing less.
+        */
+        PRIntn is;
+        PRThread *me = PR_GetCurrentThread();
+        PRUintn pri = me->priority;
+        _PRCPU *cpu = _PR_MD_CURRENT_CPU();
+
+        if ( _PR_IS_NATIVE_THREAD(me) ) _PR_MD_YIELD();
+        else
+        {
+            _PR_INTSOFF(is);
+            _PR_RUNQ_LOCK(cpu);
+            if (_PR_RUNQREADYMASK(cpu) >> pri) {
+                me->cpu = cpu;
+                me->state = _PR_RUNNABLE;
+                _PR_ADD_RUNQ(me, cpu, pri);
+                _PR_RUNQ_UNLOCK(cpu);
+
+                PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: yielding"));
+                _PR_MD_SWITCH_CONTEXT(me);
+                PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: done"));
+
+                _PR_FAST_INTSON(is);
+            }
+            else
+            {
+                _PR_RUNQ_UNLOCK(cpu);
+                _PR_INTSON(is);
+            }
+        }
+    }
+    else
+    {
+        /*
+        ** This is waiting for some finite period of time.
+        ** A thread in this state is interruptible (PR_Interrupt()),
+        ** but the lock and cvar used are local to the implementation
+        ** and not visible to the caller, therefore not notifiable.
+        */
+        PRCondVar *cv;
+        PRIntervalTime timein;
+
+        timein = PR_IntervalNow();
+        cv = PR_NewCondVar(_pr_sleeplock);
+        PR_ASSERT(cv != NULL);
+        PR_Lock(_pr_sleeplock);
+        do
+        {
+            PRIntervalTime delta = PR_IntervalNow() - timein;
+            if (delta > timeout) break;
+            rv = PR_WaitCondVar(cv, timeout - delta);
+        } while (rv == PR_SUCCESS);
+        PR_Unlock(_pr_sleeplock);
+        PR_DestroyCondVar(cv);
+    }
+    return rv;
+}
+
+PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thread)
+{
+    return thread->id;
+}
+
+PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread)
+{
+    return (PRThreadPriority) thread->priority;
+}
+
+PR_IMPLEMENT(PRThread *) PR_GetCurrentThread()
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return _PR_MD_CURRENT_THREAD();
+}
+
+/*
+** Set the interrupt flag for a thread. The thread will be unable to
+** block in i/o functions when this happens. Also, any PR_Wait's in
+** progress will be undone. The interrupt remains in force until
+** PR_ClearInterrupt is called.
+*/
+PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thread)
+{
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    PRCondVar *victim;
+
+    _PR_THREAD_LOCK(thread);
+    thread->flags |= _PR_INTERRUPT;
+    victim = thread->wait.cvar;
+    _PR_THREAD_UNLOCK(thread);
+    if ((NULL != victim) && (!(thread->flags & _PR_INTERRUPT_BLOCKED))) {
+        int haveLock = (victim->lock->owner == _PR_MD_CURRENT_THREAD());
+
+        if (!haveLock) PR_Lock(victim->lock);
+        PR_NotifyAllCondVar(victim);
+        if (!haveLock) PR_Unlock(victim->lock);
+    }
+    return PR_SUCCESS;
+#else  /* ! _PR_GLOBAL_THREADS_ONLY */
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+            if (!_PR_IS_NATIVE_THREAD(me))
+            	_PR_INTSOFF(is);
+
+            _PR_THREAD_LOCK(thread);
+            thread->flags |= _PR_INTERRUPT;
+        switch (thread->state) {
+                case _PR_COND_WAIT:
+                        /*
+                         * call is made with thread locked;
+                         * on return lock is released
+                         */
+						if (!(thread->flags & _PR_INTERRUPT_BLOCKED))
+                        	_PR_NotifyLockedThread(thread);
+                        break;
+                case _PR_IO_WAIT:
+                        /*
+                         * Need to hold the thread lock when calling
+                         * _PR_Unblock_IO_Wait().  On return lock is
+                         * released. 
+                         */
+#if defined(XP_UNIX) || defined(WINNT) || defined(WIN16)
+						if (!(thread->flags & _PR_INTERRUPT_BLOCKED))
+                        	_PR_Unblock_IO_Wait(thread);
+#else
+                        _PR_THREAD_UNLOCK(thread);
+#endif
+                        break;
+                case _PR_RUNNING:
+                case _PR_RUNNABLE:
+                case _PR_LOCK_WAIT:
+                default:
+                            _PR_THREAD_UNLOCK(thread);
+                        break;
+        }
+            if (!_PR_IS_NATIVE_THREAD(me))
+            	_PR_INTSON(is);
+            return PR_SUCCESS;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/*
+** Clear the interrupt flag for self.
+*/
+PR_IMPLEMENT(void) PR_ClearInterrupt()
+{
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+        if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(me);
+         me->flags &= ~_PR_INTERRUPT;
+    _PR_THREAD_UNLOCK(me);
+        if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+}
+
+PR_IMPLEMENT(void) PR_BlockInterrupt()
+{
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(me);
+    _PR_THREAD_BLOCK_INTERRUPT(me);
+    _PR_THREAD_UNLOCK(me);
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+}  /* PR_BlockInterrupt */
+
+PR_IMPLEMENT(void) PR_UnblockInterrupt()
+{
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(me);
+    _PR_THREAD_UNBLOCK_INTERRUPT(me);
+    _PR_THREAD_UNLOCK(me);
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+}  /* PR_UnblockInterrupt */
+
+/*
+** Return the thread stack pointer of the given thread.
+*/
+PR_IMPLEMENT(void *) PR_GetSP(PRThread *thread)
+{
+        return (void *)_PR_MD_GET_SP(thread);
+}
+
+PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thread)
+{
+        return thread->environment;
+}
+
+PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thread, void *env)
+{
+        thread->environment = env;
+}
+
+
+PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask)
+{
+#ifdef HAVE_THREAD_AFFINITY
+    return _PR_MD_GETTHREADAFFINITYMASK(thread, mask);
+#else
+    return 0;
+#endif
+}
+
+PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask )
+{
+#ifdef HAVE_THREAD_AFFINITY
+#ifndef IRIX
+    return _PR_MD_SETTHREADAFFINITYMASK(thread, mask);
+#else
+	return 0;
+#endif
+#else
+    return 0;
+#endif
+}
+
+/* This call is thread unsafe if another thread is calling SetConcurrency()
+ */
+PR_IMPLEMENT(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask)
+{
+#ifdef HAVE_THREAD_AFFINITY
+    PRCList *qp;
+    extern PRUint32 _pr_cpu_affinity_mask;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    _pr_cpu_affinity_mask = mask;
+
+    qp = _PR_CPUQ().next;
+    while(qp != &_PR_CPUQ()) {
+        _PRCPU *cpu;
+
+        cpu = _PR_CPU_PTR(qp);
+        PR_SetThreadAffinityMask(cpu->thread, mask);
+
+        qp = qp->next;
+    }
+#endif
+
+    return 0;
+}
+
+PRUint32 _pr_recycleThreads = 0;
+PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 count)
+{
+    _pr_recycleThreads = count;
+}
+
+PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble(PRThreadType type,
+                                     void (*start)(void *arg),
+                                     void *arg,
+                                     PRThreadPriority priority,
+                                     PRThreadScope scope,
+                                     PRThreadState state,
+                                     PRUint32 stackSize)
+{
+    return _PR_CreateThread(type, start, arg, priority, scope, state, 
+                            stackSize, _PR_GCABLE_THREAD);
+}
+
+#ifdef SOLARIS
+PR_IMPLEMENT(PRThread*) PR_CreateThreadBound(PRThreadType type,
+                                     void (*start)(void *arg),
+                                     void *arg,
+                                     PRUintn priority,
+                                     PRThreadScope scope,
+                                     PRThreadState state,
+                                     PRUint32 stackSize)
+{
+    return _PR_CreateThread(type, start, arg, priority, scope, state, 
+                            stackSize, _PR_BOUND_THREAD);
+}
+#endif
+
+
+PR_IMPLEMENT(PRThread*) PR_AttachThreadGCAble(
+    PRThreadType type, PRThreadPriority priority, PRThreadStack *stack)
+{
+    /* $$$$ not sure how to finese this one */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(void) PR_SetThreadGCAble()
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    PR_Lock(_pr_activeLock);
+        _PR_MD_CURRENT_THREAD()->flags |= _PR_GCABLE_THREAD;
+        PR_Unlock(_pr_activeLock);        
+}
+
+PR_IMPLEMENT(void) PR_ClearThreadGCAble()
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    PR_Lock(_pr_activeLock);
+        _PR_MD_CURRENT_THREAD()->flags &= (~_PR_GCABLE_THREAD);
+        PR_Unlock(_pr_activeLock);
+}
+
+PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thread)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+    	return (thread->flags & _PR_BOUND_THREAD) ? PR_GLOBAL_BOUND_THREAD :
+										PR_GLOBAL_THREAD;
+    } else
+        return PR_LOCAL_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thread)
+{
+    return (thread->flags & _PR_SYSTEM) ? PR_SYSTEM_THREAD : PR_USER_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thread)
+{
+    return (NULL == thread->term) ? PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD;
+}  /* PR_GetThreadState */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prdump.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prdump.c
new file mode 100644
index 0000000..3ea884d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prdump.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+/* XXX use unbuffered nspr stdio */
+
+PRFileDesc *_pr_dumpOut;
+
+PRUint32 _PR_DumpPrintf(PRFileDesc *fd, const char *fmt, ...)
+{
+    char buf[100];
+    PRUint32 nb;
+    va_list ap;
+
+    va_start(ap, fmt);
+    nb = PR_vsnprintf(buf, sizeof(buf), fmt, ap);
+    va_end(ap);
+    PR_Write(fd, buf, nb);
+
+    return nb;
+}
+
+void _PR_DumpThread(PRFileDesc *fd, PRThread *thread)
+{
+
+#ifndef _PR_GLOBAL_THREADS_ONLY
+    _PR_DumpPrintf(fd, "%05d[%08p] pri=%2d flags=0x%02x",
+                   thread->id, thread, thread->priority, thread->flags);
+    switch (thread->state) {
+      case _PR_RUNNABLE:
+      case _PR_RUNNING:
+        break;
+      case _PR_LOCK_WAIT:
+        _PR_DumpPrintf(fd, " lock=%p", thread->wait.lock);
+        break;
+      case _PR_COND_WAIT:
+        _PR_DumpPrintf(fd, " condvar=%p sleep=%lldms",
+                       thread->wait.cvar, thread->sleep);
+        break;
+      case _PR_SUSPENDED:
+        _PR_DumpPrintf(fd, " suspended");
+        break;
+    }
+    PR_Write(fd, "\n", 1);
+#endif
+
+    /* Now call dump routine */
+    if (thread->dump) {
+	thread->dump(fd, thread, thread->dumpArg);
+    }
+}
+
+static void DumpThreadQueue(PRFileDesc *fd, PRCList *list)
+{
+#ifndef _PR_GLOBAL_THREADS_ONLY
+    PRCList *q;
+
+    q = list->next;
+    while (q != list) {
+        PRThread *t = _PR_THREAD_PTR(q);
+        _PR_DumpThread(fd, t);
+        q = q->next;
+    }
+#endif
+}
+
+void _PR_DumpThreads(PRFileDesc *fd)
+{
+    PRThread *t;
+    PRIntn i;
+
+    _PR_DumpPrintf(fd, "Current Thread:\n");
+    t = _PR_MD_CURRENT_THREAD();
+    _PR_DumpThread(fd, t);
+
+    _PR_DumpPrintf(fd, "Runnable Threads:\n");
+    for (i = 0; i < 32; i++) {
+        DumpThreadQueue(fd, &_PR_RUNQ(t->cpu)[i]);
+    }
+
+    _PR_DumpPrintf(fd, "CondVar timed wait Threads:\n");
+    DumpThreadQueue(fd, &_PR_SLEEPQ(t->cpu));
+
+    _PR_DumpPrintf(fd, "CondVar wait Threads:\n");
+    DumpThreadQueue(fd, &_PR_PAUSEQ(t->cpu));
+
+    _PR_DumpPrintf(fd, "Suspended Threads:\n");
+    DumpThreadQueue(fd, &_PR_SUSPENDQ(t->cpu));
+}
+
+PR_IMPLEMENT(void) PR_ShowStatus(void)
+{
+    PRIntn is;
+
+    if ( _PR_MD_CURRENT_THREAD()
+    && !_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) _PR_INTSOFF(is);
+    _pr_dumpOut = _pr_stderr;
+    _PR_DumpThreads(_pr_dumpOut);
+    if ( _PR_MD_CURRENT_THREAD()
+    && !_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) _PR_FAST_INTSON(is);
+}
+
+PR_IMPLEMENT(void)
+PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg)
+{
+    thread->dump = dump;
+    thread->dumpArg = arg;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prmon.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prmon.c
new file mode 100644
index 0000000..dc8a32c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prmon.c
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+/************************************************************************/
+
+/*
+** Create a new monitor.
+*/
+PR_IMPLEMENT(PRMonitor*) PR_NewMonitor()
+{
+    PRMonitor *mon;
+	PRCondVar *cvar;
+	PRLock *lock;
+
+    mon = PR_NEWZAP(PRMonitor);
+    if (mon) {
+		lock = PR_NewLock();
+	    if (!lock) {
+			PR_DELETE(mon);
+			return 0;
+    	}
+
+	    cvar = PR_NewCondVar(lock);
+	    if (!cvar) {
+	    	PR_DestroyLock(lock);
+			PR_DELETE(mon);
+			return 0;
+    	}
+    	mon->cvar = cvar;
+	mon->name = NULL;
+    }
+    return mon;
+}
+
+PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name)
+{
+    PRMonitor* mon = PR_NewMonitor();
+    if (mon)
+        mon->name = name;
+    return mon;
+}
+
+/*
+** Destroy a monitor. There must be no thread waiting on the monitor's
+** condition variable. The caller is responsible for guaranteeing that the
+** monitor is no longer in use.
+*/
+PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon)
+{
+	PR_DestroyLock(mon->cvar->lock);
+    PR_DestroyCondVar(mon->cvar);
+    PR_DELETE(mon);
+}
+
+/*
+** Enter the lock associated with the monitor.
+*/
+PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon)
+{
+    if (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) {
+		mon->entryCount++;
+    } else {
+		PR_Lock(mon->cvar->lock);
+		mon->entryCount = 1;
+    }
+}
+
+/*
+** Test and then enter the lock associated with the monitor if it's not
+** already entered by some other thread. Return PR_FALSE if some other
+** thread owned the lock at the time of the call.
+*/
+PR_IMPLEMENT(PRBool) PR_TestAndEnterMonitor(PRMonitor *mon)
+{
+    if (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) {
+		mon->entryCount++;
+		return PR_TRUE;
+    } else {
+		if (PR_TestAndLock(mon->cvar->lock)) {
+	    	mon->entryCount = 1;
+	   	 	return PR_TRUE;
+		}
+    }
+    return PR_FALSE;
+}
+
+/*
+** Exit the lock associated with the monitor once.
+*/
+PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon)
+{
+    if (mon->cvar->lock->owner != _PR_MD_CURRENT_THREAD()) {
+        return PR_FAILURE;
+    }
+    if (--mon->entryCount == 0) {
+		return PR_Unlock(mon->cvar->lock);
+    }
+    return PR_SUCCESS;
+}
+
+/*
+** Return the number of times that the current thread has entered the
+** lock. Returns zero if the current thread has not entered the lock.
+*/
+PR_IMPLEMENT(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon)
+{
+    return (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) ?
+        mon->entryCount : 0;
+}
+
+/*
+** If the current thread is in |mon|, this assertion is guaranteed to
+** succeed.  Otherwise, the behavior of this function is undefined.
+*/
+PR_IMPLEMENT(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon)
+{
+    PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mon->cvar->lock);
+}
+
+/*
+** Wait for a notify on the condition variable. Sleep for "ticks" amount
+** of time (if "tick" is 0 then the sleep is indefinite). While
+** the thread is waiting it exits the monitors lock (as if it called
+** PR_ExitMonitor as many times as it had called PR_EnterMonitor).  When
+** the wait has finished the thread regains control of the monitors lock
+** with the same entry count as before the wait began.
+**
+** The thread waiting on the monitor will be resumed when the monitor is
+** notified (assuming the thread is the next in line to receive the
+** notify) or when the "ticks" elapses.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+** This routine can return PR_PENDING_INTERRUPT if the waiting thread 
+** has been interrupted.
+*/
+PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks)
+{
+    PRUintn entryCount;
+	PRStatus status;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (mon->cvar->lock->owner != me) return PR_FAILURE;
+
+    entryCount = mon->entryCount;
+    mon->entryCount = 0;
+
+	status = _PR_WaitCondVar(me, mon->cvar, mon->cvar->lock, ticks);
+
+    mon->entryCount = entryCount;
+
+    return status;
+}
+
+/*
+** Notify the highest priority thread waiting on the condition
+** variable. If a thread is waiting on the condition variable (using
+** PR_Wait) then it is awakened and begins waiting on the monitor's lock.
+*/
+PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    if (mon->cvar->lock->owner != me) return PR_FAILURE;
+    PR_NotifyCondVar(mon->cvar);
+    return PR_SUCCESS;
+}
+
+/*
+** Notify all of the threads waiting on the condition variable. All of
+** threads are notified in turn. The highest priority thread will
+** probably acquire the monitor first when the monitor is exited.
+*/
+PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    if (mon->cvar->lock->owner != me) return PR_FAILURE;
+    PR_NotifyAllCondVar(mon->cvar);
+    return PR_SUCCESS;
+}
+
+/************************************************************************/
+
+PRUint32 _PR_MonitorToString(PRMonitor *mon, char *buf, PRUint32 buflen)
+{
+    PRUint32 nb;
+
+    if (mon->cvar->lock->owner) {
+	nb = PR_snprintf(buf, buflen, "[%p] owner=%d[%p] count=%ld",
+			 mon, mon->cvar->lock->owner->id,
+			 mon->cvar->lock->owner, mon->entryCount);
+    } else {
+	nb = PR_snprintf(buf, buflen, "[%p]", mon);
+    }
+    return nb;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prrwlock.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prrwlock.c
new file mode 100644
index 0000000..35e0e3e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prrwlock.c
@@ -0,0 +1,512 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+
+#if defined(HPUX) && defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+
+#include <pthread.h>
+#define HAVE_UNIX98_RWLOCK
+#define RWLOCK_T pthread_rwlock_t
+#define RWLOCK_INIT(lock) pthread_rwlock_init(lock, NULL)
+#define RWLOCK_DESTROY(lock) pthread_rwlock_destroy(lock)
+#define RWLOCK_RDLOCK(lock) pthread_rwlock_rdlock(lock)
+#define RWLOCK_WRLOCK(lock) pthread_rwlock_wrlock(lock)
+#define RWLOCK_UNLOCK(lock) pthread_rwlock_unlock(lock)
+
+#elif defined(SOLARIS) && (defined(_PR_PTHREADS) \
+        || defined(_PR_GLOBAL_THREADS_ONLY))
+
+#include <synch.h>
+#define HAVE_UI_RWLOCK
+#define RWLOCK_T rwlock_t
+#define RWLOCK_INIT(lock) rwlock_init(lock, USYNC_THREAD, NULL)
+#define RWLOCK_DESTROY(lock) rwlock_destroy(lock)
+#define RWLOCK_RDLOCK(lock) rw_rdlock(lock)
+#define RWLOCK_WRLOCK(lock) rw_wrlock(lock)
+#define RWLOCK_UNLOCK(lock) rw_unlock(lock)
+
+#endif
+
+/*
+ * Reader-writer lock
+ */
+struct PRRWLock {
+	char			*rw_name;			/* lock name					*/
+	PRUint32		rw_rank;			/* rank of the lock				*/
+
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	RWLOCK_T		rw_lock;
+#else
+    PRLock			*rw_lock;
+	PRInt32			rw_lock_cnt;		/* ==  0, if unlocked			*/
+										/* == -1, if write-locked		*/
+										/* > 0	, # of read locks		*/
+	PRUint32		rw_reader_cnt;		/* number of waiting readers	*/
+	PRUint32		rw_writer_cnt;		/* number of waiting writers	*/
+	PRCondVar   	*rw_reader_waitq;	/* cvar for readers 			*/
+	PRCondVar   	*rw_writer_waitq;	/* cvar for writers				*/
+#ifdef DEBUG
+    PRThread 		*rw_owner;			/* lock owner for write-lock	*/
+#endif
+#endif
+};
+
+#ifdef DEBUG
+#define _PR_RWLOCK_RANK_ORDER_DEBUG	/* enable deadlock detection using
+									   rank-order for locks
+									*/
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+
+static PRUintn	pr_thread_rwlock_key;			/* TPD key for lock stack */
+static PRUintn	pr_thread_rwlock_alloc_failed;
+
+#define	_PR_RWLOCK_RANK_ORDER_LIMIT	10
+
+typedef struct thread_rwlock_stack {
+	PRInt32		trs_index;									/* top of stack */
+	PRRWLock	*trs_stack[_PR_RWLOCK_RANK_ORDER_LIMIT];	/* stack of lock
+														 	   pointers */
+
+} thread_rwlock_stack;
+
+static void _PR_SET_THREAD_RWLOCK_RANK(PRRWLock *rwlock);
+static PRUint32 _PR_GET_THREAD_RWLOCK_RANK(void);
+static void _PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock);
+static void _PR_RELEASE_LOCK_STACK(void *lock_stack);
+
+#endif
+
+/*
+ * Reader/Writer Locks
+ */
+
+/*
+ * PR_NewRWLock
+ *		Create a reader-writer lock, with the given lock rank and lock name
+ *	
+ */
+
+PR_IMPLEMENT(PRRWLock *)
+PR_NewRWLock(PRUint32 lock_rank, const char *lock_name)
+{
+    PRRWLock *rwlock;
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	int err;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    rwlock = PR_NEWZAP(PRRWLock);
+    if (rwlock == NULL)
+		return NULL;
+
+	rwlock->rw_rank = lock_rank;
+	if (lock_name != NULL) {
+		rwlock->rw_name = (char*) PR_Malloc(strlen(lock_name) + 1);
+    	if (rwlock->rw_name == NULL) {
+			PR_DELETE(rwlock);
+			return(NULL);
+		}
+		strcpy(rwlock->rw_name, lock_name);
+	} else {
+		rwlock->rw_name = NULL;
+	}
+	
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	err = RWLOCK_INIT(&rwlock->rw_lock);
+	if (err != 0) {
+		PR_SetError(PR_UNKNOWN_ERROR, err);
+		PR_Free(rwlock->rw_name);
+		PR_DELETE(rwlock);
+		return NULL;
+	}
+	return rwlock;
+#else
+	rwlock->rw_lock = PR_NewLock();
+    if (rwlock->rw_lock == NULL) {
+		goto failed;
+	}
+	rwlock->rw_reader_waitq = PR_NewCondVar(rwlock->rw_lock);
+    if (rwlock->rw_reader_waitq == NULL) {
+		goto failed;
+	}
+	rwlock->rw_writer_waitq = PR_NewCondVar(rwlock->rw_lock);
+    if (rwlock->rw_writer_waitq == NULL) {
+		goto failed;
+	}
+	rwlock->rw_reader_cnt = 0;
+	rwlock->rw_writer_cnt = 0;
+	rwlock->rw_lock_cnt = 0;
+	return rwlock;
+
+failed:
+	if (rwlock->rw_reader_waitq != NULL) {
+		PR_DestroyCondVar(rwlock->rw_reader_waitq);	
+	}
+	if (rwlock->rw_lock != NULL) {
+		PR_DestroyLock(rwlock->rw_lock);
+	}
+	PR_Free(rwlock->rw_name);
+	PR_DELETE(rwlock);
+	return NULL;
+#endif
+}
+
+/*
+** Destroy the given RWLock "lock".
+*/
+PR_IMPLEMENT(void)
+PR_DestroyRWLock(PRRWLock *rwlock)
+{
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	int err;
+	err = RWLOCK_DESTROY(&rwlock->rw_lock);
+	PR_ASSERT(err == 0);
+#else
+	PR_ASSERT(rwlock->rw_reader_cnt == 0);
+	PR_DestroyCondVar(rwlock->rw_reader_waitq);	
+	PR_DestroyCondVar(rwlock->rw_writer_waitq);	
+	PR_DestroyLock(rwlock->rw_lock);
+#endif
+	if (rwlock->rw_name != NULL)
+		PR_Free(rwlock->rw_name);
+    PR_DELETE(rwlock);
+}
+
+/*
+** Read-lock the RWLock.
+*/
+PR_IMPLEMENT(void)
+PR_RWLock_Rlock(PRRWLock *rwlock)
+{
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+int err;
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * assert that rank ordering is not violated; the rank of 'rwlock' should
+	 * be equal to or greater than the highest rank of all the locks held by
+	 * the thread.
+	 */
+	PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || 
+					(rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK()));
+#endif
+
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	err = RWLOCK_RDLOCK(&rwlock->rw_lock);
+	PR_ASSERT(err == 0);
+#else
+	PR_Lock(rwlock->rw_lock);
+	/*
+	 * wait if write-locked or if a writer is waiting; preference for writers
+	 */
+	while ((rwlock->rw_lock_cnt < 0) ||
+			(rwlock->rw_writer_cnt > 0)) {
+		rwlock->rw_reader_cnt++;
+		PR_WaitCondVar(rwlock->rw_reader_waitq, PR_INTERVAL_NO_TIMEOUT);
+		rwlock->rw_reader_cnt--;
+	}
+	/*
+	 * Increment read-lock count
+	 */
+	rwlock->rw_lock_cnt++;
+
+	PR_Unlock(rwlock->rw_lock);
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * update thread's lock rank
+	 */
+	_PR_SET_THREAD_RWLOCK_RANK(rwlock);
+#endif
+}
+
+/*
+** Write-lock the RWLock.
+*/
+PR_IMPLEMENT(void)
+PR_RWLock_Wlock(PRRWLock *rwlock)
+{
+#if defined(DEBUG)
+PRThread *me = PR_GetCurrentThread();
+#endif
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+int err;
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * assert that rank ordering is not violated; the rank of 'rwlock' should
+	 * be equal to or greater than the highest rank of all the locks held by
+	 * the thread.
+	 */
+	PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || 
+					(rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK()));
+#endif
+
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	err = RWLOCK_WRLOCK(&rwlock->rw_lock);
+	PR_ASSERT(err == 0);
+#else
+	PR_Lock(rwlock->rw_lock);
+	/*
+	 * wait if read locked
+	 */
+	while (rwlock->rw_lock_cnt != 0) {
+		rwlock->rw_writer_cnt++;
+		PR_WaitCondVar(rwlock->rw_writer_waitq, PR_INTERVAL_NO_TIMEOUT);
+		rwlock->rw_writer_cnt--;
+	}
+	/*
+	 * apply write lock
+	 */
+	rwlock->rw_lock_cnt--;
+	PR_ASSERT(rwlock->rw_lock_cnt == -1);
+#ifdef DEBUG
+	PR_ASSERT(me != NULL);
+	rwlock->rw_owner = me;
+#endif
+	PR_Unlock(rwlock->rw_lock);
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * update thread's lock rank
+	 */
+	_PR_SET_THREAD_RWLOCK_RANK(rwlock);
+#endif
+}
+
+/*
+** Unlock the RW lock.
+*/
+PR_IMPLEMENT(void)
+PR_RWLock_Unlock(PRRWLock *rwlock)
+{
+#if defined(DEBUG)
+PRThread *me = PR_GetCurrentThread();
+#endif
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+int err;
+#endif
+
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	err = RWLOCK_UNLOCK(&rwlock->rw_lock);
+	PR_ASSERT(err == 0);
+#else
+	PR_Lock(rwlock->rw_lock);
+	/*
+	 * lock must be read or write-locked
+	 */
+	PR_ASSERT(rwlock->rw_lock_cnt != 0);
+	if (rwlock->rw_lock_cnt > 0) {
+
+		/*
+		 * decrement read-lock count
+		 */
+		rwlock->rw_lock_cnt--;
+		if (rwlock->rw_lock_cnt == 0) {
+			/*
+			 * lock is not read-locked anymore; wakeup a waiting writer
+			 */
+			if (rwlock->rw_writer_cnt > 0)
+				PR_NotifyCondVar(rwlock->rw_writer_waitq);
+		}
+	} else {
+		PR_ASSERT(rwlock->rw_lock_cnt == -1);
+
+		rwlock->rw_lock_cnt = 0;
+#ifdef DEBUG
+    	PR_ASSERT(rwlock->rw_owner == me);
+    	rwlock->rw_owner = NULL;
+#endif
+		/*
+		 * wakeup a writer, if present; preference for writers
+		 */
+		if (rwlock->rw_writer_cnt > 0)
+			PR_NotifyCondVar(rwlock->rw_writer_waitq);
+		/*
+		 * else, wakeup all readers, if any
+		 */
+		else if (rwlock->rw_reader_cnt > 0)
+			PR_NotifyAllCondVar(rwlock->rw_reader_waitq);
+	}
+	PR_Unlock(rwlock->rw_lock);
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * update thread's lock rank
+	 */
+	_PR_UNSET_THREAD_RWLOCK_RANK(rwlock);
+#endif
+	return;
+}
+
+#ifndef _PR_RWLOCK_RANK_ORDER_DEBUG
+
+void _PR_InitRWLocks(void) { }
+
+#else
+
+void _PR_InitRWLocks(void)
+{
+	/*
+	 * allocated thread-private-data index for rwlock list
+	 */
+	if (PR_NewThreadPrivateIndex(&pr_thread_rwlock_key,
+			_PR_RELEASE_LOCK_STACK) == PR_FAILURE) {
+		pr_thread_rwlock_alloc_failed = 1;
+		return;
+	}
+}
+
+/*
+ * _PR_SET_THREAD_RWLOCK_RANK
+ *		Set a thread's lock rank, which is the highest of the ranks of all
+ *		the locks held by the thread. Pointers to the locks are added to a
+ *		per-thread list, which is anchored off a thread-private data key.
+ */
+
+static void
+_PR_SET_THREAD_RWLOCK_RANK(PRRWLock *rwlock)
+{
+thread_rwlock_stack *lock_stack;
+PRStatus rv;
+
+	/*
+	 * allocate a lock stack
+	 */
+	if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL) {
+		lock_stack = (thread_rwlock_stack *)
+						PR_CALLOC(1 * sizeof(thread_rwlock_stack));
+		if (lock_stack) {
+			rv = PR_SetThreadPrivate(pr_thread_rwlock_key, lock_stack);
+			if (rv == PR_FAILURE) {
+				PR_DELETE(lock_stack);
+				pr_thread_rwlock_alloc_failed = 1;
+				return;
+			}
+		} else {
+			pr_thread_rwlock_alloc_failed = 1;
+			return;
+		}
+	}
+	/*
+	 * add rwlock to lock stack, if limit is not exceeded
+	 */
+	if (lock_stack) {
+		if (lock_stack->trs_index < _PR_RWLOCK_RANK_ORDER_LIMIT)
+			lock_stack->trs_stack[lock_stack->trs_index++] = rwlock;	
+	}
+}
+
+static void
+_PR_RELEASE_LOCK_STACK(void *lock_stack)
+{
+	PR_ASSERT(lock_stack);
+	PR_DELETE(lock_stack);
+}
+
+/*
+ * _PR_GET_THREAD_RWLOCK_RANK
+ *
+ *		return thread's lock rank. If thread-private-data for the lock
+ *		stack is not allocated, return PR_RWLOCK_RANK_NONE.
+ */
+	
+static PRUint32
+_PR_GET_THREAD_RWLOCK_RANK(void)
+{
+	thread_rwlock_stack *lock_stack;
+
+	if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL)
+		return (PR_RWLOCK_RANK_NONE);
+	else
+		return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank);
+}
+
+/*
+ * _PR_UNSET_THREAD_RWLOCK_RANK
+ *
+ *		remove the rwlock from the lock stack. Since locks may not be
+ *		unlocked in a FIFO order, the entire lock stack is searched.
+ */
+	
+static void
+_PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock)
+{
+	thread_rwlock_stack *lock_stack;
+	int new_index = 0, index, done = 0;
+
+	lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key);
+
+	PR_ASSERT(lock_stack != NULL);
+
+	index = lock_stack->trs_index - 1;
+	while (index-- >= 0) {
+		if ((lock_stack->trs_stack[index] == rwlock) && !done)  {
+			/*
+			 * reset the slot for rwlock
+			 */
+			lock_stack->trs_stack[index] = NULL;
+			done = 1;
+		}
+		/*
+		 * search for the lowest-numbered empty slot, above which there are
+		 * no non-empty slots
+		 */
+		if ((lock_stack->trs_stack[index] != NULL) && !new_index)
+			new_index = index + 1;
+		if (done && new_index)
+			break;
+	}
+	/*
+	 * set top of stack to highest numbered empty slot
+	 */
+	lock_stack->trs_index = new_index;
+
+}
+
+#endif 	/* _PR_RWLOCK_RANK_ORDER_DEBUG */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prsem.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prsem.c
new file mode 100644
index 0000000..d26897c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prsem.c
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include "obsolete/prsem.h"
+
+/************************************************************************/
+
+/*
+** Create a new semaphore.
+*/
+PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value)
+{
+    PRSemaphore *sem;
+    PRCondVar *cvar;
+    PRLock *lock;
+
+    sem = PR_NEWZAP(PRSemaphore);
+    if (sem) {
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+        _PR_MD_NEW_SEM(&sem->md, value);
+#else
+        lock = PR_NewLock();
+        if (!lock) {
+            PR_DELETE(sem);
+            return NULL;
+    	}
+
+        cvar = PR_NewCondVar(lock);
+        if (!cvar) {
+            PR_DestroyLock(lock);
+            PR_DELETE(sem);
+            return NULL;
+    	}
+    	sem->cvar = cvar;
+    	sem->count = value;
+#endif
+    }
+    return sem;
+}
+
+/*
+** Destroy a semaphore. There must be no thread waiting on the semaphore.
+** The caller is responsible for guaranteeing that the semaphore is
+** no longer in use.
+*/
+PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *sem)
+{
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+    _PR_MD_DESTROY_SEM(&sem->md);
+#else
+    PR_ASSERT(sem->waiters == 0);
+
+    PR_DestroyLock(sem->cvar->lock);
+    PR_DestroyCondVar(sem->cvar);
+#endif
+    PR_DELETE(sem);
+}
+
+/*
+** Wait on a Semaphore.
+** 
+** This routine allows a calling thread to wait or proceed depending upon the 
+** state of the semahore sem. The thread can proceed only if the counter value 
+** of the semaphore sem is currently greater than 0. If the value of semaphore 
+** sem is positive, it is decremented by one and the routine returns immediately 
+** allowing the calling thread to continue. If the value of semaphore sem is 0, 
+** the calling thread blocks awaiting the semaphore to be released by another 
+** thread.
+** 
+** This routine can return PR_PENDING_INTERRUPT if the waiting thread 
+** has been interrupted.
+*/
+PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *sem)
+{
+	PRStatus status = PR_SUCCESS;
+
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+	return _PR_MD_WAIT_SEM(&sem->md);
+#else
+	PR_Lock(sem->cvar->lock);
+	while (sem->count == 0) {
+		sem->waiters++;
+		status = PR_WaitCondVar(sem->cvar, PR_INTERVAL_NO_TIMEOUT);
+		sem->waiters--;
+		if (status != PR_SUCCESS)
+			break;
+	}
+	if (status == PR_SUCCESS)
+		sem->count--;
+	PR_Unlock(sem->cvar->lock);
+#endif
+	
+	return (status);
+}
+
+/*
+** This routine increments the counter value of the semaphore. If other threads 
+** are blocked for the semaphore, then the scheduler will determine which ONE 
+** thread will be unblocked.
+*/
+PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *sem)
+{
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+	_PR_MD_POST_SEM(&sem->md);
+#else
+	PR_Lock(sem->cvar->lock);
+	if (sem->waiters)
+		PR_NotifyCondVar(sem->cvar);
+	sem->count++;
+	PR_Unlock(sem->cvar->lock);
+#endif
+}
+
+#if DEBUG
+/*
+** Returns the value of the semaphore referenced by sem without affecting
+** the state of the semaphore.  The value represents the semaphore vaule
+** at the time of the call, but may not be the actual value when the
+** caller inspects it. (FOR DEBUGGING ONLY)
+*/
+PR_IMPLEMENT(PRUintn) PR_GetValueSem(PRSemaphore *sem)
+{
+	PRUintn rv;
+
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+	rv = _PR_MD_GET_VALUE_SEM(&sem->md);
+#else
+	PR_Lock(sem->cvar->lock);
+	rv = sem->count;
+	PR_Unlock(sem->cvar->lock);
+#endif
+	
+	return rv;
+}
+#endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prtpd.c b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prtpd.c
new file mode 100644
index 0000000..5c53313
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/src/threads/prtpd.c
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Thread Private Data
+**
+** There is an aribitrary limit on the number of keys that will be allocated
+** by the runtime. It's largish, so it is intended to be a sanity check, not
+** an impediment.
+**
+** There is a counter, initialized to zero and incremented every time a
+** client asks for a new key, that holds the high water mark for keys. All
+** threads logically have the same high water mark and are permitted to
+** ask for TPD up to that key value.
+**
+** The vector to hold the TPD are allocated when PR_SetThreadPrivate() is
+** called. The size of the vector will be some value greater than or equal
+** to the current high water mark. Each thread has its own TPD length and
+** vector.
+**
+** Threads that get private data for keys they have not set (or perhaps
+** don't even exist for that thread) get a NULL return. If the key is
+** beyond the high water mark, an error will be returned.
+*/
+
+/*
+** As of this time, BeOS has its own TPD implementation.  Integrating
+** this standard one is a TODO for anyone with a bit of spare time on
+** their hand.  For now, we just #ifdef out this whole file and use
+** the routines in pr/src/btthreads/
+*/
+
+#ifndef XP_BEOS
+
+#include "primpl.h"
+
+#include <string.h>
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+#define _PR_TPD_LIMIT 128               /* arbitary limit on the TPD slots */
+static PRInt32 _pr_tpd_length = 0;      /* current length of destructor vector */
+static PRInt32 _pr_tpd_highwater = 0;   /* next TPD key to be assigned */
+static PRThreadPrivateDTOR *_pr_tpd_destructors = NULL;
+                                        /* the destructors are associated with
+                                            the keys, therefore asserting that
+                                            the TPD key depicts the data's 'type' */
+
+/*
+** Initialize the thread private data manipulation
+*/
+void _PR_InitTPD(void)
+{
+    _pr_tpd_destructors = (PRThreadPrivateDTOR*)
+        PR_CALLOC(_PR_TPD_LIMIT * sizeof(PRThreadPrivateDTOR*));
+    PR_ASSERT(NULL != _pr_tpd_destructors);
+    _pr_tpd_length = _PR_TPD_LIMIT;
+}
+
+/*
+** Clean up the thread private data manipulation
+*/
+void _PR_CleanupTPD(void)
+{
+}  /* _PR_CleanupTPD */
+
+/*
+** This routine returns a new index for per-thread-private data table. 
+** The index is visible to all threads within a process. This index can 
+** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines 
+** to save and retrieve data associated with the index for a thread.
+**
+** The index independently maintains specific values for each binding thread. 
+** A thread can only get access to its own thread-specific-data.
+**
+** Upon a new index return the value associated with the index for all threads
+** is NULL, and upon thread creation the value associated with all indices for 
+** that thread is NULL. 
+**
+**     "dtor" is the destructor function to invoke when the private
+**       data is set or destroyed
+**
+** Returns PR_FAILURE if the total number of indices will exceed the maximun 
+** allowed.
+*/
+
+PR_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndex(
+    PRUintn *newIndex, PRThreadPrivateDTOR dtor)
+{
+    PRStatus rv;
+    PRInt32 index;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    PR_ASSERT(NULL != newIndex);
+    PR_ASSERT(NULL != _pr_tpd_destructors);
+
+    index = PR_ATOMIC_INCREMENT(&_pr_tpd_highwater) - 1;  /* allocate index */
+    if (_PR_TPD_LIMIT <= index)
+    {
+        PR_SetError(PR_TPD_RANGE_ERROR, 0);
+        rv = PR_FAILURE;  /* that's just wrong */
+    }
+    else
+    {
+        _pr_tpd_destructors[index] = dtor;  /* record destructor @index */
+        *newIndex = (PRUintn)index;  /* copy into client's location */
+        rv = PR_SUCCESS;  /* that's okay */
+    }
+
+    return rv;
+}
+
+/*
+** Define some per-thread-private data.
+**     "index" is an index into the per-thread private data table
+**     "priv" is the per-thread-private data 
+**
+** If the per-thread private data table has a previously registered
+** destructor function and a non-NULL per-thread-private data value,
+** the destructor function is invoked.
+**
+** This can return PR_FAILURE if index is invalid (ie., beyond the current
+** high water mark) or memory is insufficient to allocate an exanded vector.
+*/
+
+PR_IMPLEMENT(PRStatus) PR_SetThreadPrivate(PRUintn index, void *priv)
+{
+    PRThread *self = PR_GetCurrentThread();
+
+    /*
+    ** The index being set might not have a sufficient vector in this
+    ** thread. But if the index has been allocated, it's okay to go
+    ** ahead and extend this one now.
+    */
+    if ((index >= _PR_TPD_LIMIT) || (index >= _pr_tpd_highwater))
+    {
+        PR_SetError(PR_TPD_RANGE_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    PR_ASSERT(((NULL == self->privateData) && (0 == self->tpdLength))
+        || ((NULL != self->privateData) && (0 != self->tpdLength)));
+
+    if ((NULL == self->privateData) || (self->tpdLength <= index))
+    {
+        void *extension = PR_CALLOC(_pr_tpd_length * sizeof(void*));
+        if (NULL == extension)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return PR_FAILURE;
+        }
+        if (self->privateData) {
+            (void)memcpy(
+                extension, self->privateData,
+                self->tpdLength * sizeof(void*));
+            PR_DELETE(self->privateData);
+        }
+        self->tpdLength = _pr_tpd_length;
+        self->privateData = (void**)extension;
+    }
+    /*
+    ** There wasn't much chance of having to call the destructor
+    ** unless the slot already existed.
+    */
+    else if (self->privateData[index] && _pr_tpd_destructors[index])
+    {
+        void *data = self->privateData[index];
+        self->privateData[index] = NULL;
+        (*_pr_tpd_destructors[index])(data);
+    }
+
+    PR_ASSERT(index < self->tpdLength);
+    self->privateData[index] = priv;
+
+    return PR_SUCCESS;
+}
+
+/*
+** Recover the per-thread-private data for the current thread. "index" is
+** the index into the per-thread private data table. 
+**
+** The returned value may be NULL which is indistinguishable from an error 
+** condition.
+**
+*/
+
+PR_IMPLEMENT(void*) PR_GetThreadPrivate(PRUintn index)
+{
+    PRThread *self = PR_GetCurrentThread();
+    void *tpd = ((NULL == self->privateData) || (index >= self->tpdLength)) ?
+        NULL : self->privateData[index];
+
+    return tpd;
+}
+
+/*
+** Destroy the thread's private data, if any exists. This is called at
+** thread termination time only. There should be no threading issues
+** since this is being called by the thread itself.
+*/
+void _PR_DestroyThreadPrivate(PRThread* self)
+{
+#define _PR_TPD_DESTRUCTOR_ITERATIONS 4
+
+    if (NULL != self->privateData)  /* we have some */
+    {
+        PRBool clean;
+        PRUint32 index;
+        PRInt32 passes = _PR_TPD_DESTRUCTOR_ITERATIONS;
+        PR_ASSERT(0 != self->tpdLength);
+        do
+        {
+            clean = PR_TRUE;
+            for (index = 0; index < self->tpdLength; ++index)
+            {
+                void *priv = self->privateData[index];  /* extract */
+                if (NULL != priv)  /* we have data at this index */
+                {
+                    if (NULL != _pr_tpd_destructors[index])
+                    {
+                        self->privateData[index] = NULL;  /* precondition */
+                        (*_pr_tpd_destructors[index])(priv);  /* destroy */
+                        clean = PR_FALSE;  /* unknown side effects */
+                    }
+                }
+            }
+        } while ((--passes > 0) && !clean);  /* limit # of passes */
+        /*
+        ** We give up after a fixed number of passes. Any non-NULL
+        ** thread-private data value with a registered destructor
+        ** function is not destroyed.
+        */
+        memset(self->privateData, 0, self->tpdLength * sizeof(void*));
+    }
+}  /* _PR_DestroyThreadPrivate */
+
+#endif /* !XP_BEOS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/tests/Makefile.in
new file mode 100644
index 0000000..695ce68
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/Makefile.in
@@ -0,0 +1,580 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH	= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = dll
+
+CSRCS =             \
+	accept.c		\
+	acceptread.c	\
+	acceptreademu.c	\
+	addrstr.c		\
+	affinity.c		\
+	alarm.c			\
+	anonfm.c		\
+	append.c		\
+	atomic.c		\
+	attach.c		\
+	bigfile.c		\
+	bigfile2.c		\
+	bigfile3.c		\
+	cleanup.c		\
+	cltsrv.c		\
+	concur.c	    \
+	cvar.c			\
+	cvar2.c			\
+	dceemu.c		\
+	dlltest.c		\
+	dtoa.c			\
+	env.c			\
+	errcodes.c		\
+	errset.c		\
+	exit.c  		\
+	fdcach.c		\
+	fileio.c		\
+	foreign.c	    \
+	forktest.c	    \
+	formattm.c	    \
+	fsync.c	        \
+	getai.c			\
+	gethost.c		\
+	getproto.c		\
+	i2l.c		    \
+	initclk.c		\
+	inrval.c		\
+	instrumt.c      \
+	intrio.c        \
+	intrupt.c       \
+	io_timeout.c    \
+	ioconthr.c      \
+	ipv6.c          \
+	join.c    		\
+	joinkk.c        \
+	joinku.c        \
+	joinuk.c        \
+	joinuu.c        \
+	layer.c		    \
+	lazyinit.c		\
+	libfilename.c	\
+	lltest.c        \
+	lock.c          \
+	lockfile.c      \
+	logfile.c       \
+	logger.c		\
+	makedir.c		\
+	mbcs.c			\
+	multiacc.c		\
+	multiwait.c		\
+	many_cv.c		\
+	nameshm1.c      \
+	nbconn.c		\
+	nblayer.c		\
+	nonblock.c		\
+	ntioto.c        \
+	ntoh.c			\
+	obsints.c		\
+	op_2long.c      \
+	op_excl.c		\
+	op_filnf.c		\
+	op_filok.c		\
+	op_noacc.c		\
+	op_nofil.c		\
+	openfile.c		\
+	parent.c    	\
+	parsetm.c    	\
+	peek.c    		\
+	perf.c    		\
+	pipeping.c		\
+	pipeping2.c		\
+	pipepong.c		\
+	pipepong2.c		\
+	pipeself.c		\
+	poll_er.c		\
+	poll_nm.c		\
+	poll_to.c		\
+	pollable.c		\
+	prftest.c		\
+	prftest1.c		\
+	prftest2.c		\
+	primblok.c		\
+	priotest.c		\
+	provider.c		\
+	prpoll.c		\
+	prpollml.c		\
+	ranfile.c       \
+	randseed.c      \
+	reinit.c        \
+	rmdir.c			\
+	rwlocktest.c    \
+	sel_spd.c  		\
+	selct_er.c	    \
+	selct_nm.c	    \
+	selct_to.c	    \
+	select2.c  		\
+	selintr.c  		\
+	sem.c 	  		\
+	sema.c 	  		\
+	semaerr.c 		\
+	semaerr1.c 		\
+	semaping.c 		\
+	semapong.c 		\
+	sendzlf.c 		\
+	server_test.c	\
+	servr_kk.c		\
+	servr_ku.c		\
+	servr_uk.c		\
+	servr_uu.c		\
+	short_thread.c	\
+	sigpipe.c		\
+	socket.c		\
+	sockopt.c		\
+	sockping.c		\
+	sockpong.c		\
+	sprintf.c		\
+	sproc_ch.c	    \
+	sproc_p.c	    \
+	stack.c		    \
+	stdio.c		    \
+	str2addr.c		\
+	strod.c			\
+	suspend.c		\
+	switch.c		\
+	system.c		\
+	testbit.c    	\
+	testfile.c    	\
+	thrpool_server.c \
+	thrpool_client.c \
+	threads.c 	  	\
+	thruput.c 	  	\
+	timemac.c		\
+	timetest.c		\
+	tmoacc.c        \
+	tmocon.c        \
+	tpd.c			\
+	vercheck.c		\
+	version.c	    \
+	udpsrv.c	    \
+	writev.c        \
+	xnotify.c       \
+	y2k.c           \
+	y2ktmo.c        \
+	zerolen.c       \
+	$(NULL)
+
+ifeq ($(OS_ARCH),WINCE)
+CFLAGS += -FImozce_shunt.h -Zi -UDEBUG -DNDEBUG
+LDOPTS += -link $(DIST)/lib/mozce_shunt.lib ws2.lib -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO -PDB:$(@:.exe=.pdb)
+endif
+
+ifeq ($(OS_TARGET),OS2)
+CSRCS +=            \
+	sleep.c			\
+	stat.c		    \
+	yield.c         \
+	$(NULL)
+endif
+
+ifeq (,$(filter-out WINCE WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+DLL_SUFFIX = .dll
+else
+PROG_SUFFIX =
+DLL_SUFFIX = 
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+ifeq ($(OS_ARCH), WINNT)
+ifdef NS_USE_GCC
+  EXTRA_LIBS += -lwsock32
+else
+  EXTRA_LIBS += wsock32.lib
+  LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO
+  ifdef PROFILE
+    LDOPTS += -PROFILE -MAP
+  endif # profile
+endif # NS_USE_GCC
+endif
+
+ifeq ($(OS_ARCH),OS2)
+EXTRA_LIBS = $(OS_LIBS)
+LDOPTS = -Zomf -Zlinker /PM:VIO -Zlinker /ST:0x64000
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+# Use an absolute pathname as the runtime library path (for the -R
+# or -rpath linker option or the LD_RUN_PATH environment variable).
+ifeq (,$(patsubst /%,,$(DIST)))
+# $(DIST) is already an absolute pathname.
+ABSOLUTE_LIB_DIR = $(dist_libdir)
+else
+# $(DIST) is a relative pathname: prepend the current directory.
+PWD = $(shell pwd)
+ABSOLUTE_LIB_DIR = $(PWD)/$(dist_libdir)
+endif
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+    ifeq ($(USE_CPLUS), 1)
+        CC = CC
+    endif
+    LDOPTS += -rpath $(ABSOLUTE_LIB_DIR)
+    ifdef NS_USE_GCC
+        LDOPTS += -Wl,-rdata_shared
+    else
+        LDOPTS += -rdata_shared
+    endif
+# For 6.x machines, include this flag
+    ifeq ($(basename $(OS_RELEASE)),6)
+        ifndef NS_USE_GCC
+            ifeq ($(USE_N32),1)
+                LDOPTS += -n32
+            else
+                LDOPTS += -32
+            endif
+
+            ifeq ($(USE_PTHREADS), 1)
+                ifeq ($(OS_RELEASE), 6.2)
+                    LDOPTS += -Wl,-woff,85
+                endif
+            endif
+        endif
+    endif
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+    ifeq ($(USE_CPLUS), 1)
+        CC = cxx
+    endif
+# I haven't figured out how to pass -rpath to cc on OSF1 V3.2, so
+# we do static linking.
+    ifeq (,$(filter-out V2.0 V3.2,$(OS_RELEASE)))
+        LIBNSPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+        LIBPLC = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).a
+        EXTRA_LIBS = -lc_r
+    else
+        LDOPTS += -rpath $(ABSOLUTE_LIB_DIR)
+    endif
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+    LDOPTS += -z -Wl,+s,+b,$(ABSOLUTE_LIB_DIR)
+    ifeq ($(USE_64),1)
+        LDOPTS += +DD64
+    endif
+    ifeq ($(USE_PTHREADS),1)
+        EXTRA_LIBS = $(LIBPTHREAD)
+    endif
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+    LDOPTS += -blibpath:$(ABSOLUTE_LIB_DIR):/usr/lib:/lib
+    ifneq ($(OS_ARCH)$(OS_RELEASE),AIX4.1)
+        LDOPTS += -brtl
+        EXTRA_LIBS = -ldl
+    endif
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+    ifneq ($(OS_RELEASE), 4.1.3_U1)
+        ifdef NS_USE_GCC
+            LDOPTS += -Xlinker -R -Xlinker $(ABSOLUTE_LIB_DIR)
+        else
+            ifeq ($(USE_CPLUS), 1)
+                CC = CC
+            endif
+            LDOPTS += -R $(ABSOLUTE_LIB_DIR)
+        endif
+    endif
+
+    ifdef USE_PTHREADS
+        EXTRA_LIBS = -lpthread
+    endif
+endif # SunOS
+
+ifeq ($(OS_ARCH), NEC)
+    EXTRA_LIBS = $(OS_LIBS)
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath
+# option for ld on other platforms.
+    export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH), NCR)
+# NCR needs to link against -lsocket -lnsl -ldl (and -lc, which is
+# linked implicitly by $(CC)).  Note that we did not link with these
+# system libraries when we built libnspr.so.
+    EXTRA_LIBS = -lsocket -lnsl -ldl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+    export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH), NEXTSTEP)
+# balazs.pataki@sztaki.hu: linkage is done in a different pass in the `tests'
+# modeul, so we have to pass the `-posix' flag by "hand" to `ld'
+LDOPTS += -posix
+endif
+
+ifeq ($(OS_ARCH), NEWS-OS)
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+#export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+    LIBNSPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+    LIBPLC = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).a
+    EXTRA_LIBS = -lsocket -lnsl -lgen -lresolv
+endif
+
+ifeq (,$(filter-out Linux GNU GNU_%,$(OS_ARCH)))
+    LDOPTS += -Xlinker -rpath $(ABSOLUTE_LIB_DIR)
+    ifeq ($(USE_PTHREADS),1)
+        EXTRA_LIBS = -lpthread
+    endif
+endif
+
+ifeq ($(OS_ARCH), SCOOS)
+# SCO Unix needs to link against -lsocket again even though we
+# already linked with these system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH),SINIX)
+EXTRA_LIBS = -lsocket -lnsl -lresolv -ldl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH),OpenUNIX)
+export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+ifeq ($(USE_PTHREADS),1)
+LDOPTS += -pthread
+endif
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH),FreeBSD)
+ifeq ($(USE_PTHREADS),1)
+LDOPTS += -pthread
+endif
+LDOPTS += -Xlinker -R $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH),OpenBSD)
+ifeq ($(USE_PTHREADS),1)
+LDOPTS += -pthread
+endif
+endif
+
+ifeq ($(OS_ARCH),BSD_OS)
+ifneq ($(OS_RELEASE),1.1)
+EXTRA_LIBS = -ldl
+endif
+endif
+
+ifeq ($(OS_ARCH),RISCOS)
+EXTRA_LIBS = -ldl
+endif
+
+ifeq ($(USE_PTHREADS),1)
+LIBPTHREAD = -lpthread
+ifeq ($(OS_ARCH),AIX)
+LIBPTHREAD = -lpthreads
+endif
+ifeq (,$(filter-out FreeBSD OpenBSD BSD_OS QNX Darwin OpenUNIX,$(OS_ARCH)))
+LIBPTHREAD =
+endif
+ifeq ($(OS_ARCH)$(basename $(OS_RELEASE)),HP-UXB.10)
+LIBPTHREAD = -ldce
+endif
+endif
+
+ifeq ($(OS_TARGET),Android)
+LDOPTS=$(OS_LDFLAGS)
+LIBPTHREAD=
+XCFLAGS=${OS_CFLAGS}
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifeq ($(OS_RELEASE),4.1)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to 
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+	rm -f $@ $(AIX_TMP)
+	$(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+	$(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+	rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	link $(LDOPTS) $(EXTRA_LDOPTS) $< $(LIBPLC) $(LIBNSPR) $(EXTRA_LIBS) -out:$@
+ifdef MT
+	@if test -f $@.manifest; then \
+		$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
+		rm -f $@.manifest; \
+	fi
+endif
+else
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(EXTRA_LIBS) -o $@
+endif # WINNT
+endif # AIX_PRE_4_2
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
+
+# The following tests call BSD socket functions, so they need to link
+# with -lsocket on some platforms.
+ifeq ($(OS_ARCH),SunOS)
+ifneq ($(OS_RELEASE),4.1.3_U1)
+ifeq ($(USE_IPV6),1)
+$(OBJDIR)/gethost: $(OBJDIR)/gethost.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) -lsocket $(EXTRA_LIBS) -o $@
+endif
+$(OBJDIR)/prpoll: $(OBJDIR)/prpoll.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) -lsocket $(EXTRA_LIBS) -o $@
+endif
+endif
+
+ifeq ($(USE_PTHREADS), 1)
+$(OBJDIR)/attach: $(OBJDIR)/attach.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+$(OBJDIR)/foreign: $(OBJDIR)/foreign.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+$(OBJDIR)/provider: $(OBJDIR)/provider.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+$(OBJDIR)/socket: $(OBJDIR)/socket.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+$(OBJDIR)/testfile: $(OBJDIR)/testfile.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+endif
+
+#
+# Run the test programs with no arguments
+#
+# Test output goes to the file pointed to by the environment variable
+# NSPR_TEST_LOGFILE, if set, else to /dev/null
+#
+ECHO = echo
+PROGRAMS = $(notdir $(PROGS))
+ifdef NSPR_TEST_LOGFILE
+LOGFILE = $(NSPR_TEST_LOGFILE)
+else
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+LOGFILE = nul
+else
+LOGFILE = /dev/null
+endif
+endif
+
+ifeq ($(OS_TARGET),Linux)
+ECHO = /bin/echo
+endif
+
+ALWAYS:
+
+runtests:: $(PROGS) ALWAYS
+	@$(ECHO) "\nNSPR Test Results - $(OBJDIR)\n"
+	@$(ECHO) "BEGIN\t\t\t`date`"
+	@$(ECHO) "NSPR_TEST_LOGFILE\t$(LOGFILE)\n"
+	@$(ECHO) "Test\t\t\tResult\n"
+	@cd $(OBJDIR); for i in $(PROGRAMS); do					\
+	$(ECHO) "$$i\c";										\
+	./$$i >> $(LOGFILE) 2>&1 ;								\
+	if  [ 0 = $$? ] ; then									\
+		$(ECHO) "\t\t\tPassed";								\
+	else													\
+		$(ECHO) "\t\t\tFAILED";								\
+	fi;														\
+	done
+	@$(ECHO) "\nEND\t\t`date`\n"
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/README.TXT b/nspr-4.8.6/mozilla/nsprpub/pr/tests/README.TXT
new file mode 100644
index 0000000..eaab44f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/README.TXT
@@ -0,0 +1,407 @@
+File: pr/tests/readme
+
+This document describes the test cases in the NSPR directory
+pr/tests.
+
+=====================================================================
+There is a sub-directory here:
+
+dll
+	sources for the .dll(.so) used by test dlltest.c
+
+=====================================================================
+The individual files are described here.
+
+The script 'runtests.ksh' enumerates and runs test cases that are
+expected to run on all platforms.
+
+
+accept.c
+	Tests PR_Accept() and related socket functions.
+
+acceptread.c
+	Tests PR_AcceptRead()
+
+alarm.c
+	Tests alarm functions declared in obsolete/pralarm.h.
+	The alarm functions are obsolete, so is this test.
+
+atomic.c
+	Tests Atomic operations defined in pratom.h
+
+attach.c
+	Test PR_AttachThread()
+	Note: This is an NSPR private function.
+
+bigfile.c
+	Test 64bit file offset functions declared in prio.h
+
+bug1test.c
+	Demonstrates a bug on NT.
+
+cleanup.c
+	Tests PR_Cleanup() declared in prinit.h
+
+cltsrv.c
+	Tests many socket functions.
+
+concur.c
+	Tests threading functions and concurrent operations.
+
+cvar.c
+	Tests condition variables.
+
+cvar2.c
+	Tests condition variables. A rather abusive test.
+
+dbmalloc.c
+	Obsolete. Originally for testing debug builds of NSPR's malloc.
+
+dbmalloc1.c
+	Obsolete. Originally for testing debug builds of NSPR's malloc.
+
+dceemu.c
+	Tests special functions for DCE emulation.
+
+depend.c
+	Obsoltet. Tests early spec for library dependency.
+
+dlltest.c
+	Tests dynamic library functions. Used with dll/my.c
+
+dtoa.c
+	Tests conversions of double to string.
+
+exit.c
+	Tests PR_ProcessExit() declared in prinit.h
+
+fileio.c
+	Tests NSPR semaphores a bit of file i/o and threading
+	functions.
+
+foreign.c
+	Test auto-attach of a thread created by something other than
+	NSPR.
+
+forktest.c
+	Limited use. Tests unix fork() and related functions.
+
+fsync.c
+	Tests use of PR_Sync() declared in prio.h
+
+getproto.c
+	Tests socket functions PR_GetProtoByName(), etc.
+
+i2l.c
+	Tests LongLong functions for converting 32bit integer to 64bit
+	integer.
+
+initclk.c
+	Tests timing on minimal use of condition variable
+
+inrval.c
+	Tests interval timing functions.
+
+instrumt.c
+	Tests instrumentation functions. prcountr.h prtrace.h
+
+intrupt.c
+	Tests PR_Interrupt()
+
+ioconthr.c
+	Tests i/o continuation mechanism in pthreads.
+
+io_timeout.c
+	Test socket i/o timeouts.
+
+io_timeoutk.c
+	Obsolete. Subsumed in io_timeout.c
+
+io_timeoutu.c
+	Obsolete. Subsumed in io_timeout.c
+
+ipv6.c
+	Tests IPv6. IPv6 is not used by NSPR clients.
+
+join.c
+	Tests PR_JoinThread()
+
+joinkk.c
+	Tests PR_JoinThread()
+
+joinku.c
+	Tests PR_JoinThread()
+
+joinuk.c
+	Tests PR_JoinThread()
+
+joinuu.c
+	Tests PR_JoinThread()
+
+layer.c
+	Tests layered I/O.
+
+lazyinit.c
+	Tests implicit initialization.
+
+lltest.c
+	Tests LongLong (64bit integer) arithmentic and conversions.
+
+lock.c
+	Tests PR_Lock() in heavily threaded environment.
+
+lockfile.c
+	Test PR_Lockfile().
+
+logger.c
+	Tests PR_LOG()
+
+makefile
+	The makefile that builds all the tests
+
+many_cv.c
+	Tests aquiring a large number of condition variables.
+
+multiwait.c
+	???
+
+nbconn.c
+	Test non-blocking connect.
+
+nblayer.c
+	Tests NSPR's layered I/O capability.
+
+nonblock.c
+	Tests operations on non-blocking socket.
+
+op_2long.c
+	Tests PR_Open() where filename is too long.
+
+op_filnf.c
+	Tests PR_Open() where filename is NotFound.
+
+op_filok.c
+	Tests PR_Open() where filename is accessable.
+
+op_noacc.c
+	Tests PR_Open() where file permissions are wrong.
+	Limited use. Windows has no concept of Unix style file permissions.
+
+op_nofil.c
+	Tests PR_Open() where filename does not exist.
+
+parent.c
+	Test parent/child process capability
+
+perf.c
+	Tests and measures context switch times for various thread
+	syncronization functions.
+
+pipeping.c
+	Tests inter-process pipes. Run with pipepong.c
+
+pipepong.c
+	Tests inter-process pipes. Run with pipeping.c
+
+pipeself.c
+	Tests inter-thread pipes.
+
+pollable.c
+	Tests pollable events. prio.h
+
+poll_er.c
+	Tests PR_Poll() where an error is expected.
+
+poll_nm.c
+	Tests PR_Poll() where normal operation is expected.
+
+poll_to.c
+	Tests PR_Poll() where timeout is expected.
+
+prftest.c
+	Tests printf-like formatting.
+
+prftest1.c
+	Obsolete. Subsumed in prftest.c
+
+prftest2.c
+	Obsolete. Subsumed in prftest.c
+
+priotest.c
+	Limited use. Tests NSPR thread dispatching priority.
+
+provider.c
+
+prpoll.c
+	Tests PR_Poll().
+
+prselect.c
+	Obsolete. PR_Select() is obsolete.
+
+prttools.h
+	Unused file.
+
+ranfile.c
+	Tests random file access.
+
+readme
+	This file.
+
+runtests.ksh
+	A korn shell script that runs a set of tests that should run
+	on any of the NSPR supported platforms.
+
+runtests.pl
+	A perl script to run the test cases. This srcipt runs tests
+	common to all platforms and runs tests applicable to specific
+	platforms. Uses file runtests.txt to control execution.
+
+runtests.txt
+	Control file for perl script: runtests.pl
+
+rwlocktest.c
+	Tests Reader/Writer lock
+
+selct_er.c
+	Obsolete. PR_Select() is obsolete.
+
+selct_nm.c
+	Obsolete. PR_Select() is obsolete.
+
+selct_to.c
+	Obsolete. PR_Select() is obsolete.
+
+select2.c
+	Obsolete. PR_Select() is obsolete.
+
+sel_spd.c
+	Obsolete. PR_Select() is obsolete.
+
+sem.c
+	Obsolete. Semaphores are not supported.
+
+server_test.c
+	Tests sockets by simulating a server in loopback mode.
+	Makes its own client threads.
+
+servr_kk.c
+	Tests client/server sockets, threads using system threads.
+
+servr_ku.c
+	Tests client/server sockets, threads using system and user threads.
+
+servr_uk.c
+	Tests client/server sockets, threads using system and user threads.
+
+servr_uu.c
+	Tests client/server sockets, threads user threads.
+
+short_thread.c
+	Tests short-running threads. Useful for testing for race conditions.
+
+sigpipe.c
+	Tests NSPR's SIGPIPE handler. Unix only.
+
+sleep.c
+	Limited use. Tests sleep capability of platform.
+
+socket.c
+	Tests many socket functions.
+
+sockopt.c
+	Tests setting and getting socket options.
+
+sprintf.c
+	Tests sprintf.
+
+sproc_ch.c
+	Obsolete. Tests IRIX sproc-based threads.
+
+sproc_p.c
+	Obsolete. Tests IRIX sproc-based threads.
+
+stack.c
+	Test atomic stack operations.
+
+stat.c
+	Tests performance of getfileinfo() vs. stat()
+
+stdio.c
+	Tests NSPR's handling of stdin, stdout, stderr.
+
+strod.c
+	Tests formatting of double precision floating point.
+
+suspend.c
+	Private interfaces PR_SuspendAll(), PR_ResumeAll(), etc.
+
+switch.c
+	Tests thread switching
+
+system.c
+	Tests PR_GetSystemInfo()
+
+testbit.c
+	Tests bit arrays.
+
+testfile.c
+	Tests many file I/O functions.
+
+threads.c
+	Tests thread caching.
+
+thruput.c
+	Tests socket thruput. Must be run by hand as client/server.
+	Does not self terminate.
+
+time.c
+	Incomplete. Limited use.
+
+timemac.c
+	Test time and date functions. Originally for Mac.
+
+timetest.c
+	Tests time conversion over a wide range of dates.
+
+tmoacc.c
+	Server to tmocon.c and writev.c
+	Do not run it by itself.
+
+tmocon.c
+	Client thread to tmoacc.c
+
+tpd.c
+	Tests thread private data.
+
+udpsrv.c
+	Tests UDP socket functions.
+
+ut_ttools.h
+	unused file.
+
+version.c
+	Extract and print library version data.
+
+vercheck.c
+	Test PR_VersionCheck().
+
+writev.c
+	Tests gather-write on a socket. Requires tmoacc.c
+
+xnotify.c
+	Tests cached monitors.
+
+yield.c
+	Limited use
+
+y2k.c
+	Test to verify NSPR's date functions as Y2K compliant.
+
+dll\Makefile
+	makefile for mygetval.c, mysetval.c
+
+dll\mygetval.c
+	Dynamic library test. See also dlltest.c
+
+dll\mysetval.c
+	Dynamic library test. See also dlltest.c
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/accept.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/accept.c
new file mode 100644
index 0000000..f1bfde4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/accept.c
@@ -0,0 +1,519 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: accept.c
+**
+** Description: Run accept() sucessful connection tests.
+**
+** Modification History:
+** 04-Jun-97 AGarcia - Reconvert test file to return a 0 for PASS and a 1 for FAIL
+** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode 
+**             The debug mode will print all of the printfs associated with this test.
+**             The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**             have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**            recognize the return code from tha main program.
+** 12-June-97 Revert to return code 0 and 1.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+#include "nspr.h"
+#include "prpriv.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "plgetopt.h"
+#include "plerror.h"
+
+#define BASE_PORT 10000
+
+#define CLIENT_DATA        128
+
+#define ACCEPT_NORMAL        0x1
+#define ACCEPT_FAST        0x2
+#define ACCEPT_READ        0x3
+#define ACCEPT_READ_FAST    0x4
+#define ACCEPT_READ_FAST_CB    0x5
+
+#define CLIENT_NORMAL        0x1
+#define CLIENT_TIMEOUT_ACCEPT    0x2
+#define CLIENT_TIMEOUT_SEND    0x3
+
+#define SERVER_MAX_BIND_COUNT        100
+
+#if defined(XP_OS2) || defined(SYMBIAN)
+#define TIMEOUTSECS 10
+#else
+#define TIMEOUTSECS 2
+#endif
+PRIntervalTime timeoutTime;
+
+static PRInt32 count = 1;
+static PRFileDesc *output;
+static PRNetAddr serverAddr;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+static PRInt32 clientCommand;
+static PRInt32 iterations;
+static PRStatus rv;
+static PRFileDesc *listenSock;
+static PRFileDesc *clientSock = NULL;
+static PRNetAddr listenAddr;
+static PRNetAddr clientAddr;
+static PRThread *clientThread;
+static PRNetAddr *raddr;
+static char buf[4096 + 2*sizeof(PRNetAddr) + 32];
+static PRInt32 status;
+static PRInt32 bytesRead;
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+void Test_Assert(const char *msg, const char *file, PRIntn line)
+{
+    failed_already=1;
+    if (debug_mode) {
+        PR_fprintf(output,  "@%s:%d ", file, line);
+        PR_fprintf(output, msg);
+    }
+}  /* Test_Assert */
+
+#define TEST_ASSERT(expr) \
+    if (!(expr)) Test_Assert(#expr, __FILE__, __LINE__)
+
+#ifdef WINNT
+#define CALLBACK_MAGIC 0x12345678
+
+void timeout_callback(void *magic)
+{
+    TEST_ASSERT(magic == (void *)CALLBACK_MAGIC);
+    if (debug_mode)
+        PR_fprintf(output, "timeout callback called okay\n");
+}
+#endif
+
+
+static void PR_CALLBACK
+ClientThread(void *_action)
+{
+    PRInt32 action = * (PRInt32 *) _action;
+    PRInt32 iterations = count;
+    PRFileDesc *sock = NULL;
+
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = listenAddr.inet.port;
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    for (; iterations--;) {
+        PRInt32 rv;
+        char buf[CLIENT_DATA];
+
+        memset(buf, 0xaf, sizeof(buf)); /* initialize with arbitrary data */
+        sock = PR_NewTCPSocket();
+        if (!sock) {
+            if (!debug_mode)
+                failed_already=1;
+            else    
+                PR_fprintf(output, "client: unable to create socket\n");
+            return;
+        }
+
+        if (action != CLIENT_TIMEOUT_ACCEPT) {
+
+            if ((rv = PR_Connect(sock, &serverAddr,
+                timeoutTime)) < 0) {
+                if (!debug_mode)
+                    failed_already=1;
+                else    
+                    PR_fprintf(output, 
+                        "client: unable to connect to server (%ld, %ld, %ld, %ld)\n",
+                        iterations, rv, PR_GetError(), PR_GetOSError());
+                goto ErrorExit;
+            }
+
+            if (action != CLIENT_TIMEOUT_SEND) {
+                if ((rv = PR_Send(sock, buf, CLIENT_DATA,
+                    0, timeoutTime))< 0) {
+                    if (!debug_mode)
+                        failed_already=1;
+                    else    
+                        PR_fprintf(output, 
+                            "client: unable to send to server (%d, %ld, %ld)\n",
+                            CLIENT_DATA, rv, PR_GetError());
+                	goto ErrorExit;
+                }
+            } else {
+                PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1));
+            }
+        } else {
+            PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1));
+        }
+        if (debug_mode)
+            PR_fprintf(output, ".");
+        PR_Close(sock);
+		sock = NULL;
+    }
+    if (debug_mode)
+        PR_fprintf(output, "\n");
+
+ErrorExit:
+	if (sock != NULL)
+        PR_Close(sock);
+}
+
+
+static void 
+RunTest(PRInt32 acceptType, PRInt32 clientAction)
+{
+int i;
+
+    /* First bind to the socket */
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+        failed_already=1;
+        if (debug_mode)
+            PR_fprintf(output, "unable to create listen socket\n");
+        return;
+    }
+	memset(&listenAddr, 0 , sizeof(listenAddr));
+    listenAddr.inet.family = PR_AF_INET;
+    listenAddr.inet.port = PR_htons(BASE_PORT);
+    listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+    i = 0;
+    while (PR_Bind(listenSock, &listenAddr) == PR_FAILURE) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            listenAddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        failed_already=1;
+        if (debug_mode)
+        	PR_fprintf(output,"accept: ERROR - PR_Bind failed\n");
+		return;
+    }
+
+
+    rv = PR_Listen(listenSock, 100);
+    if (rv == PR_FAILURE) {
+        failed_already=1;
+        if (debug_mode)
+            PR_fprintf(output, "unable to listen\n");
+        return;
+    }
+
+    clientCommand = clientAction;
+    clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread,
+        (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope,
+        PR_JOINABLE_THREAD, 0);
+    if (!clientThread) {
+        failed_already=1;
+        if (debug_mode)
+            PR_fprintf(output, "error creating client thread\n");
+        return;
+    }
+
+    iterations = count;
+    for (;iterations--;) {
+        switch (acceptType) {
+        case ACCEPT_NORMAL:
+            clientSock = PR_Accept(listenSock, &clientAddr,
+                timeoutTime);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                TEST_ASSERT(clientSock == 0);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                bytesRead = PR_Recv(clientSock,
+                    buf,  CLIENT_DATA,  0,  timeoutTime);
+                TEST_ASSERT(bytesRead == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                TEST_ASSERT(clientSock);
+                bytesRead = PR_Recv(clientSock,
+                    buf,  CLIENT_DATA,  0,  timeoutTime);
+                TEST_ASSERT(bytesRead == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+        case ACCEPT_READ:
+            status = PR_AcceptRead(listenSock, &clientSock,
+                &raddr, buf, CLIENT_DATA, timeoutTime);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                /* Invalid test case */
+                TEST_ASSERT(0);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                TEST_ASSERT(status == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                TEST_ASSERT(status == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+#ifdef WINNT
+        case ACCEPT_FAST:
+            clientSock = PR_NTFast_Accept(listenSock,
+                &clientAddr, timeoutTime);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                TEST_ASSERT(clientSock == 0);
+                if (debug_mode)
+                    PR_fprintf(output, "PR_GetError is %ld\n", PR_GetError());
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                bytesRead = PR_Recv(clientSock,
+                    buf,  CLIENT_DATA,  0,  timeoutTime);
+                TEST_ASSERT(bytesRead == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                TEST_ASSERT(clientSock);
+                bytesRead = PR_Recv(clientSock,
+                    buf,  CLIENT_DATA,  0,  timeoutTime);
+                TEST_ASSERT(bytesRead == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+            break;
+        case ACCEPT_READ_FAST:
+            status = PR_NTFast_AcceptRead(listenSock,
+                &clientSock, &raddr, buf, 4096, timeoutTime);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                /* Invalid test case */
+                TEST_ASSERT(0);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                TEST_ASSERT(status == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                TEST_ASSERT(clientSock == NULL);
+                TEST_ASSERT(status == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+        case ACCEPT_READ_FAST_CB:
+            status = PR_NTFast_AcceptRead_WithTimeoutCallback(
+                listenSock, &clientSock, &raddr, buf, 4096,
+                timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                /* Invalid test case */
+                TEST_ASSERT(0);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                TEST_ASSERT(status == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                if (debug_mode)
+                    PR_fprintf(output, "clientSock = 0x%8.8lx\n", clientSock);
+                TEST_ASSERT(clientSock == NULL);
+                TEST_ASSERT(status == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+#endif
+        }
+        if (clientSock != NULL) {
+            PR_Close(clientSock);
+            clientSock = NULL;
+        }
+    }
+    PR_Close(listenSock);
+
+    PR_JoinThread(clientThread);
+}
+
+
+void AcceptUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_NORMAL, CLIENT_NORMAL); 
+}
+void AcceptNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_FAST, CLIENT_NORMAL); 
+}
+void AcceptReadTest(void)
+{ 
+    RunTest(ACCEPT_READ, CLIENT_NORMAL); 
+}
+void AcceptReadNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST, CLIENT_NORMAL); 
+}
+void AcceptReadCallbackTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST_CB, CLIENT_NORMAL); 
+}
+
+void TimeoutAcceptUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_ACCEPT); 
+}
+void TimeoutAcceptNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_ACCEPT); 
+}
+void TimeoutAcceptReadCallbackTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_ACCEPT); 
+}
+
+void TimeoutReadUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_SEND); 
+}
+void TimeoutReadNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_SEND); 
+}
+void TimeoutReadReadTest(void)
+{ 
+    RunTest(ACCEPT_READ, CLIENT_TIMEOUT_SEND); 
+}
+void TimeoutReadReadNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST, CLIENT_TIMEOUT_SEND); 
+}
+void TimeoutReadReadCallbackTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_SEND); 
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+    if (debug_mode)
+        PR_fprintf(output, "%40s: %6.2f usec\n", msg, d / count);
+
+}
+
+int main(int argc, char **argv)
+{
+
+    /* The command line argument: -d is used to determine if the test is being run
+    in debug mode. The regress tool requires only one line output:PASS or FAIL.
+    All of the printfs associated with this test has been handled with a if (debug_mode)
+    test.
+    Usage: test_name [-d] [-c n]
+    */
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "Gdc:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'd':  /* debug mode */
+            debug_mode = 1;
+            break;
+        case 'c':  /* loop counter */
+            count = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    output = PR_STDERR;
+    PR_STDIO_INIT();
+
+    timeoutTime = PR_SecondsToInterval(TIMEOUTSECS);
+    if (debug_mode)
+        PR_fprintf(output, "\nRun accept() sucessful connection tests\n");
+
+    Measure(AcceptUpdatedTest, "PR_Accept()");
+    Measure(AcceptReadTest, "PR_AcceptRead()");
+#ifdef WINNT
+    Measure(AcceptNotUpdatedTest, "PR_NTFast_Accept()");
+    Measure(AcceptReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
+    Measure(AcceptReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
+#endif
+    if (debug_mode)
+        PR_fprintf(output, "\nRun accept() timeout in the accept tests\n");
+#ifdef WINNT
+    Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
+#endif
+    Measure(TimeoutReadUpdatedTest, "PR_Accept()");
+    if (debug_mode)
+        PR_fprintf(output, "\nRun accept() timeout in the read tests\n");
+    Measure(TimeoutReadReadTest, "PR_AcceptRead()");
+#ifdef WINNT
+    Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()");
+    Measure(TimeoutReadReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
+    Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
+#endif
+    PR_fprintf(output, "%s\n", (failed_already) ? "FAIL" : "PASS");
+    return failed_already;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/acceptread.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/acceptread.c
new file mode 100644
index 0000000..bc42433
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/acceptread.c
@@ -0,0 +1,276 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <prio.h>
+#include <prprf.h>
+#include <prinit.h>
+#include <prnetdb.h>
+#include <prinrval.h>
+#include <prthread.h>
+
+#include <plerror.h>
+
+#include <stdlib.h>
+
+#define DEFAULT_PORT 12273
+#define GET "GET / HTTP/1.0\n\n"
+static PRFileDesc *std_out, *err_out;
+static PRIntervalTime write_dally, accept_timeout;
+
+static PRStatus PrintAddress(const PRNetAddr* address)
+{
+    char buffer[100];
+    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
+    if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString");
+    else PR_fprintf(
+        std_out, "Accepted connection from (0x%p)%s:%d\n",
+        address, buffer, address->inet.port);
+    return rv;
+}  /* PrintAddress */
+
+static void ConnectingThread(void *arg)
+{
+    PRInt32 nbytes;
+#ifdef SYMBIAN
+    char buf[256];
+#else
+    char buf[1024];
+#endif
+    PRFileDesc *sock;
+    PRNetAddr peer_addr, *addr;
+
+    addr = (PRNetAddr*)arg;
+
+    sock = PR_NewTCPSocket();
+    if (sock == NULL)
+    {
+        PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed");
+        PR_ProcessExit(1);
+    }
+
+    if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_Connect (client) failed");
+        PR_ProcessExit(1);
+    }
+    if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_GetPeerName (client) failed");
+        PR_ProcessExit(1);
+    }
+
+    /*
+    ** Then wait between the connection coming up and sending the expected
+    ** data. At some point in time, the server should fail due to a timeou
+    ** on the AcceptRead() operation, which according to the document is
+    ** only due to the read() portion.
+    */
+    PR_Sleep(write_dally);
+
+    nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed");
+
+    nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed");
+    else
+    {
+        PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes);
+        buf[sizeof(buf) - 1] = '\0';
+        PR_fprintf(std_out, "%s\n", buf);
+    }
+
+    if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH))
+        PL_FPrintError(err_out, "PR_Shutdown (client) failed");
+
+    if (PR_FAILURE == PR_Close(sock))
+        PL_FPrintError(err_out, "PR_Close (client) failed");
+
+    return;
+}  /* ConnectingThread */
+
+#define BUF_SIZE 117
+static void AcceptingThread(void *arg)
+{
+    PRStatus rv;
+    PRInt32 bytes;
+    PRSize buf_size = BUF_SIZE;
+    PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32];
+    PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg;
+    PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket();
+    PRSocketOptionData sock_opt;
+
+    if (NULL == listen_sock)
+    {
+        PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed");
+        PR_ProcessExit(1);        
+    }
+    sock_opt.option = PR_SockOpt_Reuseaddr;
+    sock_opt.value.reuse_addr = PR_TRUE;
+    rv = PR_SetSocketOption(listen_sock, &sock_opt);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_SetSocketOption (server) failed");
+        PR_ProcessExit(1);        
+    }
+    rv = PR_Bind(listen_sock, listen_addr);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_Bind (server) failed");
+        PR_ProcessExit(1);        
+    }
+    rv = PR_Listen(listen_sock, 10);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_Listen (server) failed");
+        PR_ProcessExit(1);        
+    }
+    bytes = PR_AcceptRead(
+        listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout);
+
+    if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed");
+    else
+    {
+        PrintAddress(accept_addr);
+        PR_fprintf(
+            std_out, "(Server) read [0x%p..0x%p) %s\n",
+            buf, &buf[BUF_SIZE], buf);
+        bytes = PR_Write(accept_sock, buf, bytes);
+        rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err_out, "PR_Shutdown (server) failed");
+    }
+
+    if (-1 != bytes)
+    {
+        rv = PR_Close(accept_sock);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err_out, "PR_Close (server) failed");
+    }
+
+    rv = PR_Close(listen_sock);
+    if (PR_FAILURE == rv)
+        PL_FPrintError(err_out, "PR_Close (server) failed");
+}  /* AcceptingThread */
+
+int main(int argc, char **argv)
+{
+    PRHostEnt he;
+    PRStatus status;
+    PRIntn next_index;
+    PRUint16 port_number;
+    char netdb_buf[PR_NETDB_BUF_SIZE];
+    PRNetAddr client_addr, server_addr;
+    PRThread *client_thread, *server_thread;
+    PRIntervalTime delta = PR_MillisecondsToInterval(500);
+
+    err_out = PR_STDERR;
+    std_out = PR_STDOUT;
+    accept_timeout = PR_SecondsToInterval(2);
+
+    if (argc != 2 && argc != 3) port_number = DEFAULT_PORT;
+    else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]);
+
+    status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr);
+    if (PR_SUCCESS != status)
+    {
+        PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
+        PR_ProcessExit(1);
+    }
+    if (argc < 3)
+    {
+        status = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, port_number, &client_addr);
+        if (PR_SUCCESS != status)
+        {
+            PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
+            PR_ProcessExit(1);
+        }
+    }
+    else
+    {
+        status = PR_GetHostByName(
+            argv[1], netdb_buf, sizeof(netdb_buf), &he);
+        if (status == PR_FAILURE)
+        {
+            PL_FPrintError(err_out, "PR_GetHostByName failed");
+            PR_ProcessExit(1);
+        }
+        next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr);
+        if (next_index == -1)
+        {
+            PL_FPrintError(err_out, "PR_EnumerateHostEnt failed");
+            PR_ProcessExit(1);
+        }
+    }
+
+    for (
+        write_dally = 0;
+        write_dally < accept_timeout + (2 * delta);
+        write_dally += delta)
+    {
+        PR_fprintf(
+            std_out, "Testing w/ write_dally = %d msec\n",
+            PR_IntervalToMilliseconds(write_dally));
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, AcceptingThread, &server_addr,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (server_thread == NULL)
+        {
+            PL_FPrintError(err_out, "PR_CreateThread (server) failed");
+            PR_ProcessExit(1);
+        }
+
+        PR_Sleep(delta);  /* let the server pot thicken */
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, ConnectingThread, &client_addr,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (client_thread == NULL)
+        {
+            PL_FPrintError(err_out, "PR_CreateThread (client) failed");
+            PR_ProcessExit(1);
+        }
+
+        if (PR_JoinThread(client_thread) == PR_FAILURE)
+            PL_FPrintError(err_out, "PR_JoinThread (client) failed");
+
+        if (PR_JoinThread(server_thread) == PR_FAILURE)
+            PL_FPrintError(err_out, "PR_JoinThread (server) failed");
+    }
+
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/acceptreademu.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/acceptreademu.c
new file mode 100644
index 0000000..1701aba
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/acceptreademu.c
@@ -0,0 +1,306 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This test is the same as acceptread.c except that it uses the
+ * emulated acceptread method instead of the regular acceptread.
+ */
+
+#include <prio.h>
+#include <prprf.h>
+#include <prinit.h>
+#include <prnetdb.h>
+#include <prinrval.h>
+#include <prthread.h>
+#include <pprio.h>
+
+#include <plerror.h>
+
+#include <stdlib.h>
+
+#define DEFAULT_PORT 12273
+#define GET "GET / HTTP/1.0\n\n"
+static PRFileDesc *std_out, *err_out;
+static PRIntervalTime write_dally, accept_timeout;
+static PRDescIdentity emu_layer_ident;
+static PRIOMethods emu_layer_methods;
+
+/* the acceptread method in emu_layer_methods */
+static PRInt32 PR_CALLBACK emu_AcceptRead(PRFileDesc *sd, PRFileDesc **nd,
+    PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+    return PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout);
+}
+
+static PRStatus PrintAddress(const PRNetAddr* address)
+{
+    char buffer[100];
+    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
+    if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString");
+    else PR_fprintf(
+        std_out, "Accepted connection from (0x%p)%s:%d\n",
+        address, buffer, address->inet.port);
+    return rv;
+}  /* PrintAddress */
+
+static void ConnectingThread(void *arg)
+{
+    PRInt32 nbytes;
+#ifdef SYMBIAN
+    char buf[256];
+#else
+    char buf[1024];
+#endif
+    PRFileDesc *sock;
+    PRNetAddr peer_addr, *addr;
+
+    addr = (PRNetAddr*)arg;
+
+    sock = PR_NewTCPSocket();
+    if (sock == NULL)
+    {
+        PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed");
+        PR_ProcessExit(1);
+    }
+
+    if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_Connect (client) failed");
+        PR_ProcessExit(1);
+    }
+    if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_GetPeerName (client) failed");
+        PR_ProcessExit(1);
+    }
+
+    /*
+    ** Then wait between the connection coming up and sending the expected
+    ** data. At some point in time, the server should fail due to a timeou
+    ** on the AcceptRead() operation, which according to the document is
+    ** only due to the read() portion.
+    */
+    PR_Sleep(write_dally);
+
+    nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed");
+
+    nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed");
+    else
+    {
+        PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes);
+        buf[sizeof(buf) - 1] = '\0';
+        PR_fprintf(std_out, "%s\n", buf);
+    }
+
+    if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH))
+        PL_FPrintError(err_out, "PR_Shutdown (client) failed");
+
+    if (PR_FAILURE == PR_Close(sock))
+        PL_FPrintError(err_out, "PR_Close (client) failed");
+
+    return;
+}  /* ConnectingThread */
+
+#define BUF_SIZE 117
+static void AcceptingThread(void *arg)
+{
+    PRStatus rv;
+    PRInt32 bytes;
+    PRSize buf_size = BUF_SIZE;
+    PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32];
+    PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg;
+    PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket();
+    PRFileDesc *layer;
+    PRSocketOptionData sock_opt;
+
+    if (NULL == listen_sock)
+    {
+        PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed");
+        PR_ProcessExit(1);        
+    }
+    layer = PR_CreateIOLayerStub(emu_layer_ident, &emu_layer_methods);
+    if (NULL == layer)
+    {
+        PL_FPrintError(err_out, "PR_CreateIOLayerStub (server) failed");
+        PR_ProcessExit(1);        
+    }
+    if (PR_PushIOLayer(listen_sock, PR_TOP_IO_LAYER, layer) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_PushIOLayer (server) failed");
+        PR_ProcessExit(1);        
+    }
+    sock_opt.option = PR_SockOpt_Reuseaddr;
+    sock_opt.value.reuse_addr = PR_TRUE;
+    rv = PR_SetSocketOption(listen_sock, &sock_opt);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_SetSocketOption (server) failed");
+        PR_ProcessExit(1);        
+    }
+    rv = PR_Bind(listen_sock, listen_addr);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_Bind (server) failed");
+        PR_ProcessExit(1);        
+    }
+    rv = PR_Listen(listen_sock, 10);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_Listen (server) failed");
+        PR_ProcessExit(1);        
+    }
+    bytes = PR_AcceptRead(
+        listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout);
+
+    if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed");
+    else
+    {
+        PrintAddress(accept_addr);
+        PR_fprintf(
+            std_out, "(Server) read [0x%p..0x%p) %s\n",
+            buf, &buf[BUF_SIZE], buf);
+        bytes = PR_Write(accept_sock, buf, bytes);
+        rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err_out, "PR_Shutdown (server) failed");
+    }
+
+    if (-1 != bytes)
+    {
+        rv = PR_Close(accept_sock);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err_out, "PR_Close (server) failed");
+    }
+
+    rv = PR_Close(listen_sock);
+    if (PR_FAILURE == rv)
+        PL_FPrintError(err_out, "PR_Close (server) failed");
+}  /* AcceptingThread */
+
+int main(int argc, char **argv)
+{
+    PRHostEnt he;
+    PRStatus status;
+    PRIntn next_index;
+    PRUint16 port_number;
+    char netdb_buf[PR_NETDB_BUF_SIZE];
+    PRNetAddr client_addr, server_addr;
+    PRThread *client_thread, *server_thread;
+    PRIntervalTime delta = PR_MillisecondsToInterval(500);
+
+    err_out = PR_STDERR;
+    std_out = PR_STDOUT;
+    accept_timeout = PR_SecondsToInterval(2);
+    emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead");
+    emu_layer_methods = *PR_GetDefaultIOMethods();
+    emu_layer_methods.acceptread = emu_AcceptRead;
+
+    if (argc != 2 && argc != 3) port_number = DEFAULT_PORT;
+    else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]);
+
+    status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr);
+    if (PR_SUCCESS != status)
+    {
+        PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
+        PR_ProcessExit(1);
+    }
+    if (argc < 3)
+    {
+        status = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, port_number, &client_addr);
+        if (PR_SUCCESS != status)
+        {
+            PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
+            PR_ProcessExit(1);
+        }
+    }
+    else
+    {
+        status = PR_GetHostByName(
+            argv[1], netdb_buf, sizeof(netdb_buf), &he);
+        if (status == PR_FAILURE)
+        {
+            PL_FPrintError(err_out, "PR_GetHostByName failed");
+            PR_ProcessExit(1);
+        }
+        next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr);
+        if (next_index == -1)
+        {
+            PL_FPrintError(err_out, "PR_EnumerateHostEnt failed");
+            PR_ProcessExit(1);
+        }
+    }
+
+    for (
+        write_dally = 0;
+        write_dally < accept_timeout + (2 * delta);
+        write_dally += delta)
+    {
+        PR_fprintf(
+            std_out, "Testing w/ write_dally = %d msec\n",
+            PR_IntervalToMilliseconds(write_dally));
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, AcceptingThread, &server_addr,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (server_thread == NULL)
+        {
+            PL_FPrintError(err_out, "PR_CreateThread (server) failed");
+            PR_ProcessExit(1);
+        }
+
+        PR_Sleep(delta);  /* let the server pot thicken */
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, ConnectingThread, &client_addr,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (client_thread == NULL)
+        {
+            PL_FPrintError(err_out, "PR_CreateThread (client) failed");
+            PR_ProcessExit(1);
+        }
+
+        if (PR_JoinThread(client_thread) == PR_FAILURE)
+            PL_FPrintError(err_out, "PR_JoinThread (client) failed");
+
+        if (PR_JoinThread(server_thread) == PR_FAILURE)
+            PL_FPrintError(err_out, "PR_JoinThread (server) failed");
+    }
+
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/addrstr.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/addrstr.c
new file mode 100644
index 0000000..532d75f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/addrstr.c
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+const char *testaddrs[] = {
+    "::", "::",
+    "::1", "::1",
+    "::ffff", "::ffff",
+    "::1:0", "::0.1.0.0",
+    "::127.0.0.1", "::127.0.0.1",
+    "::FFFF:127.0.0.1", "::ffff:127.0.0.1",
+    "::FFFE:9504:3501", "::fffe:9504:3501",
+    "0:0:1:0:35c:0:0:0", "0:0:1:0:35c::",
+    "0:0:3f4c:0:0:4552:0:0", "::3f4c:0:0:4552:0:0",
+    "0:0:1245:0:0:0:0567:0", "0:0:1245::567:0", 
+    "0:1:2:3:4:5:6:7", "0:1:2:3:4:5:6:7", 
+    "1:2:3:0:4:5:6:7", "1:2:3:0:4:5:6:7", 
+    "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:0", 
+    "1:2:3:4:5:6:7:8", "1:2:3:4:5:6:7:8", 
+    "1:2:3:4:5:6::7", "1:2:3:4:5:6:0:7", 
+    0
+};
+
+const char *badaddrs[] = {
+    "::.1.2.3",
+    "ffff::.1.2.3",
+    "1:2:3:4:5:6:7::8",
+    "1:2:3:4:5:6::7:8",
+    "::ff99.2.3.4",
+    0
+};
+
+int failed_already = 0;
+
+int main(int argc, char **argv)
+{
+    const char **nexttestaddr = testaddrs;
+    const char **nextbadaddr = badaddrs;
+    const char *in, *expected_out;
+    PRNetAddr addr;
+    char buf[256];
+    PRStatus rv;
+
+    while ((in = *nexttestaddr++) != 0) {
+	expected_out = *nexttestaddr++;
+	rv = PR_StringToNetAddr(in, &addr);
+	if (rv) {
+	    printf("cannot convert %s to addr: %d\n", in, rv);
+            failed_already = 1;
+	    continue;
+	}
+	rv = PR_NetAddrToString(&addr, buf, sizeof(buf));
+	if (rv) {
+	    printf("cannot convert %s back to string: %d\n", in, rv);
+            failed_already = 1;
+	    continue;
+	}
+	if (strcmp(buf, expected_out)) {
+            /* This is not necessarily an error */
+	    printf("%s expected %s got %s\n", in, expected_out, buf);
+	}
+    }
+    while ((in = *nextbadaddr++) != 0) {
+        if (PR_StringToNetAddr(in, &addr) == PR_SUCCESS) {
+            printf("converted bad addr %s\n", in);
+            failed_already = 1;
+        }
+    }
+    if (failed_already) {
+        printf("FAIL\n");
+        return 1;
+    }
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/affinity.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/affinity.c
new file mode 100644
index 0000000..46f159b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/affinity.c
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "pprthred.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef XP_BEOS
+
+/*
+ * Test PR_GetThreadAffinityMask
+ *		The function is called by each of local, global and global bound threads
+ *		The test should be run on both single and multi-cpu systems
+ */
+static void PR_CALLBACK thread_start(void *arg)
+{
+PRUint32 mask = 0;
+
+	if (PR_GetThreadAffinityMask(PR_GetCurrentThread(), &mask)) 
+		printf("\tthread_start: PR_GetCurrentThreadAffinityMask failed\n");
+	else
+		printf("\tthread_start: AffinityMask = 0x%x\n",mask);
+
+}
+
+int main(int argc, char **argv)
+{
+	PRThread *t;
+
+	printf("main: creating local thread\n");
+
+	t = PR_CreateThread(PR_USER_THREAD,
+				  thread_start, 0, 
+				  PR_PRIORITY_NORMAL,
+				  PR_LOCAL_THREAD,
+				  PR_JOINABLE_THREAD,
+				  0);
+
+	if (NULL == t) {
+		printf("main: cannot create local thread\n");
+		exit(1);
+	}
+
+	PR_JoinThread(t);
+
+	printf("main: creating global thread\n");
+	t = PR_CreateThread(PR_USER_THREAD,
+				  thread_start, 0, 
+				  PR_PRIORITY_NORMAL,
+				  PR_GLOBAL_THREAD,
+				  PR_JOINABLE_THREAD,
+				  0);
+
+	if (NULL == t) {
+		printf("main: cannot create global thread\n");
+		exit(1);
+	}
+
+	PR_JoinThread(t);
+
+	printf("main: creating global bound thread\n");
+	t = PR_CreateThread(PR_USER_THREAD,
+				  thread_start, 0, 
+				  PR_PRIORITY_NORMAL,
+				  PR_GLOBAL_BOUND_THREAD,
+				  PR_JOINABLE_THREAD,
+				  0);
+
+	if (NULL == t) {
+		printf("main: cannot create global bound thread\n");
+		exit(1);
+	}
+
+	PR_JoinThread(t);
+
+    return 0;
+}
+
+#else /* !XP_BEOS */
+
+int main()
+{
+	printf( "This test is not supported on the BeOS\n" );
+	return 0;
+}
+#endif /* !XP_BEOS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/alarm.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/alarm.c
new file mode 100644
index 0000000..7ae9d4f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/alarm.c
@@ -0,0 +1,551 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: alarmtst.c
+**
+** Description: Test alarms
+**
+** Modification History:
+** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+#include "prlog.h"
+#include "prinit.h"
+#include "obsolete/pralarm.h"
+#include "prlock.h"
+#include "prlong.h"
+#include "prcvar.h"
+#include "prinrval.h"
+#include "prtime.h"
+
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(XP_UNIX)
+#include <sys/time.h>
+#endif
+
+static PRIntn debug_mode;
+static PRIntn failed_already=0;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+typedef struct notifyData {
+    PRLock *ml;
+    PRCondVar *child;
+    PRCondVar *parent;
+    PRBool pending;
+    PRUint32 counter;
+} NotifyData;
+
+static void Notifier(void *arg)
+{
+    NotifyData *notifyData = (NotifyData*)arg;
+    PR_Lock(notifyData->ml);
+    while (notifyData->counter > 0)
+    {
+        while (!notifyData->pending)
+            PR_WaitCondVar(notifyData->child, PR_INTERVAL_NO_TIMEOUT);
+        notifyData->counter -= 1;
+        notifyData->pending = PR_FALSE;
+        PR_NotifyCondVar(notifyData->parent);
+    }
+    PR_Unlock(notifyData->ml);
+}  /* Notifier */
+/***********************************************************************
+** PRIVATE FUNCTION:    ConditionNotify
+** DESCRIPTION:
+** 
+** INPUTS:      loops
+** OUTPUTS:     None
+** RETURN:      overhead
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:
+**      
+***********************************************************************/
+
+
+static PRIntervalTime ConditionNotify(PRUint32 loops)
+{
+    PRThread *thread;
+    NotifyData notifyData;
+    PRIntervalTime timein, overhead;
+    
+    timein = PR_IntervalNow();
+
+    notifyData.counter = loops;
+    notifyData.ml = PR_NewLock();
+    notifyData.child = PR_NewCondVar(notifyData.ml);
+    notifyData.parent = PR_NewCondVar(notifyData.ml);
+    thread = PR_CreateThread(
+        PR_USER_THREAD, Notifier, &notifyData,
+        PR_GetThreadPriority(PR_GetCurrentThread()),
+        thread_scope, PR_JOINABLE_THREAD, 0);
+
+    overhead = PR_IntervalNow() - timein;  /* elapsed so far */
+
+    PR_Lock(notifyData.ml);
+    while (notifyData.counter > 0)
+    {
+        notifyData.pending = PR_TRUE;
+        PR_NotifyCondVar(notifyData.child);
+        while (notifyData.pending)
+            PR_WaitCondVar(notifyData.parent, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(notifyData.ml);
+
+    timein = PR_IntervalNow();
+
+    (void)PR_JoinThread(thread);
+    PR_DestroyCondVar(notifyData.child);
+    PR_DestroyCondVar(notifyData.parent);
+    PR_DestroyLock(notifyData.ml);
+    
+    overhead += (PR_IntervalNow() - timein);  /* more overhead */
+
+    return overhead;
+}  /* ConditionNotify */
+
+static PRIntervalTime ConditionTimeout(PRUint32 loops)
+{
+    PRUintn count;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+    PRIntervalTime interval = PR_MillisecondsToInterval(50);
+
+    overhead = PR_IntervalNow() - timein;
+
+    PR_Lock(ml);
+    for (count = 0; count < loops; ++count)
+    {
+        overhead += interval;
+        PR_ASSERT(PR_WaitCondVar(cv, interval) == PR_SUCCESS);
+    }
+    PR_Unlock(ml);
+
+    timein = PR_IntervalNow();
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    overhead += (PR_IntervalNow() - timein);
+
+    return overhead;
+}  /* ConditionTimeout */
+
+typedef struct AlarmData {
+    PRLock *ml;
+    PRCondVar *cv;
+    PRUint32 rate, late, times;
+    PRIntervalTime duration, timein, period;
+} AlarmData;
+
+static PRBool AlarmFn1(PRAlarmID *id, void *clientData, PRUint32 late)
+{
+    PRStatus rv = PR_SUCCESS;
+    PRBool keepGoing, resetAlarm;
+    PRIntervalTime interval, now = PR_IntervalNow();
+    AlarmData *ad = (AlarmData*)clientData;
+
+    PR_Lock(ad->ml);
+    ad->late += late;
+    ad->times += 1;
+    keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ?
+        PR_TRUE : PR_FALSE;
+    if (!keepGoing)
+        rv = PR_NotifyCondVar(ad->cv);
+    resetAlarm = ((ad->times % 31) == 0) ? PR_TRUE : PR_FALSE;
+                                         
+    interval = (ad->period + ad->rate - 1) / ad->rate;
+    if (!late && (interval > 10))
+    {
+        interval &= (now & 0x03) + 1;
+        PR_WaitCondVar(ad->cv, interval);
+    }
+          
+    PR_Unlock(ad->ml);
+
+    if (rv != PR_SUCCESS)
+    {
+		if (!debug_mode) failed_already=1;
+		else
+		 printf("AlarmFn: notify status: FAIL\n");
+		
+	}
+
+    if (resetAlarm)
+    {   
+        ad->rate += 3;
+        ad->late = ad->times = 0;
+        if (PR_ResetAlarm(id, ad->period, ad->rate) != PR_SUCCESS)
+        {
+			if (!debug_mode)
+				failed_already=1;
+			else		
+				printf("AlarmFn: Resetting alarm status: FAIL\n");
+
+            keepGoing = PR_FALSE;
+        }
+
+    }
+
+    return keepGoing;
+}  /* AlarmFn1 */
+
+static PRIntervalTime Alarms1(PRUint32 loops)
+{
+    PRAlarm *alarm;
+    AlarmData ad;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+    PRIntervalTime duration = PR_SecondsToInterval(3);
+
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+
+    ad.ml = ml;
+    ad.cv = cv;
+    ad.rate = 1;
+    ad.times = loops;
+    ad.late = ad.times = 0;
+    ad.duration = duration;
+    ad.timein = PR_IntervalNow();
+    ad.period = PR_SecondsToInterval(1);
+
+    alarm = PR_CreateAlarm();
+
+    (void)PR_SetAlarm(
+        alarm, ad.period, ad.rate, AlarmFn1, &ad);
+        
+    overhead = PR_IntervalNow() - timein;
+
+    PR_Lock(ml);
+    while ((PRIntervalTime)(PR_IntervalNow() - ad.timein) < duration)
+        PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+    PR_Unlock(ml);
+
+    timein = PR_IntervalNow();
+    (void)PR_DestroyAlarm(alarm);
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    overhead += (PR_IntervalNow() - timein);
+    
+    return duration + overhead;
+}  /* Alarms1 */
+
+static PRBool AlarmFn2(PRAlarmID *id, void *clientData, PRUint32 late)
+{
+    PRBool keepGoing;
+    PRStatus rv = PR_SUCCESS;
+    AlarmData *ad = (AlarmData*)clientData;
+    PRIntervalTime interval, now = PR_IntervalNow();
+
+    PR_Lock(ad->ml);
+    ad->times += 1;
+    keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ?
+        PR_TRUE : PR_FALSE;
+    interval = (ad->period + ad->rate - 1) / ad->rate;
+
+    if (!late && (interval > 10))
+    {
+        interval &= (now & 0x03) + 1;
+        PR_WaitCondVar(ad->cv, interval);
+    }
+
+    if (!keepGoing) rv = PR_NotifyCondVar(ad->cv);
+
+    PR_Unlock(ad->ml);
+
+
+    if (rv != PR_SUCCESS)
+		failed_already=1;;
+
+    return keepGoing;
+}  /* AlarmFn2 */
+
+static PRIntervalTime Alarms2(PRUint32 loops)
+{
+    PRStatus rv;
+    PRAlarm *alarm;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+    AlarmData ad;
+    PRIntervalTime duration = PR_SecondsToInterval(30);
+
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+
+    ad.ml = ml;
+    ad.cv = cv;
+    ad.rate = 1;
+    ad.times = loops;
+    ad.late = ad.times = 0;
+    ad.duration = duration;
+    ad.timein = PR_IntervalNow();
+    ad.period = PR_SecondsToInterval(1);
+
+    alarm = PR_CreateAlarm();
+
+    (void)PR_SetAlarm(
+        alarm, ad.period, ad.rate, AlarmFn2, &ad);
+        
+    overhead = PR_IntervalNow() - timein;
+
+    PR_Lock(ml);
+    while ((PRIntervalTime)(PR_IntervalNow() - ad.timein) < duration)
+        PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+    PR_Unlock(ml);
+    
+    timein = PR_IntervalNow();
+
+    rv = PR_DestroyAlarm(alarm);
+    if (rv != PR_SUCCESS)
+    {
+		if (!debug_mode)
+			failed_already=1;
+		else	
+			printf("***Destroying alarm status: FAIL\n");
+    }
+		
+
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    
+    overhead += (PR_IntervalNow() - timein);
+    
+    return duration + overhead;
+}  /* Alarms2 */
+
+static PRIntervalTime Alarms3(PRUint32 loops)
+{
+    PRIntn i;
+    PRStatus rv;
+    PRAlarm *alarm;
+    AlarmData ad[3];
+    PRIntervalTime duration = PR_SecondsToInterval(30);
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+
+    for (i = 0; i < 3; ++i)
+    {
+        ad[i].ml = ml;
+        ad[i].cv = cv;
+        ad[i].rate = 1;
+        ad[i].times = loops;
+        ad[i].duration = duration;
+        ad[i].late = ad[i].times = 0;
+        ad[i].timein = PR_IntervalNow();
+        ad[i].period = PR_SecondsToInterval(1);
+
+        /* more loops, faster rate => same elapsed time */
+        ad[i].times = (i + 1) * loops;
+        ad[i].rate = (i + 1) * 10;
+    }
+
+    alarm = PR_CreateAlarm();
+
+    for (i = 0; i < 3; ++i)
+    {
+        (void)PR_SetAlarm(
+            alarm, ad[i].period, ad[i].rate,
+            AlarmFn2, &ad[i]);
+    }
+        
+    overhead = PR_IntervalNow() - timein;
+
+    PR_Lock(ml);
+    for (i = 0; i < 3; ++i)
+    {
+        while ((PRIntervalTime)(PR_IntervalNow() - ad[i].timein) < duration)
+            PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(ml);
+
+    timein = PR_IntervalNow();
+
+	if (debug_mode)
+	printf
+        ("Alarms3 finished at %u, %u, %u\n",
+        ad[0].timein, ad[1].timein, ad[2].timein);
+    
+    rv = PR_DestroyAlarm(alarm);
+    if (rv != PR_SUCCESS)
+    {
+		if (!debug_mode)		
+			failed_already=1;
+		else	
+		   printf("***Destroying alarm status: FAIL\n");
+	}
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    
+    overhead += (duration / 3);
+    overhead += (PR_IntervalNow() - timein);
+
+    return overhead;
+}  /* Alarms3 */
+
+static PRUint32 TimeThis(
+    const char *msg, PRUint32 (*func)(PRUint32 loops), PRUint32 loops)
+{
+    PRUint32 overhead, usecs;
+    PRIntervalTime predicted, timein, timeout, ticks;
+
+ if (debug_mode)
+    printf("Testing %s ...", msg);
+
+    timein = PR_IntervalNow();
+    predicted = func(loops);
+    timeout = PR_IntervalNow();
+
+  if (debug_mode)
+    printf(" done\n");
+
+    ticks = timeout - timein;
+    usecs = PR_IntervalToMicroseconds(ticks);
+    overhead = PR_IntervalToMicroseconds(predicted);
+
+    if(ticks < predicted)
+    {
+		if (debug_mode) {
+        printf("\tFinished in negative time\n");
+        printf("\tpredicted overhead was %d usecs\n", overhead);
+        printf("\ttest completed in %d usecs\n\n", usecs);
+		}
+    }
+    else
+    {
+	if (debug_mode)		
+        printf(
+            "\ttotal: %d usecs\n\toverhead: %d usecs\n\tcost: %6.3f usecs\n\n",
+            usecs, overhead, ((double)(usecs - overhead) / (double)loops));
+    }
+
+    return overhead;
+}  /* TimeThis */
+
+int prmain(int argc, char** argv)
+{
+    PRUint32 cpu, cpus = 0, loops = 0;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name [-d]
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:c:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* GLOBAL threads */
+			thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'l':  /* loop count */
+			loops = atoi(opt->value);
+            break;
+        case 'c':  /* concurrency limit */
+			cpus = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+
+    if (cpus == 0) cpus = 1;
+    if (loops == 0) loops = 4;
+
+	if (debug_mode)
+		printf("Alarm: Using %d loops\n", loops);
+
+	if (debug_mode)		
+        printf("Alarm: Using %d cpu(s)\n", cpus);
+
+    for (cpu = 1; cpu <= cpus; ++cpu)
+    {
+    if (debug_mode)
+        printf("\nAlarm: Using %d CPU(s)\n", cpu);
+
+	PR_SetConcurrency(cpu);
+        
+        /* some basic time test */
+        (void)TimeThis("ConditionNotify", ConditionNotify, loops);
+        (void)TimeThis("ConditionTimeout", ConditionTimeout, loops);
+        (void)TimeThis("Alarms1", Alarms1, loops);
+        (void)TimeThis("Alarms2", Alarms2, loops);
+        (void)TimeThis("Alarms3", Alarms3, loops);
+    }
+    return 0;
+}
+
+int main(int argc, char** argv)
+{
+     PR_Initialize(prmain, argc, argv, 0);
+     PR_STDIO_INIT();
+	 if (failed_already) return 1;
+	 else return 0;
+
+}  /* main */
+
+
+/* alarmtst.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/anonfm.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/anonfm.c
new file mode 100644
index 0000000..2aa2415
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/anonfm.c
@@ -0,0 +1,343 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: anonfm.c
+** Description: Test anonymous file map 
+**
+** Synopsis: anonfm [options] [dirName]
+**
+** Options:
+** -d   enable debug mode
+** -h   display a help message
+** -s <n>  size of the anonymous memory map, in KBytes. default: 100KBytes.
+** -C 1 Operate this process as ClientOne() 
+** -C 2 Operate this process as ClientTwo()
+**
+** anonfn.c contains two tests, corresponding to the two protocols for
+** passing an anonymous file map to a child process.
+**
+** ServerOne()/ClientOne() tests the passing of "raw" file map; it uses
+** PR_CreateProcess() [for portability of the test case] to create the
+** child process, but does not use the PRProcessAttr structure for
+** passing the file map data.
+**
+** ServerTwo()/ClientTwo() tests the passing of the file map using the
+** PRProcessAttr structure.
+**
+*/
+#include <plgetopt.h> 
+#include <nspr.h> 
+#include <private/primpl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRUint32  failed_already = 0;
+
+PRIntn  debug = 0;
+PRIntn  client = 0; /* invoke client, style */
+char    dirName[512] = "."; /* directory name to contain anon mapped file */
+PRSize  fmSize = (100 * 1024 );
+PRUint32 fmMode = 0600;
+PRFileMapProtect fmProt = PR_PROT_READWRITE;
+const char *fmEnvName = "nsprFileMapEnvVariable";
+
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+    printf("anonfm [options] [dirName]\n");
+    printf("-d -- enable debug mode\n");
+    printf("dirName is alternate directory name. Default: . (current directory)\n");
+    exit(1);
+} /* end Help() */
+
+
+/*
+** ClientOne() --
+*/
+static void ClientOne( void )
+{
+    PRFileMap   *fm;
+    char        *fmString;
+    char        *addr;
+    PRStatus    rc;
+
+    PR_LOG(lm, msgLevel,
+        ("ClientOne() starting"));
+    
+    fmString = PR_GetEnv( fmEnvName );
+    if ( NULL == fmString ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+                ("ClientOne(): PR_Getenv() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_Getenv(): found: %s", fmString));
+
+    fm = PR_ImportFileMapFromString( fmString );
+    if ( NULL == fm ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+                ("ClientOne(): PR_ImportFileMapFromString() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_ImportFileMapFromString(): fm: %p", fm ));
+
+    addr = PR_MemMap( fm, LL_ZERO, fmSize );
+    if ( NULL == addr ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("ClientOne(): PR_MemMap() failed, OSError: %d", PR_GetOSError() ));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_MemMap(): addr: %p", addr ));
+
+    /* write to memory map to release server */
+    *addr = 1;
+
+    rc = PR_MemUnmap( addr, fmSize );
+    PR_ASSERT( rc == PR_SUCCESS );
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_MemUnap(): success" ));
+
+    rc = PR_CloseFileMap( fm );
+    if ( PR_FAILURE == rc ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("ClientOne(): PR_MemUnap() failed, OSError: %d", PR_GetOSError() ));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_CloseFileMap(): success" ));
+
+    return;
+} /* end ClientOne() */
+
+/*
+** ClientTwo() --
+*/
+static void ClientTwo( void )
+{
+    failed_already = 1;
+} /* end ClientTwo() */
+
+/*
+** ServerOne() --
+*/
+static void ServerOne( void )
+{
+    PRFileMap   *fm;
+    PRStatus    rc;
+    PRIntn      i;
+    char        *addr;
+    char        fmString[256];
+    char        envBuf[256];
+    char        *child_argv[8];
+    PRProcess   *proc;
+    PRInt32     exit_status;
+
+    PR_LOG(lm, msgLevel,
+        ("ServerOne() starting"));
+    
+    fm = PR_OpenAnonFileMap( dirName, fmSize, fmProt );
+    if ( NULL == fm )      {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+                ("PR_OpenAnonFileMap() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): FileMap: %p", fm ));
+    
+    rc = PR_ExportFileMapAsString( fm, sizeof(fmString), fmString );
+    if ( PR_FAILURE == rc )  {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("PR_ExportFileMap() failed"));
+        return;
+    }
+
+    /*
+    ** put the string into the environment
+    */
+    PR_snprintf( envBuf, sizeof(envBuf), "%s=%s", fmEnvName, fmString);
+    putenv( envBuf );
+    
+    addr = PR_MemMap( fm, LL_ZERO, fmSize );
+    if ( NULL == addr ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("PR_MemMap() failed"));
+        return;
+    }
+
+    /* set initial value for client */
+    for (i = 0; i < (PRIntn)fmSize ; i++ )
+        *(addr+i) = 0x00;  
+
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): PR_MemMap(): addr: %p", addr ));
+    
+    /*
+    ** set arguments for child process
+    */
+    child_argv[0] = "anonfm";
+    child_argv[1] = "-C";
+    child_argv[2] = "1";
+    child_argv[3] = NULL;
+
+    proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
+    PR_ASSERT( proc );
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): PR_CreateProcess(): proc: %x", proc ));
+
+    /*
+    ** ClientOne() will set the memory to 1
+    */
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): waiting on Client, *addr: %x", *addr ));
+    while( *addr == 0x00 ) {
+        if ( debug )
+            fprintf(stderr, ".");
+        PR_Sleep(PR_MillisecondsToInterval(300));
+    }
+    if ( debug )
+        fprintf(stderr, "\n");
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): Client responded" ));
+
+    rc = PR_WaitProcess( proc, &exit_status );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_MemUnmap( addr, fmSize);
+    if ( PR_FAILURE == rc ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("PR_MemUnmap() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): PR_MemUnmap(): success" ));
+
+    rc = PR_CloseFileMap(fm);
+    if ( PR_FAILURE == rc ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("PR_CloseFileMap() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): PR_CloseFileMap() success" ));
+
+    return;
+} /* end ServerOne() */
+
+/*
+** ServerTwo() --
+*/
+static void ServerTwo( void )
+{
+    PR_LOG(lm, msgLevel,
+        ("ServerTwo(): Not implemented yet" ));
+} /* end ServerTwo() */
+
+
+int main(int argc, char **argv)
+{
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "hdC:");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'C':  /* Client style */
+                client = atol(opt->value);
+                break;
+            case 's':  /* file size */
+                fmSize = atol( opt->value ) * 1024;
+                break;
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+            case 'h':  /* help message */
+			    Help();
+                break;
+             default:
+                strcpy(dirName, opt->value);
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+
+    if ( client == 1 ) {
+        ClientOne();
+    } else if ( client == 2 )  {
+        ClientTwo();
+    } else {
+        ServerOne();
+        if ( failed_already ) goto Finished;
+        ServerTwo();
+    }
+
+Finished:
+    if ( debug )
+        printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end anonfm.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/append.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/append.c
new file mode 100644
index 0000000..6a037b5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/append.c
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        append.c
+** Description: Testing File writes where PR_APPEND was used on open
+**
+** append attempts to verify that a file opened with PR_APPEND
+** will always append to the end of file, regardless where the
+** current file pointer is positioned. To do this, PR_Seek() is
+** called before each write with the position set to beginning of
+** file. Subsequent writes should always append.
+** The file is read back, summing the integer data written to the
+** file. If the expected result is equal, the test passes.
+**
+** See BugSplat: 4090
+*/
+#include "plgetopt.h"
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+PRIntn  debug = 0;
+PRIntn  verbose = 0;
+PRBool  failedAlready = PR_FALSE;
+const PRInt32 addedBytes = 1000;
+const PRInt32   buf = 1; /* constant written to fd, addedBytes times */
+PRInt32         inBuf;   /* read it back into here */
+
+int main(int argc, char **argv)
+{
+    PRStatus    rc;
+    PRInt32     rv;
+    PRFileDesc  *fd;
+    PRIntn      i;
+    PRInt32     sum = 0;
+
+    {   /* Get command line options */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "vd");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+                break;
+            case 'v':  /* verbose */
+                verbose = 1;
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    } /* end block "Get command line options" */
+/* ---------------------------------------------------------------------- */
+    fd = PR_Open( "/tmp/nsprAppend", (PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE | PR_WRONLY), 0666 );
+    if ( NULL == fd )  {
+        if (debug) printf("PR_Open() failed for writing: %d\n", PR_GetError());
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+
+    for ( i = 0; i < addedBytes ; i++ ) {
+        rv = PR_Write( fd, &buf, sizeof(buf));
+        if ( sizeof(buf) != rv )  {
+            if (debug) printf("PR_Write() failed: %d\n", PR_GetError());
+            failedAlready = PR_TRUE;
+            goto Finished;
+        }
+        rv = PR_Seek( fd, 0 , PR_SEEK_SET );
+        if ( -1 == rv )  {
+            if (debug) printf("PR_Seek() failed: %d\n", PR_GetError());
+            failedAlready = PR_TRUE;
+            goto Finished;
+        }
+    }
+    rc = PR_Close( fd );
+    if ( PR_FAILURE == rc ) {
+        if (debug) printf("PR_Close() failed after writing: %d\n", PR_GetError());
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+/* ---------------------------------------------------------------------- */
+    fd = PR_Open( "/tmp/nsprAppend", PR_RDONLY, 0 );
+    if ( NULL == fd )  {
+        if (debug) printf("PR_Open() failed for reading: %d\n", PR_GetError());
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+
+    for ( i = 0; i < addedBytes ; i++ ) {
+        rv = PR_Read( fd, &inBuf, sizeof(inBuf));
+        if ( sizeof(inBuf) != rv)  {
+            if (debug) printf("PR_Write() failed: %d\n", PR_GetError());
+            failedAlready = PR_TRUE;
+            goto Finished;
+        }
+        sum += inBuf;
+    }
+
+    rc = PR_Close( fd );
+    if ( PR_FAILURE == rc ) {
+        if (debug) printf("PR_Close() failed after reading: %d\n", PR_GetError());
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+    if ( sum != addedBytes )  {
+        if (debug) printf("Uh Oh! addedBytes: %d. Sum: %d\n", addedBytes, sum);
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+
+/* ---------------------------------------------------------------------- */
+Finished:
+    if (debug || verbose) printf("%s\n", (failedAlready)? "FAILED" : "PASSED" );
+    return( (failedAlready)? 1 : 0 );
+}  /* main() */
+
+/* append.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/atomic.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/atomic.c
new file mode 100644
index 0000000..f7e3fe3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/atomic.c
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ 
+#include "prio.h"
+#include "prprf.h"
+#include "pratom.h"
+
+/*
+ * TODO: create a macro to generate the six lines of code that are repeated
+ * for every test.  Also rewrite the statement
+ *     result = result | ((EXPRESSION) ? 0 : 1);
+ * as
+ *     result |= !(EXPRESSION);
+ */
+
+int main(int argc, char **argv)
+{
+    PRInt32 rv, oldval, test, result = 0;
+    PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput);
+
+    /***********************/
+    /* Test the functions. */
+    /***********************/
+
+    oldval = test = -2;
+    rv = PR_AtomicIncrement(&test);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicIncrement(%d) == %d: %s\n",
+        oldval, rv, (rv == -1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicIncrement(&test);
+    result = result | ((rv == 0) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicIncrement(%d) == %d: %s\n",
+        oldval, rv, (rv == 0) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicIncrement(&test);
+    result = result | ((rv == 1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicIncrement(%d) == %d: %s\n",
+        oldval, rv, (rv == 1) ? "PASSED" : "FAILED");
+
+    oldval = test = -2;
+    rv = PR_AtomicAdd(&test,1);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicAdd(%d,%d) == %d: %s\n",
+        oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicAdd(&test, 4);
+    result = result | ((rv == 3) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicAdd(%d,%d) == %d: %s\n",
+        oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicAdd(&test, -6);
+    result = result | ((rv == -3) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicAdd(%d,%d) == %d: %s\n",
+        oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED");
+
+    oldval = test = 2;
+    rv = PR_AtomicDecrement(&test);
+    result = result | ((rv == 1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicDecrement(%d) == %d: %s\n",
+        oldval, rv, (rv == 1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicDecrement(&test);
+    result = result | ((rv == 0) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicDecrement(%d) == %d: %s\n",
+        oldval, rv, (rv == 0) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicDecrement(&test);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicDecrement(%d) == %d: %s\n",
+        oldval, rv, (rv == -1) ? "PASSED" : "FAILED");
+
+    /* set to a different value */
+    oldval = test = -2;
+    rv = PR_AtomicSet(&test, 2);
+    result = result | (((rv == -2) && (test == 2)) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicSet(%d, %d) == %d: %s\n",
+        oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED");
+
+    /* set to the same value */
+    oldval = test = -2;
+    rv = PR_AtomicSet(&test, -2);
+    result = result | (((rv == -2) && (test == -2)) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicSet(%d, %d) == %d: %s\n",
+        oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED");
+
+    /***********************/
+    /* Test the macros.    */
+    /***********************/
+
+    oldval = test = -2;
+    rv = PR_ATOMIC_INCREMENT(&test);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n",
+        oldval, rv, (rv == -1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_ATOMIC_INCREMENT(&test);
+    result = result | ((rv == 0) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n",
+        oldval, rv, (rv == 0) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_ATOMIC_INCREMENT(&test);
+    result = result | ((rv == 1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n",
+        oldval, rv, (rv == 1) ? "PASSED" : "FAILED");
+
+    oldval = test = -2;
+    rv = PR_ATOMIC_ADD(&test,1);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n",
+        oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_ATOMIC_ADD(&test, 4);
+    result = result | ((rv == 3) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n",
+        oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_ATOMIC_ADD(&test, -6);
+    result = result | ((rv == -3) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n",
+        oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED");
+
+    oldval = test = 2;
+    rv = PR_ATOMIC_DECREMENT(&test);
+    result = result | ((rv == 1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n",
+        oldval, rv, (rv == 1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_ATOMIC_DECREMENT(&test);
+    result = result | ((rv == 0) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n",
+        oldval, rv, (rv == 0) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_ATOMIC_DECREMENT(&test);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n",
+        oldval, rv, (rv == -1) ? "PASSED" : "FAILED");
+
+    /* set to a different value */
+    oldval = test = -2;
+    rv = PR_ATOMIC_SET(&test, 2);
+    result = result | (((rv == -2) && (test == 2)) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_SET(%d, %d) == %d: %s\n",
+        oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED");
+
+    /* set to the same value */
+    oldval = test = -2;
+    rv = PR_ATOMIC_SET(&test, -2);
+    result = result | (((rv == -2) && (test == -2)) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_ATOMIC_SET(%d, %d) == %d: %s\n",
+        oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED");
+
+    PR_fprintf(
+        output, "Atomic operations test %s\n",
+        (result == 0) ? "PASSED" : "FAILED");
+    return result;
+}  /* main */
+
+/* atomic.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/attach.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/attach.c
new file mode 100644
index 0000000..2eaefdc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/attach.c
@@ -0,0 +1,387 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: attach.c
+**
+** Description: Platform-specific code to create a native thread. The native thread will
+**                            repeatedly call PR_AttachThread and PR_DetachThread. The
+**                            primordial thread waits for this new thread to finish.
+**
+** Modification History:
+** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+** 12-June-97 Revert to return code 0 and 1.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+/* Used to get the command line option */
+#include "nspr.h"
+#include "pprthred.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#ifdef WIN32
+#include <windows.h>
+#include <process.h>
+#elif defined(_PR_PTHREADS)
+#include <pthread.h>
+#include "md/_pth.h"
+#elif defined(IRIX)
+#include <sys/types.h>
+#include <sys/prctl.h>
+#include <sys/wait.h>
+#include <errno.h>
+#elif defined(SOLARIS)
+#include <thread.h>
+#elif defined(OS2)
+#define INCL_DOS
+#define INCL_ERRORS
+#include <os2.h>
+#include <process.h>
+#elif defined(XP_BEOS)
+#include <kernel/OS.h>
+#endif
+
+#define DEFAULT_COUNT 1000
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+int count;
+
+
+static void 
+AttachDetach(void)
+{
+    PRThread *me;
+    PRInt32 index;
+
+    for (index=0;index<count; index++) {
+        me = PR_AttachThread(PR_USER_THREAD, 
+                             PR_PRIORITY_NORMAL,
+                             NULL);
+ 
+        if (!me) {
+            fprintf(stderr, "Error attaching thread %d: PR_AttachThread failed\n",
+		    count);
+	    	failed_already = 1;
+	    	return;
+        }
+        PR_DetachThread();
+    }
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+	if (debug_mode)
+    printf("%40s: %6.2f usec\n", msg, d / count);
+}
+
+#ifdef WIN32
+static unsigned __stdcall threadStartFunc(void *arg)
+#elif defined(IRIX) && !defined(_PR_PTHREADS)
+static void threadStartFunc(void *arg)
+#elif defined(XP_BEOS)
+static int32 threadStartFunc(void *arg)
+#else
+static void * threadStartFunc(void *arg)
+#endif
+{
+#ifdef _PR_DCETHREADS
+    {
+        int rv;
+        pthread_t self = pthread_self();
+        rv = pthread_detach(&self);
+        if (debug_mode) PR_ASSERT(0 == rv);
+		else if (0 != rv) failed_already=1;
+    }
+#endif
+
+    Measure(AttachDetach, "Attach/Detach");
+
+#ifndef IRIX
+    return 0;
+#endif
+}
+
+int main(int argc, char **argv)
+{
+#ifdef _PR_PTHREADS
+    int rv;
+    pthread_t threadID;
+    pthread_attr_t attr;
+#elif defined(SOLARIS)
+    int rv;
+    thread_t threadID;
+#elif defined(WIN32)
+    DWORD rv;
+    unsigned threadID;
+    HANDLE hThread;
+#elif defined(IRIX)
+    int rv;
+    int threadID;
+#elif defined(OS2)
+    int rv;
+    TID threadID;
+#elif defined(XP_BEOS)
+	thread_id threadID;
+	int32 threadRV;
+	status_t waitRV;
+#endif
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name [-d] [-c n]
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'c':  /* loop count */
+			count = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+#if defined(WIN16)
+    printf("attach: This test is not valid for Win16\n");
+    goto exit_now;
+#endif
+
+	if(0 == count) count = DEFAULT_COUNT;	
+
+    /*
+     * To force the implicit initialization of nspr20
+     */
+    PR_SetError(0, 0);
+    PR_STDIO_INIT();
+
+    /*
+     * Platform-specific code to create a native thread.  The native
+     * thread will repeatedly call PR_AttachThread and PR_DetachThread.
+     * The primordial thread waits for this new thread to finish.
+     */
+
+#ifdef _PR_PTHREADS
+
+    rv = _PT_PTHREAD_ATTR_INIT(&attr);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv) {
+		failed_already=1;
+		goto exit_now;
+	}
+	
+#ifndef _PR_DCETHREADS
+    rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv) {
+		failed_already=1;
+		goto exit_now;
+	}
+#endif  /* !_PR_DCETHREADS */
+    rv = _PT_PTHREAD_CREATE(&threadID, attr, threadStartFunc, NULL);
+    if (rv != 0) {
+			fprintf(stderr, "thread creation failed: error code %d\n", rv);
+			failed_already=1;
+			goto exit_now;
+	}
+	else {
+		if (debug_mode)
+			printf ("thread creation succeeded \n");
+
+	}
+    rv = _PT_PTHREAD_ATTR_DESTROY(&attr);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv) {
+		failed_already=1;
+		goto exit_now;
+	}
+    rv = pthread_join(threadID, NULL);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv) {
+		failed_already=1;
+		goto exit_now;
+	}
+
+#elif defined(SOLARIS)
+
+    rv = thr_create(NULL, 0, threadStartFunc, NULL, 0, &threadID);
+    if (rv != 0) {
+	if(!debug_mode) {
+		failed_already=1;
+		goto exit_now;
+	} else	
+		fprintf(stderr, "thread creation failed: error code %d\n", rv);
+    }
+    rv = thr_join(threadID, NULL, NULL);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv)
+	{
+		failed_already=1;
+		goto exit_now;
+	}
+
+
+#elif defined(WIN32)
+
+    hThread = (HANDLE) _beginthreadex(NULL, 0, threadStartFunc, NULL,
+            0, &threadID); 
+    if (hThread == 0) {
+        fprintf(stderr, "thread creation failed: error code %d\n",
+                GetLastError());
+		failed_already=1;
+		goto exit_now;
+    }
+    rv = WaitForSingleObject(hThread, INFINITE);
+    if (debug_mode)PR_ASSERT(rv != WAIT_FAILED);
+	else if (rv == WAIT_FAILED) {
+		failed_already=1;
+		goto exit_now;
+	}
+
+#elif defined(IRIX)
+
+    threadID = sproc(threadStartFunc, PR_SALL, NULL);
+    if (threadID == -1) {
+
+			fprintf(stderr, "thread creation failed: error code %d\n",
+					errno);
+			failed_already=1;
+			goto exit_now;
+	
+	}
+	else {
+		if (debug_mode) 
+			printf ("thread creation succeeded \n");
+		sleep(3);
+		goto exit_now;
+	}
+    rv = waitpid(threadID, NULL, 0);
+    if (debug_mode) PR_ASSERT(rv != -1);
+	else  if (rv != -1) {
+		failed_already=1;
+		goto exit_now;
+	}
+
+#elif defined(OS2)
+
+    threadID = (TID) _beginthread((void *)threadStartFunc, NULL,
+            32768, NULL); 
+    if (threadID == -1) {
+        fprintf(stderr, "thread creation failed: error code %d\n", errno);
+        failed_already=1;
+        goto exit_now;
+    }
+    rv = DosWaitThread(&threadID, DCWW_WAIT);
+    if (debug_mode) {
+        PR_ASSERT(rv == NO_ERROR);
+    } else if (rv != NO_ERROR) {
+        failed_already=1;
+        goto exit_now;
+    }
+
+#elif defined(XP_BEOS)
+	
+	threadID = spawn_thread(threadStartFunc, NULL, B_NORMAL_PRIORITY, NULL);
+	if (threadID <= B_ERROR) {
+		fprintf(stderr, "thread creation failed: error code %08lx\n", threadID);
+		failed_already = 1;
+		goto exit_now;
+	}
+	if (resume_thread(threadID) != B_OK) {
+		fprintf(stderr, "failed starting thread: error code %08lx\n", threadID);
+		failed_already = 1;
+		goto exit_now;
+	}
+
+	waitRV = wait_for_thread(threadID, &threadRV);
+	if (debug_mode)
+		PR_ASSERT(waitRV == B_OK);
+	else if (waitRV != B_OK) {
+		failed_already = 1;
+		goto exit_now;
+	}
+	
+#else
+	if (!debug_mode)
+		failed_already=1;
+	else	
+		printf("The attach test does not apply to this platform because\n"
+	    "either this platform does not have native threads or the\n"
+	    "test needs to be written for this platform.\n");
+	goto exit_now;
+#endif
+
+exit_now:
+   if(failed_already)	
+		return 1;
+	else
+		return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile.c
new file mode 100644
index 0000000..9c7d323
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile.c
@@ -0,0 +1,323 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prinit.h"
+#include "prerror.h"
+#include "prthread.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#define DEFAULT_COUNT 10
+#define DEFAULT_FILESIZE 1
+#define BUFFER_SIZE 1000000
+
+typedef enum {v_silent, v_whisper, v_shout} Verbosity;
+static void Verbose(Verbosity, const char*, const char*, PRIntn);
+
+#define VERBOSE(_l, _m) Verbose(_l, _m, __FILE__, __LINE__)
+
+static PRIntn test_result = 2;
+static PRFileDesc *output = NULL;
+static PRIntn verbose = v_silent;
+static PRIntn filesize = DEFAULT_FILESIZE;
+
+static PRIntn Usage(void)
+{
+    PR_fprintf(output, "Bigfile test usage:\n");
+    PR_fprintf(output, ">bigfile [-G] [-d] [-v[*v]] [-s <n>] <filename>\n");
+    PR_fprintf(output, "\td\tdebug mode (equivalent to -vvv)\t(false)\n");
+    PR_fprintf(output, "\tv\tAdditional levels of output\t(none)\n");
+    PR_fprintf(output, "\tk\tKeep data file after exit\t(false)\n");
+    PR_fprintf(output, "\ts <n>\tFile size in megabytes\t\t(1 megabyte)\n");
+    PR_fprintf(output, "\t<filename>\tName of test file\t(none)\n");
+    return 2;  /* nothing happened */
+}  /* Usage */
+
+static PRStatus DeleteIfFound(const char *filename)
+{
+    PRStatus rv;
+    VERBOSE(v_shout, "Checking for existing file");
+    rv = PR_Access(filename, PR_ACCESS_WRITE_OK);
+    if (PR_SUCCESS == rv)
+    {
+        VERBOSE(v_shout, "Deleting existing file");
+        rv = PR_Delete(filename);
+        if (PR_FAILURE == rv) VERBOSE(v_shout, "Cannot delete big file");
+    }
+    else if (PR_FILE_NOT_FOUND_ERROR !=  PR_GetError())
+        VERBOSE(v_shout, "Cannot access big file");
+    else rv = PR_SUCCESS;
+    return rv;
+}  /* DeleteIfFound */
+
+static PRIntn Error(const char *msg, const char *filename)
+{
+    PRInt32 error = PR_GetError();
+    if (NULL != msg)
+    {
+        if (0 == error) PR_fprintf(output, msg);
+        else PL_FPrintError(output, msg);
+    }
+    (void)DeleteIfFound(filename);
+    if (v_shout == verbose) PR_Abort();
+    return 1;
+}  /* Error */
+
+static void Verbose(
+    Verbosity level, const char *msg, const char *file, PRIntn line)
+{
+    if (level <= verbose)
+        PR_fprintf(output, "[%s : %d]: %s\n", file, line, msg);
+}  /* Verbose */
+
+static void PrintInfo(PRFileInfo64 *info, const char *filename)
+{
+    PRExplodedTime tm;
+    char ctime[40], mtime[40];
+    static const char *types[] = {"FILE", "DIRECTORY", "OTHER"};
+    PR_fprintf(
+        output, "[%s : %d]: File info for %s\n",
+        __FILE__, __LINE__, filename);
+    PR_fprintf(
+        output, "    type: %s, size: %llu bytes,\n",
+        types[info->type - 1], info->size);
+
+    PR_ExplodeTime(info->creationTime, PR_GMTParameters, &tm);
+    (void)PR_FormatTime(ctime, sizeof(ctime), "%c GMT", &tm);
+    PR_ExplodeTime(info->modifyTime, PR_GMTParameters, &tm);
+    (void)PR_FormatTime(mtime, sizeof(mtime), "%c GMT", &tm);
+
+    PR_fprintf(
+        output, "    creation: %s,\n    modify: %s\n", ctime, mtime);
+}  /* PrintInfo */
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+    char *buffer;
+    PLOptStatus os;
+    PRInt32 loop, bytes;
+    PRFileInfo small_info;
+    PRFileInfo64 big_info;
+    PRBool keep = PR_FALSE;
+    PRFileDesc *file = NULL;
+    const char *filename = NULL;
+    PRIntn count = DEFAULT_COUNT;
+    PRInt64 filesize64, big_answer, big_size, one_meg, zero_meg, big_fragment;
+    PRInt64 sevenFox = LL_INIT(0,0x7fffffff);
+
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dtvhs:");
+
+    output = PR_GetSpecialFD(PR_StandardError);
+    PR_STDIO_INIT();
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            filename = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            verbose = v_shout;
+            break;
+        case 'k':  /* keep file */
+            keep = PR_TRUE;
+            break;
+        case 'v':  /* verbosity */
+            if (v_shout > verbose) verbose += 1;
+            break;
+        case 'c':  /* loop counter */
+            count = atoi(opt->value);
+            break;
+        case 's':  /* filesize */
+            filesize = atoi(opt->value);
+            break;
+        case 'h':  /* confused */
+        default:
+            return Usage();
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (0 == count) count = DEFAULT_COUNT;
+    if (0 == filesize) filesize = DEFAULT_FILESIZE;
+    if (NULL == filename)
+    {
+#ifdef SYMBIAN
+#define FILE_NAME "c:\\data\\bigfile.dat"
+#else
+#define FILE_NAME "bigfile.dat"
+#endif
+        if (DEFAULT_FILESIZE != filesize) return Usage();
+        else filename = FILE_NAME;
+    }
+
+    if (PR_FAILURE == DeleteIfFound(filename)) return 1;
+
+    test_result = 0;
+
+    LL_I2L(zero_meg, 0);
+    LL_I2L(one_meg, 1000000);
+    LL_I2L(filesize64, filesize);
+    buffer = (char*)PR_MALLOC(BUFFER_SIZE);
+    LL_I2L(big_fragment, BUFFER_SIZE);
+    LL_MUL(filesize64, filesize64, one_meg); 
+
+    for (loop = 0; loop < BUFFER_SIZE; ++loop) buffer[loop] = (char)loop;
+
+    VERBOSE(v_whisper, "Creating big file");
+    file = PR_Open(filename, PR_CREATE_FILE | PR_WRONLY, 0666);
+    if (NULL == file) return Error("PR_Open()", filename);
+    
+    VERBOSE(v_whisper, "Testing available space in empty file");
+    big_answer = file->methods->available64(file);
+    if (!LL_IS_ZERO(big_answer)) return Error("empty available64()", filename);
+
+	LL_SUB(big_size, filesize64, one_meg);
+    VERBOSE(v_whisper, "Creating sparse big file by seeking to end");
+	big_answer = file->methods->seek64(file, big_size, PR_SEEK_SET);
+    if (!LL_EQ(big_answer, big_size)) return Error("seek", filename);
+
+    VERBOSE(v_whisper, "Writing block at end of sparse file");
+	bytes = file->methods->write(file, buffer, BUFFER_SIZE);
+    if (bytes != BUFFER_SIZE) return Error("write", filename);
+
+    VERBOSE(v_whisper, "Testing available space at end of sparse file");
+    big_answer = file->methods->available64(file);
+    if (!LL_IS_ZERO(big_answer)) return Error("eof available64()", filename);
+
+    VERBOSE(v_whisper, "Getting big info on sparse big file");
+    rv = file->methods->fileInfo64(file, &big_info);
+    if (PR_FAILURE == rv) return Error("fileInfo64()", filename);
+    if (v_shout <= verbose) PrintInfo(&big_info, filename);
+
+    VERBOSE(v_whisper, "Getting small info on sparse big file");
+    rv = file->methods->fileInfo(file, &small_info);
+    if (LL_CMP(sevenFox, <, filesize64) && (PR_SUCCESS == rv))
+    {
+        VERBOSE(v_whisper, "Should have failed and didn't");
+        return Error("fileInfo()", filename);
+    }
+    else if (LL_CMP(sevenFox, >, filesize64) && (PR_FAILURE == rv))
+    {
+        VERBOSE(v_whisper, "Should have succeeded and didn't");
+        return Error("fileInfo()", filename);
+    }
+
+    VERBOSE(v_whisper, "Rewinding big file");
+    big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_SET);
+    if (!LL_IS_ZERO(big_answer)) return Error("rewind seek64()", filename);
+
+    VERBOSE(v_whisper, "Establishing available space in rewound file");
+    big_answer = file->methods->available64(file);
+    if (LL_NE(filesize64, big_answer))
+        return Error("bof available64()", filename);
+
+    VERBOSE(v_whisper, "Closing big file");
+    rv = file->methods->close(file);
+    if (PR_FAILURE == rv) return Error("close()", filename);
+
+    VERBOSE(v_whisper, "Reopening big file");
+    file = PR_Open(filename, PR_RDWR, 0666);
+    if (NULL == file) return Error("open failed", filename);
+
+    VERBOSE(v_whisper, "Checking available data in reopened file");
+    big_answer = file->methods->available64(file);
+    if (LL_NE(filesize64, big_answer))
+        return Error("reopened available64()", filename);
+
+    big_answer = zero_meg;
+    VERBOSE(v_whisper, "Rewriting every byte of big file data");
+    do
+    {
+        bytes = file->methods->write(file, buffer, BUFFER_SIZE);
+        if (bytes != BUFFER_SIZE)
+            return Error("write", filename);
+        LL_ADD(big_answer, big_answer, big_fragment);
+    } while (LL_CMP(big_answer, <, filesize64));
+
+    VERBOSE(v_whisper, "Checking position at eof");
+    big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_CUR);
+    if (LL_NE(big_answer, filesize64))
+        return Error("file size error", filename);
+
+    VERBOSE(v_whisper, "Testing available space at eof");
+    big_answer = file->methods->available64(file);
+    if (!LL_IS_ZERO(big_answer))
+        return Error("eof available64()", filename);
+
+    VERBOSE(v_whisper, "Rewinding full file");
+    big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_SET);
+    if (!LL_IS_ZERO(big_answer)) return Error("bof seek64()", filename);
+
+    VERBOSE(v_whisper, "Testing available space in rewound file");
+    big_answer = file->methods->available64(file);
+    if (LL_NE(big_answer, filesize64)) return Error("bof available64()", filename);
+
+    VERBOSE(v_whisper, "Seeking to end of big file");
+    big_answer = file->methods->seek64(file, filesize64, PR_SEEK_SET);
+    if (LL_NE(big_answer, filesize64)) return Error("eof seek64()", filename);
+
+    VERBOSE(v_whisper, "Getting info on big file while it's open");
+    rv = file->methods->fileInfo64(file, &big_info);
+    if (PR_FAILURE == rv) return Error("fileInfo64()", filename);
+    if (v_shout <= verbose) PrintInfo(&big_info, filename);
+
+    VERBOSE(v_whisper, "Closing big file");
+    rv = file->methods->close(file);
+    if (PR_FAILURE == rv) return Error("close()", filename);
+
+    VERBOSE(v_whisper, "Getting info on big file after it's closed");
+    rv = PR_GetFileInfo64(filename, &big_info);
+    if (PR_FAILURE == rv) return Error("fileInfo64()", filename);
+    if (v_shout <= verbose) PrintInfo(&big_info, filename);
+
+    VERBOSE(v_whisper, "Deleting big file");
+    rv = PR_Delete(filename);
+    if (PR_FAILURE == rv) return Error("PR_Delete()", filename);
+
+    PR_DELETE(buffer);
+    return test_result;
+} /* main */
+
+/* bigfile.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile2.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile2.c
new file mode 100644
index 0000000..2b538e2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile2.c
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define TEST_FILE_NAME "bigfile2.txt"
+#ifdef WINCE
+#define TEST_FILE_NAME_FOR_CREATEFILE   L"bigfile2.txt"
+#else
+#define TEST_FILE_NAME_FOR_CREATEFILE   TEST_FILE_NAME
+#endif
+
+#define MESSAGE "Hello world!"
+#define MESSAGE_SIZE 13
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *fd;
+    PRInt64 offset, position;
+    PRInt32 nbytes;
+    char buf[MESSAGE_SIZE];
+#ifdef _WIN32
+    HANDLE hFile;
+    LARGE_INTEGER li;
+#endif /* _WIN32 */
+
+    LL_I2L(offset, 1);
+    LL_SHL(offset, offset, 32);
+
+    fd = PR_Open(TEST_FILE_NAME,
+            PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0666);
+    if (fd == NULL) {
+        fprintf(stderr, "PR_Open failed\n");
+        exit(1);
+    }
+    position = PR_Seek64(fd, offset, PR_SEEK_SET);
+    if (!LL_GE_ZERO(position)) {
+        fprintf(stderr, "PR_Seek64 failed\n");
+        exit(1);
+    }
+    PR_ASSERT(LL_EQ(position, offset));
+    strcpy(buf, MESSAGE);
+    nbytes = PR_Write(fd, buf, sizeof(buf));
+    if (nbytes != sizeof(buf)) {
+        fprintf(stderr, "PR_Write failed\n");
+        exit(1);
+    }
+    if (PR_Close(fd) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    memset(buf, 0, sizeof(buf));
+
+#ifdef _WIN32
+    hFile = CreateFile(TEST_FILE_NAME_FOR_CREATEFILE, GENERIC_READ, 0, NULL,
+            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (hFile == INVALID_HANDLE_VALUE) {
+        fprintf(stderr, "CreateFile failed\n");
+        exit(1);
+    }
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+    if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+        fprintf(stderr, "SetFilePointer failed\n");
+        exit(1);
+    }
+    PR_ASSERT(li.QuadPart == offset);
+    if (ReadFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) {
+        fprintf(stderr, "ReadFile failed\n");
+        exit(1);
+    }
+    PR_ASSERT(nbytes == sizeof(buf));
+    if (strcmp(buf, MESSAGE)) {
+        fprintf(stderr, "corrupt data:$%s$\n", buf);
+        exit(1);
+    }
+    if (CloseHandle(hFile) == 0) {
+        fprintf(stderr, "CloseHandle failed\n");
+        exit(1);
+    }
+#endif /* _WIN32 */
+
+    if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_Delete failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile3.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile3.c
new file mode 100644
index 0000000..be04d5e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/bigfile3.c
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define TEST_FILE_NAME "bigfile3.txt"
+#ifdef WINCE
+#define TEST_FILE_NAME_FOR_CREATEFILE   L"bigfile3.txt"
+#else
+#define TEST_FILE_NAME_FOR_CREATEFILE   TEST_FILE_NAME
+#endif
+
+#define MESSAGE "Hello world!"
+#define MESSAGE_SIZE 13
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *fd;
+    PRInt64 offset, position;
+    PRInt32 nbytes;
+    char buf[MESSAGE_SIZE];
+#ifdef _WIN32
+    HANDLE hFile;
+    LARGE_INTEGER li;
+#endif /* _WIN32 */
+
+    LL_I2L(offset, 1);
+    LL_SHL(offset, offset, 32);
+
+#ifdef _WIN32
+    hFile = CreateFile(TEST_FILE_NAME_FOR_CREATEFILE, GENERIC_WRITE, 0, NULL,
+            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (hFile == INVALID_HANDLE_VALUE) {
+        fprintf(stderr, "CreateFile failed\n");
+        exit(1);
+    }
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+    if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+        fprintf(stderr, "SetFilePointer failed\n");
+        exit(1);
+    }
+    PR_ASSERT(li.QuadPart == offset);
+    strcpy(buf, MESSAGE);
+    if (WriteFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) {
+        fprintf(stderr, "WriteFile failed\n");
+        exit(1);
+    }
+    PR_ASSERT(nbytes == sizeof(buf));
+    if (CloseHandle(hFile) == 0) {
+        fprintf(stderr, "CloseHandle failed\n");
+        exit(1);
+    }
+#endif /* _WIN32 */
+
+    memset(buf, 0, sizeof(buf));
+
+    fd = PR_Open(TEST_FILE_NAME, PR_RDONLY, 0666);
+    if (fd == NULL) {
+        fprintf(stderr, "PR_Open failed\n");
+        exit(1);
+    }
+    position = PR_Seek64(fd, offset, PR_SEEK_SET);
+    if (!LL_GE_ZERO(position)) {
+        fprintf(stderr, "PR_Seek64 failed\n");
+        exit(1);
+    }
+    PR_ASSERT(LL_EQ(position, offset));
+    nbytes = PR_Read(fd, buf, sizeof(buf));
+    if (nbytes != sizeof(buf)) {
+        fprintf(stderr, "PR_Read failed\n");
+        exit(1);
+    }
+    if (strcmp(buf, MESSAGE)) {
+        fprintf(stderr, "corrupt data:$%s$\n", buf);
+        exit(1);
+    }
+    if (PR_Close(fd) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_Delete failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/bug1test.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/bug1test.c
new file mode 100644
index 0000000..6c4c4d8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/bug1test.c
@@ -0,0 +1,257 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+Attached is a test program that uses the nspr1 to demonstrate a bug
+under NT4.0. The fix has already been mentioned (add a ResetEvent just
+before leaving the critical section in _PR_CondWait in hwmon.c).
+*/
+
+#include "prthread.h"
+#include "prtypes.h"
+#include "prinit.h"
+#include "prmon.h"
+#include "prlog.h"
+
+typedef struct Arg_s
+{
+	PRInt32 a, b;
+} Arg_t;
+
+PRMonitor*  gMonitor;       // the monitor
+PRInt32     gReading;       // number of read locks
+PRInt32     gWriteWaiting;  // number of threads waiting for write lock
+PRInt32     gReadWaiting;   // number of threads waiting for read lock
+
+PRInt32     gCounter;       // a counter
+
+                            // stats
+PRInt32     gReads;         // number of successful reads
+PRInt32     gMaxReads;      // max number of simultaneous reads
+PRInt32     gMaxWriteWaits; // max number of writes that waited for read
+PRInt32     gMaxReadWaits;  // max number of reads that waited for write wait
+
+
+void spin (PRInt32 aDelay)
+{
+  PRInt32 index;
+  PRInt32 delay = aDelay * 1000;
+
+  PR_Sleep(0);
+
+  // randomize delay a bit
+  delay = (delay / 2) + (PRInt32)((float)delay *
+	  ((float)rand () / (float)RAND_MAX));
+
+  for (index = 0; index < delay * 10; index++)
+	  // consume a bunch of cpu cycles
+    ;
+  PR_Sleep(0); 
+}
+
+void  doWriteThread (void* arg)
+{
+  PRInt32 last;
+  Arg_t *args = (Arg_t*)arg;
+  PRInt32 aWorkDelay = args->a, aWaitDelay = args->b;
+  PR_Sleep(0);
+
+  while (1)
+  {
+    // -- enter write lock
+    PR_EnterMonitor (gMonitor);
+
+    if (0 < gReading)     // wait for read locks to go away
+    {
+      PRIntervalTime fiveSecs = PR_SecondsToInterval(5);
+
+      gWriteWaiting++;
+      if (gWriteWaiting > gMaxWriteWaits) // stats
+        gMaxWriteWaits = gWriteWaiting;
+      while (0 < gReading)
+        PR_Wait (gMonitor, fiveSecs);
+      gWriteWaiting--;
+    }
+    // -- write lock entered
+
+    last = gCounter;
+    gCounter++;
+
+    spin (aWorkDelay);
+
+    PR_ASSERT (gCounter == (last + 1)); // test invariance
+
+    // -- exit write lock        
+//    if (0 < gReadWaiting)   // notify waiting reads (do it anyway to show off the CondWait bug)
+      PR_NotifyAll (gMonitor);
+
+    PR_ExitMonitor (gMonitor);
+    // -- write lock exited
+
+    spin (aWaitDelay);
+  }
+}
+
+void  doReadThread (void* arg)
+{
+  PRInt32 last;
+  Arg_t *args = (Arg_t*)arg;
+  PRInt32 aWorkDelay = args->a, aWaitDelay = args->b;
+  PR_Sleep(0);
+
+  while (1)
+  {
+    // -- enter read lock
+    PR_EnterMonitor (gMonitor); 
+
+    if (0 < gWriteWaiting)  // give up the monitor to waiting writes
+    {
+      PRIntervalTime fiveSecs = PR_SecondsToInterval(5);
+
+      gReadWaiting++;
+      if (gReadWaiting > gMaxReadWaits) // stats
+        gMaxReadWaits = gReadWaiting;
+      while (0 < gWriteWaiting)
+        PR_Wait (gMonitor, fiveSecs);
+      gReadWaiting--;
+    }
+
+    gReading++;
+
+    gReads++;   // stats
+    if (gReading > gMaxReads) // stats
+      gMaxReads = gReading;
+
+    PR_ExitMonitor (gMonitor);
+    // -- read lock entered
+
+    last = gCounter;
+
+    spin (aWorkDelay);
+
+    PR_ASSERT (gCounter == last); // test invariance
+
+    // -- exit read lock
+    PR_EnterMonitor (gMonitor);  // read unlock
+    gReading--;
+
+//    if ((0 == gReading) && (0 < gWriteWaiting))  // notify waiting writes  (do it anyway to show off the CondWait bug)
+      PR_NotifyAll (gMonitor);
+    PR_ExitMonitor (gMonitor);
+    // -- read lock exited
+
+    spin (aWaitDelay);
+  }
+}
+
+
+void fireThread (
+    char* aName, void (*aProc)(void *arg), Arg_t *aArg)
+{
+  PRThread *thread = PR_CreateThread(
+	  PR_USER_THREAD, aProc, aArg, PR_PRIORITY_NORMAL,
+	  PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+}
+
+int pseudoMain (int argc, char** argv, char *pad)
+{
+  PRInt32 lastWriteCount  = gCounter;
+  PRInt32 lastReadCount   = gReads;
+  Arg_t a1 = {500, 250};
+  Arg_t a2 = {500, 500};
+  Arg_t a3 = {250, 500};
+  Arg_t a4 = {750, 250};
+  Arg_t a5 = {100, 750};
+  Arg_t a6 = {100, 500};
+  Arg_t a7 = {100, 750};
+
+  gMonitor = PR_NewMonitor ();
+
+  fireThread ("R1", doReadThread,   &a1);
+  fireThread ("R2", doReadThread,   &a2);
+  fireThread ("R3", doReadThread,   &a3);
+  fireThread ("R4", doReadThread,   &a4);
+
+  fireThread ("W1", doWriteThread,  &a5);
+  fireThread ("W2", doWriteThread,  &a6);
+  fireThread ("W3", doWriteThread,  &a7);
+
+  fireThread ("R5", doReadThread,   &a1);
+  fireThread ("R6", doReadThread,   &a2);
+  fireThread ("R7", doReadThread,   &a3);
+  fireThread ("R8", doReadThread,   &a4);
+
+  fireThread ("W4", doWriteThread,  &a5);
+  fireThread ("W5", doWriteThread,  &a6);
+  fireThread ("W6", doWriteThread,  &a7);
+  
+  while (1)
+  {
+	PRInt32 writeCount, readCount;
+    PRIntervalTime fiveSecs = PR_SecondsToInterval(5);
+    PR_Sleep (fiveSecs);  // get out of the way
+
+    // print some stats, not threadsafe, informative only
+    writeCount = gCounter;
+    readCount   = gReads;
+    printf ("\ntick %d writes (+%d), %d reads (+%d) [max %d, %d, %d]", 
+            writeCount, writeCount - lastWriteCount,
+            readCount, readCount - lastReadCount, 
+            gMaxReads, gMaxWriteWaits, gMaxReadWaits);
+    lastWriteCount = writeCount;
+    lastReadCount = readCount;
+    gMaxReads = gMaxWriteWaits = gMaxReadWaits = 0;
+  }
+  return 0;
+}
+
+
+static void padStack (int argc, char** argv)
+{
+  char pad[512];      /* Work around bug in nspr on windoze */
+  pseudoMain (argc, argv, pad);
+}
+
+int main(int argc, char **argv)
+{
+  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+  PR_STDIO_INIT();
+  padStack (argc, argv);
+}
+
+
+/* bug1test.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/cleanup.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/cleanup.c
new file mode 100644
index 0000000..38f9b94
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/cleanup.c
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prprf.h"
+#include "prio.h"
+#include "prinit.h"
+#include "prthread.h"
+#include "prinrval.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+static void PR_CALLBACK Thread(void *sleep)
+{
+    PR_Sleep(PR_SecondsToInterval((PRUint32)sleep));
+    printf("Thread exiting\n");
+}
+
+static void Help(void)
+{
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PR_fprintf(err, "Cleanup usage: [-g] [-s n] [-t n] [-c n] [-h]\n");
+    PR_fprintf(err, "\t-c   Call cleanup before exiting     (default: false)\n");
+    PR_fprintf(err, "\t-G   Use global threads only         (default: local)\n");
+    PR_fprintf(err, "\t-t n Number of threads involved      (default: 1)\n");
+    PR_fprintf(err, "\t-s n Seconds thread(s) should dally  (defaut: 10)\n");
+    PR_fprintf(err, "\t-S n Seconds main() should dally     (defaut: 5)\n");
+    PR_fprintf(err, "\t-C n Value to set concurrency        (default 1)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    PRBool cleanup = PR_FALSE;
+	PRThreadScope type = PR_LOCAL_THREAD;
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PLOptState *opt = PL_CreateOptState(argc, argv, "Ghs:S:t:cC:");
+    PRIntn concurrency = 1, child_sleep = 10, main_sleep = 5, threads = 1;
+
+    PR_STDIO_INIT();
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'c':  /* call PR_Cleanup() before exiting */
+            cleanup = PR_TRUE;
+            break;
+        case 'G':  /* local vs global threads */
+            type = PR_GLOBAL_THREAD;
+            break;
+        case 's':  /* time to sleep */
+            child_sleep = atoi(opt->value);
+            break;
+        case 'S':  /* time to sleep */
+            main_sleep = atoi(opt->value);
+            break;
+        case 'C':  /* number of cpus to create */
+            concurrency = atoi(opt->value);
+            break;
+        case 't':  /* number of threads to create */
+            threads = atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_fprintf(err, "Cleanup settings\n");
+    PR_fprintf(err, "\tThread type: %s\n",
+        (PR_LOCAL_THREAD == type) ? "LOCAL" : "GLOBAL");
+    PR_fprintf(err, "\tConcurrency: %d\n", concurrency);
+    PR_fprintf(err, "\tNumber of threads: %d\n", threads);
+    PR_fprintf(err, "\tThread sleep: %d\n", child_sleep);
+    PR_fprintf(err, "\tMain sleep: %d\n", main_sleep); 
+    PR_fprintf(err, "\tCleanup will %sbe called\n\n", (cleanup) ? "" : "NOT "); 
+
+    PR_SetConcurrency(concurrency);
+
+	while (threads-- > 0)
+		(void)PR_CreateThread(
+        	PR_USER_THREAD, Thread, (void*)child_sleep, PR_PRIORITY_NORMAL,
+       		type, PR_UNJOINABLE_THREAD, 0);
+    PR_Sleep(PR_SecondsToInterval(main_sleep));
+
+    if (cleanup) PR_Cleanup();
+
+    PR_fprintf(err, "main() exiting\n");
+    return 0;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/cltsrv.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/cltsrv.c
new file mode 100644
index 0000000..33553aa
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/cltsrv.c
@@ -0,0 +1,1214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *
+ * Notes:
+ * [1] lth. The call to Sleep() is a hack to get the test case to run
+ * on Windows 95. Without it, the test case fails with an error
+ * WSAECONNRESET following a recv() call. The error is caused by the
+ * server side thread termination without a shutdown() or closesocket()
+ * call. Windows docmunentation suggests that this is predicted
+ * behavior; that other platforms get away with it is ... serindipity.
+ * The test case should shutdown() or closesocket() before
+ * thread termination. I didn't have time to figure out where or how
+ * to do it. The Sleep() call inserts enough delay to allow the
+ * client side to recv() all his data before the server side thread
+ * terminates. Whew! ...
+ *
+ ** Modification History:
+ * 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+ *             The debug mode will print all of the printfs associated with this test.
+ *             The regress mode will be the default mode. Since the regress tool limits
+ *           the output to a one line status:PASS or FAIL,all of the printf statements
+ *             have been handled with an if (debug_mode) statement. 
+ */
+
+#include "prclist.h"
+#include "prcvar.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prtime.h"
+#include "prmem.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prthread.h"
+
+#include "pprio.h"
+#include "primpl.h"
+
+#include "plstr.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(XP_UNIX)
+#include <math.h>
+#endif
+
+/*
+** This is the beginning of the test
+*/
+
+#define RECV_FLAGS 0
+#define SEND_FLAGS 0
+#define DEFAULT_LOW 0
+#define DEFAULT_HIGH 0
+#define BUFFER_SIZE 1024
+#define DEFAULT_BACKLOG 5
+#define DEFAULT_PORT 12849
+#define DEFAULT_CLIENTS 1
+#define ALLOWED_IN_ACCEPT 1
+#define DEFAULT_CLIPPING 1000
+#define DEFAULT_WORKERS_MIN 1
+#define DEFAULT_WORKERS_MAX 1
+#define DEFAULT_SERVER "localhost"
+#define DEFAULT_EXECUTION_TIME 10
+#define DEFAULT_CLIENT_TIMEOUT 4000
+#define DEFAULT_SERVER_TIMEOUT 4000
+#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGH
+
+typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t;
+
+static void PR_CALLBACK Worker(void *arg);
+typedef struct CSPool_s CSPool_t;
+typedef struct CSWorker_s CSWorker_t;
+typedef struct CSServer_s CSServer_t;
+typedef enum Verbosity
+{
+    TEST_LOG_ALWAYS,
+    TEST_LOG_ERROR,
+    TEST_LOG_WARNING,
+    TEST_LOG_NOTICE,
+    TEST_LOG_INFO,
+    TEST_LOG_STATUS,
+    TEST_LOG_VERBOSE
+} Verbosity;
+
+static PRInt32 domain = AF_INET;
+static PRInt32 protocol = 6;  /* TCP */
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE;
+static PRBool pthread_stats = PR_FALSE;
+static Verbosity verbosity = TEST_LOG_ALWAYS;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+struct CSWorker_s
+{
+    PRCList element;        /* list of the server's workers */
+
+    PRThread *thread;       /* this worker objects thread */
+    CSServer_t *server;     /* back pointer to server structure */
+};
+
+struct CSPool_s
+{
+    PRCondVar *exiting;
+    PRCondVar *acceptComplete;
+    PRUint32 accepting, active, workers;
+};
+
+struct CSServer_s
+{
+    PRCList list;           /* head of worker list */
+
+    PRLock *ml;
+    PRThread *thread;       /* the main server thread */
+    PRCondVar *stateChange;
+
+    PRUint16 port;          /* port we're listening on */
+    PRUint32 backlog;       /* size of our listener backlog */
+    PRFileDesc *listener;   /* the fd accepting connections */
+
+    CSPool_t pool;          /* statistics on worker threads */
+    CSState_t state;        /* the server's state */
+    struct                  /* controlling worker counts */
+    {
+        PRUint32 minimum, maximum, accepting;
+    } workers;
+
+    /* statistics */
+    PRIntervalTime started, stopped;
+    PRUint32 operations, bytesTransferred;
+};
+
+typedef struct CSDescriptor_s
+{
+    PRInt32 size;       /* size of transfer */
+    char filename[60];  /* filename, null padded */
+} CSDescriptor_t;
+
+typedef struct CSClient_s
+{
+    PRLock *ml;
+    PRThread *thread;
+    PRCondVar *stateChange;
+    PRNetAddr serverAddress;
+
+    CSState_t state;
+
+    /* statistics */
+    PRIntervalTime started, stopped;
+    PRUint32 operations, bytesTransferred;
+} CSClient_t;
+
+#define TEST_LOG(l, p, a) \
+    do { \
+        if (debug_mode || (p <= verbosity)) printf a; \
+    } while (0)
+
+PRLogModuleInfo *cltsrv_log_file = NULL;
+
+#define MY_ASSERT(_expr) \
+    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))
+
+#define TEST_ASSERT(_expr) \
+    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))
+
+static void _MY_Assert(const char *s, const char *file, PRIntn ln)
+{
+    PL_PrintError(NULL);
+    PR_Assert(s, file, ln);
+}  /* _MY_Assert */
+
+static PRBool Aborted(PRStatus rv)
+{
+    return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ?
+        PR_TRUE : PR_FALSE;
+}
+
+static void TimeOfDayMessage(const char *msg, PRThread* me)
+{
+    char buffer[100];
+    PRExplodedTime tod;
+    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod);
+    (void)PR_FormatTime(buffer, sizeof(buffer), "%H:%M:%S", &tod);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("%s(0x%p): %s\n", msg, me, buffer));
+}  /* TimeOfDayMessage */
+
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRIntn index;
+    char buffer[1024];
+    PRFileDesc *fd = NULL;
+    PRUintn clipping = DEFAULT_CLIPPING;
+    PRThread *me = PR_GetCurrentThread();
+    CSClient_t *client = (CSClient_t*)arg;
+    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
+    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT);
+
+
+    for (index = 0; index < sizeof(buffer); ++index)
+        buffer[index] = (char)index;
+
+    client->started = PR_IntervalNow();
+
+    PR_Lock(client->ml);
+    client->state = cs_run;
+    PR_NotifyCondVar(client->stateChange);
+    PR_Unlock(client->ml);
+
+    TimeOfDayMessage("Client started at", me);
+
+    while (cs_run == client->state)
+    {
+        PRInt32 bytes, descbytes, filebytes, netbytes;
+
+        (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer));
+        TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, 
+            ("\tClient(0x%p): connecting to server at %s\n", me, buffer));
+
+        fd = PR_Socket(domain, SOCK_STREAM, protocol);
+        TEST_ASSERT(NULL != fd);
+        rv = PR_Connect(fd, &client->serverAddress, timeout);
+        if (PR_FAILURE == rv)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tClient(0x%p): conection failed (%d, %d)\n",
+                me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+
+        memset(descriptor, 0, sizeof(*descriptor));
+        descriptor->size = PR_htonl(descbytes = rand() % clipping);
+        PR_snprintf(
+            descriptor->filename, sizeof(descriptor->filename),
+            "CS%p%p-%p.dat", client->started, me, client->operations);
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes));
+        bytes = PR_Send(
+            fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout);
+        if (sizeof(CSDescriptor_t) != bytes)
+        {
+            if (Aborted(PR_FAILURE)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\tClient(0x%p): send descriptor timeout\n", me));
+                goto retry;
+            }
+        }
+        TEST_ASSERT(sizeof(*descriptor) == bytes);
+
+        netbytes = 0;
+        while (netbytes < descbytes)
+        {
+            filebytes = sizeof(buffer);
+            if ((descbytes - netbytes) < filebytes)
+                filebytes = descbytes - netbytes;
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\tClient(0x%p): sending %d bytes\n", me, filebytes));
+            bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
+            if (filebytes != bytes)
+            {
+                if (Aborted(PR_FAILURE)) goto aborted;
+                if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                {
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): send data timeout\n", me));
+                    goto retry;
+                }
+            }
+            TEST_ASSERT(bytes == filebytes);
+            netbytes += bytes;
+        }
+        filebytes = 0;
+        while (filebytes < descbytes)
+        {
+            netbytes = sizeof(buffer);
+            if ((descbytes - filebytes) < netbytes)
+                netbytes = descbytes - filebytes;
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\tClient(0x%p): receiving %d bytes\n", me, netbytes));
+            bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
+            if (-1 == bytes)
+            {
+                if (Aborted(PR_FAILURE))
+                {
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive data aborted\n", me));
+                    goto aborted;
+                }
+                else if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive data timeout\n", me));
+				else
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive error (%d, %d)\n",
+						me, PR_GetError(), PR_GetOSError()));
+                goto retry;
+           }
+            if (0 == bytes)
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tClient(0x%p): unexpected end of stream\n",
+                    PR_GetCurrentThread()));
+                break;
+            }
+            filebytes += bytes;
+        }
+
+        rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+        if (Aborted(rv)) goto aborted;
+        TEST_ASSERT(PR_SUCCESS == rv);
+retry:
+        (void)PR_Close(fd); fd = NULL;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_INFO,
+            ("\tClient(0x%p): disconnected from server\n", me));
+
+        PR_Lock(client->ml);
+        client->operations += 1;
+        client->bytesTransferred += 2 * descbytes;
+        rv = PR_WaitCondVar(client->stateChange, rand() % clipping);
+        PR_Unlock(client->ml);
+        if (Aborted(rv)) break;
+    }
+
+aborted:
+    client->stopped = PR_IntervalNow();
+
+    PR_ClearInterrupt();
+    if (NULL != fd) rv = PR_Close(fd);
+
+    PR_Lock(client->ml);
+    client->state = cs_exit;
+    PR_NotifyCondVar(client->stateChange);
+    PR_Unlock(client->ml);
+    PR_DELETE(descriptor);
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("\tClient(0x%p): stopped after %u operations and %u bytes\n",
+        PR_GetCurrentThread(), client->operations, client->bytesTransferred));
+
+}  /* Client */
+
+static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
+{
+    PRStatus drv, rv;
+    char buffer[1024];
+    PRFileDesc *file = NULL;
+    PRThread * me = PR_GetCurrentThread();
+    PRInt32 bytes, descbytes, netbytes, filebytes = 0;
+    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
+    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\tProcessRequest(0x%p): receiving desciptor\n", me));
+    bytes = PR_Recv(
+        fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout);
+    if (-1 == bytes)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto exit;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tProcessRequest(0x%p): receive timeout\n", me));
+        }
+        goto exit;
+    }
+    if (0 == bytes)
+    {
+        rv = PR_FAILURE;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_ERROR,
+            ("\tProcessRequest(0x%p): unexpected end of file\n", me));
+        goto exit;
+    }
+    descbytes = PR_ntohl(descriptor->size);
+    TEST_ASSERT(sizeof(*descriptor) == bytes);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE, 
+        ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n",
+        me, descbytes, descriptor->filename));
+
+    file = PR_Open(
+        descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666);
+    if (NULL == file)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto aborted;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tProcessRequest(0x%p): open file timeout\n", me));
+            goto aborted;
+        }
+    }
+    TEST_ASSERT(NULL != file);
+
+    filebytes = 0;
+    while (filebytes < descbytes)
+    {
+        netbytes = sizeof(buffer);
+        if ((descbytes - filebytes) < netbytes)
+            netbytes = descbytes - filebytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes));
+        bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
+        if (-1 == bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): receive data timeout\n", me));
+                goto aborted;
+            }
+            /*
+             * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED)
+             * on NT here.  This is equivalent to ECONNRESET on Unix.
+             *     -wtc
+             */
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_WARNING,
+                ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n",
+                me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+        if(0 == bytes)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_WARNING,
+                ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me));
+            rv = PR_FAILURE;
+            goto aborted;
+        }
+        filebytes += bytes;
+        netbytes = bytes;
+        /* The byte count for PR_Write should be positive */
+        MY_ASSERT(netbytes > 0);
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes));
+        bytes = PR_Write(file, buffer, netbytes);
+        if (netbytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): write file timeout\n", me));
+                goto aborted;
+            }
+        }
+        TEST_ASSERT(bytes > 0);
+    }
+
+    PR_Lock(server->ml);
+    server->operations += 1;
+    server->bytesTransferred += filebytes;
+    PR_Unlock(server->ml);
+
+    rv = PR_Close(file);
+    if (Aborted(rv)) goto aborted;
+    TEST_ASSERT(PR_SUCCESS == rv);
+    file = NULL;
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename));
+    file = PR_Open(descriptor->filename, PR_RDONLY, 0);
+    if (NULL == file)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto aborted;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\t\tProcessRequest(0x%p): open file timeout\n",
+                PR_GetCurrentThread()));
+            goto aborted;
+        }
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_ERROR,
+            ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n",
+            me, PR_GetError(), PR_GetOSError()));
+        goto aborted;
+    }
+    TEST_ASSERT(NULL != file);
+
+    netbytes = 0;
+    while (netbytes < descbytes)
+    {
+        filebytes = sizeof(buffer);
+        if ((descbytes - netbytes) < filebytes)
+            filebytes = descbytes - netbytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes));
+        bytes = PR_Read(file, buffer, filebytes);
+        if (filebytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): read file timeout\n", me));
+            else
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n",
+                    me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+        TEST_ASSERT(bytes > 0);
+        netbytes += bytes;
+        filebytes = bytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes));
+        bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
+        if (filebytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): send data timeout\n", me));
+                goto aborted;
+            }
+            break;
+        }
+       TEST_ASSERT(bytes > 0);
+    }
+    
+    PR_Lock(server->ml);
+    server->bytesTransferred += filebytes;
+    PR_Unlock(server->ml);
+
+    rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+    if (Aborted(rv)) goto aborted;
+
+    rv = PR_Close(file);
+    if (Aborted(rv)) goto aborted;
+    TEST_ASSERT(PR_SUCCESS == rv);
+    file = NULL;
+
+aborted:
+    PR_ClearInterrupt();
+    if (NULL != file) PR_Close(file);
+    drv = PR_Delete(descriptor->filename);
+    TEST_ASSERT(PR_SUCCESS == drv);
+exit:
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\t\tProcessRequest(0x%p): Finished\n", me));
+
+    PR_DELETE(descriptor);
+
+#if defined(WIN95)
+    PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */
+#endif
+    return rv;
+}  /* ProcessRequest */
+
+static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool)
+{
+    CSWorker_t *worker = PR_NEWZAP(CSWorker_t);
+    worker->server = server;
+    PR_INIT_CLIST(&worker->element);
+    worker->thread = PR_CreateThread(
+        PR_USER_THREAD, Worker, worker,
+        DEFAULT_SERVER_PRIORITY, thread_scope,
+        PR_UNJOINABLE_THREAD, 0);
+    if (NULL == worker->thread)
+    {
+        PR_DELETE(worker);
+        return PR_FAILURE;
+    }
+
+    TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
+        ("\tCreateWorker(0x%p): create new worker (0x%p)\n",
+        PR_GetCurrentThread(), worker->thread));
+
+    return PR_SUCCESS;
+}  /* CreateWorker */
+
+static void PR_CALLBACK Worker(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr from;
+    PRFileDesc *fd = NULL;
+    PRThread *me = PR_GetCurrentThread();
+    CSWorker_t *worker = (CSWorker_t*)arg;
+    CSServer_t *server = worker->server;
+    CSPool_t *pool = &server->pool;
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_NOTICE,
+        ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1));
+
+    PR_Lock(server->ml);
+    PR_APPEND_LINK(&worker->element, &server->list);
+    pool->workers += 1;  /* define our existance */
+
+    while (cs_run == server->state)
+    {
+        while (pool->accepting >= server->workers.accepting)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\t\tWorker(0x%p): waiting for accept slot[%d]\n",
+                me, pool->accepting));
+            rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT);
+            if (Aborted(rv) || (cs_run != server->state))
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_NOTICE,
+                    ("\tWorker(0x%p): has been %s\n",
+                    me, (Aborted(rv) ? "interrupted" : "stopped")));
+                goto exit;
+            }
+        } 
+        pool->accepting += 1;  /* how many are really in accept */
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\t\tWorker(0x%p): calling accept\n", me));
+        fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT);
+
+        PR_Lock(server->ml);        
+        pool->accepting -= 1;
+        PR_NotifyCondVar(pool->acceptComplete);
+
+        if ((NULL == fd) && Aborted(PR_FAILURE))
+        {
+            if (NULL != server->listener)
+            {
+                PR_Close(server->listener);
+                server->listener = NULL;
+            }
+            goto exit;
+        }
+
+        if (NULL != fd)
+        {
+            /*
+            ** Create another worker of the total number of workers is
+            ** less than the minimum specified or we have none left in
+            ** accept() AND we're not over the maximum.
+            ** This sort of presumes that the number allowed in accept
+            ** is at least as many as the minimum. Otherwise we'll keep
+            ** creating new threads and deleting them soon after.
+            */
+            PRBool another =
+                ((pool->workers < server->workers.minimum) ||
+                ((0 == pool->accepting)
+                    && (pool->workers < server->workers.maximum))) ?
+                    PR_TRUE : PR_FALSE;
+            pool->active += 1;
+            PR_Unlock(server->ml);
+
+            if (another) (void)CreateWorker(server, pool);
+
+            rv = ProcessRequest(fd, server);
+            if (PR_SUCCESS != rv)
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tWorker(0x%p): server process ended abnormally\n", me));
+            (void)PR_Close(fd); fd = NULL;
+
+            PR_Lock(server->ml);
+            pool->active -= 1;
+        }
+    }
+
+exit:
+    PR_ClearInterrupt();    
+    PR_Unlock(server->ml);
+
+    if (NULL != fd)
+    {
+        (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+        (void)PR_Close(fd);
+    }
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_NOTICE,
+        ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers));
+
+    PR_Lock(server->ml);
+    pool->workers -= 1;  /* undefine our existance */
+    PR_REMOVE_AND_INIT_LINK(&worker->element);
+    PR_NotifyCondVar(pool->exiting);
+    PR_Unlock(server->ml);
+
+    PR_DELETE(worker);  /* destruction of the "worker" object */
+
+}  /* Worker */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr serverAddress;
+    PRThread *me = PR_GetCurrentThread();
+    CSServer_t *server = (CSServer_t*)arg;
+    PRSocketOptionData sockOpt;
+
+    server->listener = PR_Socket(domain, SOCK_STREAM, protocol);
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    rv = PR_SetSocketOption(server->listener, &sockOpt);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    memset(&serverAddress, 0, sizeof(serverAddress));
+	if (PR_AF_INET6 != domain)
+		rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress);
+	else
+		rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, DEFAULT_PORT,
+													&serverAddress);
+    rv = PR_Bind(server->listener, &serverAddress);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    rv = PR_Listen(server->listener, server->backlog);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    server->started = PR_IntervalNow();
+    TimeOfDayMessage("Server started at", me);
+
+    PR_Lock(server->ml);
+    server->state = cs_run;
+    PR_NotifyCondVar(server->stateChange);
+    PR_Unlock(server->ml);
+
+    /*
+    ** Create the first worker (actually, a thread that accepts
+    ** connections and then processes the work load as needed).
+    ** From this point on, additional worker threads are created
+    ** as they are needed by existing worker threads.
+    */
+    rv = CreateWorker(server, &server->pool);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    /*
+    ** From here on this thread is merely hanging around as the contact
+    ** point for the main test driver. It's just waiting for the driver
+    ** to declare the test complete.
+    */
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\tServer(0x%p): waiting for state change\n", me));
+
+    PR_Lock(server->ml);
+    while ((cs_run == server->state) && !Aborted(rv))
+    {
+        rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(server->ml);
+    PR_ClearInterrupt();
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_INFO,
+        ("\tServer(0x%p): shutting down workers\n", me));
+
+    /*
+    ** Get all the worker threads to exit. They know how to
+    ** clean up after themselves, so this is just a matter of
+    ** waiting for clorine in the pool to take effect. During
+    ** this stage we're ignoring interrupts.
+    */
+    server->workers.minimum = server->workers.maximum = 0;
+
+    PR_Lock(server->ml);
+    while (!PR_CLIST_IS_EMPTY(&server->list))
+    {
+        PRCList *head = PR_LIST_HEAD(&server->list);
+        CSWorker_t *worker = (CSWorker_t*)head;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker));
+        rv = PR_Interrupt(worker->thread);
+        TEST_ASSERT(PR_SUCCESS == rv);
+        PR_REMOVE_AND_INIT_LINK(head);
+    }
+
+    while (server->pool.workers > 0)
+    {
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE,
+            ("\tServer(0x%p): waiting for %u workers to exit\n",
+            me, server->pool.workers));
+        (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    server->state = cs_exit;
+    PR_NotifyCondVar(server->stateChange);
+    PR_Unlock(server->ml);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("\tServer(0x%p): stopped after %u operations and %u bytes\n",
+        me, server->operations, server->bytesTransferred));
+
+    if (NULL != server->listener) PR_Close(server->listener);
+    server->stopped = PR_IntervalNow();
+
+}  /* Server */
+
+static void WaitForCompletion(PRIntn execution)
+{
+    while (execution > 0)
+    { 
+        PRIntn dally = (execution > 30) ? 30 : execution;
+        PR_Sleep(PR_SecondsToInterval(dally));
+        if (pthread_stats) PT_FPrintStats(debug_out, "\nPThread Statistics\n");
+        execution -= dally;
+    }
+}  /* WaitForCompletion */
+
+static void Help(void)
+{
+    PR_fprintf(debug_out, "cltsrv test program usage:\n");
+    PR_fprintf(debug_out, "\t-a <n>       threads allowed in accept        (5)\n");
+    PR_fprintf(debug_out, "\t-b <n>       backlock for listen              (5)\n");
+    PR_fprintf(debug_out, "\t-c <threads> number of clients to create      (1)\n");
+    PR_fprintf(debug_out, "\t-f <low>     low water mark for fd caching    (0)\n");
+    PR_fprintf(debug_out, "\t-F <high>    high water mark for fd caching   (0)\n");
+    PR_fprintf(debug_out, "\t-w <threads> minimal number of server threads (1)\n");
+    PR_fprintf(debug_out, "\t-W <threads> maximum number of server threads (1)\n");
+    PR_fprintf(debug_out, "\t-e <seconds> duration of the test in seconds  (10)\n");
+    PR_fprintf(debug_out, "\t-s <string>  dsn name of server               (localhost)\n");
+    PR_fprintf(debug_out, "\t-G           use GLOBAL threads               (LOCAL)\n");
+    PR_fprintf(debug_out, "\t-X           use XTP as transport             (TCP)\n");
+    PR_fprintf(debug_out, "\t-6           Use IPv6                         (IPv4)\n");
+    PR_fprintf(debug_out, "\t-v           verbosity (accumulative)         (0)\n");
+    PR_fprintf(debug_out, "\t-p           pthread statistics               (FALSE)\n");
+    PR_fprintf(debug_out, "\t-d           debug mode                       (FALSE)\n");
+    PR_fprintf(debug_out, "\t-h           this message\n");
+}  /* Help */
+
+static Verbosity IncrementVerbosity(void)
+{
+    PRIntn verboge = (PRIntn)verbosity + 1;
+    return (Verbosity)verboge;
+}  /* IncrementVerbosity */
+
+int main(int argc, char** argv)
+{
+    PRUintn index;
+    PRBool boolean;
+    CSClient_t *client;
+    PRStatus rv, joinStatus;
+    CSServer_t *server = NULL;
+
+    PRUintn backlog = DEFAULT_BACKLOG;
+    PRUintn clients = DEFAULT_CLIENTS;
+    const char *serverName = DEFAULT_SERVER;
+    PRBool serverIsLocal = PR_TRUE;
+    PRUintn accepting = ALLOWED_IN_ACCEPT;
+    PRUintn workersMin = DEFAULT_WORKERS_MIN;
+    PRUintn workersMax = DEFAULT_WORKERS_MAX;
+    PRIntn execution = DEFAULT_EXECUTION_TIME;
+    PRIntn low = DEFAULT_LOW, high = DEFAULT_HIGH;
+
+    /*
+     * -G           use global threads
+     * -a <n>       threads allowed in accept
+     * -b <n>       backlock for listen
+     * -c <threads> number of clients to create
+     * -f <low>     low water mark for caching FDs
+     * -F <high>    high water mark for caching FDs
+     * -w <threads> minimal number of server threads
+     * -W <threads> maximum number of server threads
+     * -e <seconds> duration of the test in seconds
+     * -s <string>  dsn name of server (implies no server here)
+     * -v           verbosity
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:f:F:w:W:e:s:vdhp");
+
+    debug_out = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'X':  /* use XTP as transport */
+            protocol = 36;
+            break;
+        case '6':  /* Use IPv6 */
+            domain = PR_AF_INET6;
+            break;
+        case 'a':  /* the value for accepting */
+            accepting = atoi(opt->value);
+            break;
+        case 'b':  /* the value for backlock */
+            backlog = atoi(opt->value);
+            break;
+        case 'c':  /* number of client threads */
+            clients = atoi(opt->value);
+            break;
+        case 'f':  /* low water fd cache */
+            low = atoi(opt->value);
+            break;
+        case 'F':  /* low water fd cache */
+            high = atoi(opt->value);
+            break;
+        case 'w':  /* minimum server worker threads */
+            workersMin = atoi(opt->value);
+            break;
+        case 'W':  /* maximum server worker threads */
+            workersMax = atoi(opt->value);
+            break;
+        case 'e':  /* program execution time in seconds */
+            execution = atoi(opt->value);
+            break;
+        case 's':  /* server's address */
+            serverName = opt->value;
+            break;
+        case 'v':  /* verbosity */
+            verbosity = IncrementVerbosity();
+            break;
+        case 'd':  /* debug mode */
+            debug_mode = PR_TRUE;
+            break;
+        case 'p':  /* pthread mode */
+            pthread_stats = PR_TRUE;
+            break;
+        case 'h':
+        default:
+            Help();
+            return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE;
+    if (0 == execution) execution = DEFAULT_EXECUTION_TIME;
+    if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX;
+    if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN;
+    if (0 == accepting) accepting = ALLOWED_IN_ACCEPT;
+    if (0 == backlog) backlog = DEFAULT_BACKLOG;
+
+    if (workersMin > accepting) accepting = workersMin;
+
+    PR_STDIO_INIT();
+    TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread());
+
+    cltsrv_log_file = PR_NewLogModule("cltsrv_log");
+    MY_ASSERT(NULL != cltsrv_log_file);
+    boolean = PR_SetLogFile("cltsrv.log");
+    MY_ASSERT(boolean);
+
+    rv = PR_SetFDCacheSize(low, high);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    if (serverIsLocal)
+    {
+        /* Establish the server */
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_INFO,
+            ("main(0x%p): starting server\n", PR_GetCurrentThread()));
+
+        server = PR_NEWZAP(CSServer_t);
+        PR_INIT_CLIST(&server->list);
+        server->state = cs_init;
+        server->ml = PR_NewLock();
+        server->backlog = backlog;
+        server->port = DEFAULT_PORT;
+        server->workers.minimum = workersMin;
+        server->workers.maximum = workersMax;
+        server->workers.accepting = accepting;
+        server->stateChange = PR_NewCondVar(server->ml);
+        server->pool.exiting = PR_NewCondVar(server->ml);
+        server->pool.acceptComplete = PR_NewCondVar(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE,
+            ("main(0x%p): creating server thread\n", PR_GetCurrentThread()));
+
+        server->thread = PR_CreateThread(
+            PR_USER_THREAD, Server, server, PR_PRIORITY_HIGH,
+            thread_scope, PR_JOINABLE_THREAD, 0);
+        TEST_ASSERT(NULL != server->thread);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): waiting for server init\n", PR_GetCurrentThread()));
+
+        PR_Lock(server->ml);
+        while (server->state == cs_init)
+            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): server init complete (port #%d)\n",
+            PR_GetCurrentThread(), server->port));
+    }
+
+    if (clients != 0)
+    {
+        /* Create all of the clients */
+        PRHostEnt host;
+        char buffer[BUFFER_SIZE];
+        client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t));
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): creating %d client threads\n",
+            PR_GetCurrentThread(), clients));
+        
+        if (!serverIsLocal)
+        {
+            rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host);
+            if (PR_SUCCESS != rv)
+            {
+                PL_FPrintError(PR_STDERR, "PR_GetHostByName");
+                return 2;
+            }
+        }
+
+        for (index = 0; index < clients; ++index)
+        {
+            client[index].state = cs_init;
+            client[index].ml = PR_NewLock();
+            if (serverIsLocal)
+            {
+				if (PR_AF_INET6 != domain)
+                	(void)PR_InitializeNetAddr(
+                    	PR_IpAddrLoopback, DEFAULT_PORT,
+                    	&client[index].serverAddress);
+				else
+					rv = PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6,
+							DEFAULT_PORT, &client[index].serverAddress);
+            }
+            else
+            {
+                (void)PR_EnumerateHostEnt(
+                    0, &host, DEFAULT_PORT, &client[index].serverAddress);
+            }
+            client[index].stateChange = PR_NewCondVar(client[index].ml);
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_INFO,
+                ("main(0x%p): creating client threads\n", PR_GetCurrentThread()));
+            client[index].thread = PR_CreateThread(
+                PR_USER_THREAD, Client, &client[index], PR_PRIORITY_NORMAL,
+                thread_scope, PR_JOINABLE_THREAD, 0);
+            TEST_ASSERT(NULL != client[index].thread);
+            PR_Lock(client[index].ml);
+            while (cs_init == client[index].state)
+                PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
+            PR_Unlock(client[index].ml);
+        }
+    }
+
+    /* Then just let them go at it for a bit */
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("main(0x%p): waiting for execution interval (%d seconds)\n",
+        PR_GetCurrentThread(), execution));
+
+    WaitForCompletion(execution);
+
+    TimeOfDayMessage("Shutting down", PR_GetCurrentThread());
+
+    if (clients != 0)
+    {
+        for (index = 0; index < clients; ++index)
+        {
+            TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
+                ("main(0x%p): notifying client(0x%p) to stop\n",
+                PR_GetCurrentThread(), client[index].thread));
+
+            PR_Lock(client[index].ml);
+            if (cs_run == client[index].state)
+            {
+                client[index].state = cs_stop;
+                PR_Interrupt(client[index].thread);
+                while (cs_stop == client[index].state)
+                    PR_WaitCondVar(
+                        client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
+            }
+            PR_Unlock(client[index].ml);
+
+            TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, 
+                ("main(0x%p): joining client(0x%p)\n",
+                PR_GetCurrentThread(), client[index].thread));
+
+		    joinStatus = PR_JoinThread(client[index].thread);
+		    TEST_ASSERT(PR_SUCCESS == joinStatus);
+            PR_DestroyCondVar(client[index].stateChange);
+            PR_DestroyLock(client[index].ml);
+        }
+        PR_DELETE(client);
+    }
+
+    if (NULL != server)
+    {
+        /* All clients joined - retrieve the server */
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE, 
+            ("main(0x%p): notifying server(0x%p) to stop\n",
+            PR_GetCurrentThread(), server->thread));
+
+        PR_Lock(server->ml);
+        server->state = cs_stop;
+        PR_Interrupt(server->thread);
+        while (cs_exit != server->state)
+            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE, 
+            ("main(0x%p): joining server(0x%p)\n",
+            PR_GetCurrentThread(), server->thread));
+        joinStatus = PR_JoinThread(server->thread);
+        TEST_ASSERT(PR_SUCCESS == joinStatus);
+
+        PR_DestroyCondVar(server->stateChange);
+        PR_DestroyCondVar(server->pool.exiting);
+        PR_DestroyCondVar(server->pool.acceptComplete);
+        PR_DestroyLock(server->ml);
+        PR_DELETE(server);
+    }
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS, 
+        ("main(0x%p): test complete\n", PR_GetCurrentThread()));
+
+    PT_FPrintStats(debug_out, "\nPThread Statistics\n");
+
+    TimeOfDayMessage("Test exiting at", PR_GetCurrentThread());
+    PR_Cleanup();
+    return 0;
+}  /* main */
+
+/* cltsrv.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/concur.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/concur.c
new file mode 100644
index 0000000..d7b9539
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/concur.c
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:            concur.c 
+** Description:     test of adding and removing concurrency options
+*/
+
+#include "prcvar.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prprf.h"
+#include "prmem.h"
+#include "prlog.h"
+
+#include "plgetopt.h"
+
+#include "private/pprio.h"
+
+#include <stdlib.h>
+
+#define DEFAULT_RANGE 10
+#define DEFAULT_LOOPS 100
+
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+typedef struct Context
+{
+    PRLock *ml;
+    PRCondVar *cv;
+    PRIntn want, have;
+} Context;
+
+
+/*
+** Make the instance of 'context' static (not on the stack)
+** for Win16 threads
+*/
+static Context context = {NULL, NULL, 0, 0};
+
+static void PR_CALLBACK Dull(void *arg)
+{
+    Context *context = (Context*)arg;
+    PR_Lock(context->ml);
+    context->have += 1;
+    while (context->want >= context->have)
+        PR_WaitCondVar(context->cv, PR_INTERVAL_NO_TIMEOUT);
+    context->have -= 1;
+    PR_Unlock(context->ml);
+}  /* Dull */
+
+PRIntn PR_CALLBACK Concur(PRIntn argc, char **argv)
+{
+    PRUintn cpus;
+	PLOptStatus os;
+	PRThread **threads;
+    PRBool debug = PR_FALSE;
+    PRUintn range = DEFAULT_RANGE;
+	PRStatus rc;
+    PRUintn cnt;
+    PRUintn loops = DEFAULT_LOOPS;
+	PRIntervalTime hundredMills = PR_MillisecondsToInterval(100);
+	PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:r:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* GLOBAL threads */
+			thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'd':  /* debug mode */
+			debug = PR_TRUE;
+            break;
+        case 'r':  /* range limit */
+			range = atoi(opt->value);
+            break;
+        case 'l':  /* loop counter */
+			loops = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (0 == range) range = DEFAULT_RANGE;
+    if (0 == loops) loops = DEFAULT_LOOPS;
+
+    context.ml = PR_NewLock();
+    context.cv = PR_NewCondVar(context.ml);
+
+    if (debug)
+        PR_fprintf(
+            PR_STDERR, "Testing with %d CPUs and %d interations\n", range, loops);
+
+	threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * range);
+    while (--loops > 0)
+    {
+        for (cpus = 1; cpus <= range; ++cpus)
+        {
+            PR_SetConcurrency(cpus);
+            context.want = cpus;
+
+            threads[cpus - 1] = PR_CreateThread(
+                PR_USER_THREAD, Dull, &context, PR_PRIORITY_NORMAL,
+				      thread_scope, PR_JOINABLE_THREAD, 0);
+        }
+
+        PR_Sleep(hundredMills);
+
+        for (cpus = range; cpus > 0; cpus--)
+        {
+            PR_SetConcurrency(cpus);
+            context.want = cpus - 1;
+
+            PR_Lock(context.ml);
+            PR_NotifyCondVar(context.cv);
+            PR_Unlock(context.ml);
+        }
+		for(cnt = 0; cnt < range; cnt++) {
+			rc = PR_JoinThread(threads[cnt]);
+			PR_ASSERT(rc == PR_SUCCESS);
+		}
+    }
+
+    
+    if (debug)
+        PR_fprintf(
+            PR_STDERR, "Waiting for %d thread(s) to exit\n", context.have);
+
+    while (context.have > 0) PR_Sleep(hundredMills);
+
+    if (debug)
+        PR_fprintf(
+            PR_STDERR, "Finished [want: %d, have: %d]\n",
+            context.want, context.have);
+
+    PR_DestroyLock(context.ml);
+    PR_DestroyCondVar(context.cv);
+    PR_DELETE(threads);
+
+    PR_fprintf(PR_STDERR, "PASSED\n");
+
+    return 0;
+} /* Concur */
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+    return PR_Initialize(Concur, argc, argv, 0);
+}  /* main */
+
+/* concur.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/cvar.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/cvar.c
new file mode 100644
index 0000000..928e1d3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/cvar.c
@@ -0,0 +1,323 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: cvar.c
+**
+** Description: Tests Condition Variable Operations 
+**
+** Modification History:
+** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+** 12-June-97 Revert to return code 0 and 1.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+#include "nspr.h"
+
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRMonitor *mon;
+#define DEFAULT_COUNT   1000
+PRInt32 count = 0;
+PRIntn debug_mode;
+
+#define kQSIZE	1
+
+typedef struct {
+	PRLock		*bufLock;
+	int			startIdx;
+	int			numFull;
+	PRCondVar	*notFull;
+	PRCondVar	*notEmpty;
+	void		*data[kQSIZE];
+} CircBuf;
+
+static PRBool failed = PR_FALSE;
+
+/*
+** NewCB creates and initializes a new circular buffer.
+*/
+static CircBuf* NewCB(void)
+{
+	CircBuf		*cbp;
+	
+	cbp = PR_NEW(CircBuf);
+	if (cbp == NULL)
+		return (NULL);
+		
+	cbp->bufLock 	= PR_NewLock();
+	cbp->startIdx 	= 0;
+	cbp->numFull 	= 0;
+	cbp->notFull	= PR_NewCondVar(cbp->bufLock);
+	cbp->notEmpty	= PR_NewCondVar(cbp->bufLock);
+	
+	return (cbp);
+}
+
+/*
+** DeleteCB frees a circular buffer.
+*/
+static void DeleteCB(CircBuf *cbp)
+{
+	PR_DestroyLock(cbp->bufLock);
+	PR_DestroyCondVar(cbp->notFull);
+	PR_DestroyCondVar(cbp->notEmpty);
+	PR_DELETE(cbp);
+}
+
+
+/*
+** PutCBData puts new data on the queue.  If the queue is full, it waits 
+** until there is room.
+*/
+static void PutCBData(CircBuf *cbp, void *data)
+{
+	PR_Lock(cbp->bufLock);
+	/* wait while the buffer is full */
+	while (cbp->numFull == kQSIZE)
+		PR_WaitCondVar(cbp->notFull,PR_INTERVAL_NO_TIMEOUT);
+	cbp->data[(cbp->startIdx + cbp->numFull) % kQSIZE] = data;
+	cbp->numFull += 1;
+	
+	/* let a waiting reader know that there is data */
+	PR_NotifyCondVar(cbp->notEmpty);
+	PR_Unlock(cbp->bufLock);
+
+}
+
+
+/*
+** GetCBData gets the oldest data on the queue.  If the queue is empty, it waits 
+** until new data appears.
+*/
+static void* GetCBData(CircBuf *cbp)
+{
+	void *data;
+	
+	PR_Lock(cbp->bufLock);
+	/* wait while the buffer is empty */
+	while (cbp->numFull == 0)
+		PR_WaitCondVar(cbp->notEmpty,PR_INTERVAL_NO_TIMEOUT);
+	data = cbp->data[cbp->startIdx];
+	cbp->startIdx =(cbp->startIdx + 1) % kQSIZE;
+	cbp->numFull -= 1;
+	
+	/* let a waiting writer know that there is room */
+	PR_NotifyCondVar(cbp->notFull);
+	PR_Unlock(cbp->bufLock);
+	
+	return (data);
+}
+
+
+/************************************************************************/
+
+static int alive;
+
+static void PR_CALLBACK CXReader(void *arg)
+{
+	CircBuf *cbp = (CircBuf *)arg;
+    PRInt32 i, n;
+    void *data;
+
+    n = count / 2;
+    for (i = 0; i < n; i++) {
+		data = GetCBData(cbp);
+		if ((int)data != i)
+    		if (debug_mode) printf("data mismatch at for i = %d usec\n", i);
+    }
+ 
+    PR_EnterMonitor(mon);
+    --alive;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+}
+
+static void PR_CALLBACK CXWriter(void *arg)
+{
+	CircBuf *cbp = (CircBuf *)arg;
+    PRInt32 i, n;
+
+    n = count / 2;
+    for (i = 0; i < n; i++)
+		PutCBData(cbp, (void *)i);
+
+    PR_EnterMonitor(mon);
+    --alive;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+}
+
+static void CondWaitContextSwitch(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *t1, *t2;
+	CircBuf *cbp;
+
+    PR_EnterMonitor(mon);
+
+    alive = 2;
+
+	cbp =  NewCB();
+
+	t1 = PR_CreateThread(PR_USER_THREAD,
+				      CXReader, cbp, 
+				      PR_PRIORITY_NORMAL,
+				      scope1,
+    				  PR_UNJOINABLE_THREAD,
+				      0);
+	PR_ASSERT(t1);
+	t2 = PR_CreateThread(PR_USER_THREAD,
+				      CXWriter, cbp, 
+				      PR_PRIORITY_NORMAL,
+				      scope2,
+    				  PR_UNJOINABLE_THREAD,
+				      0);
+	PR_ASSERT(t2);
+
+    /* Wait for both of the threads to exit */
+    while (alive) {
+	PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+	DeleteCB(cbp);
+
+    PR_ExitMonitor(mon);
+}
+
+static void CondWaitContextSwitchUU(void)
+{
+    CondWaitContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CondWaitContextSwitchUK(void)
+{
+    CondWaitContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void CondWaitContextSwitchKK(void)
+{
+    CondWaitContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("%40s: %6.2f usec\n", msg, d / count);
+
+    if (0 ==  d) failed = PR_TRUE;
+}
+
+static PRIntn PR_CALLBACK RealMain(int argc, char **argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name [-d] [-c n]
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'c':  /* loop count */
+            count = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (0 == count) count = DEFAULT_COUNT;
+
+    mon = PR_NewMonitor();
+
+    Measure(CondWaitContextSwitchUU, "cond var wait context switch- user/user");
+    Measure(CondWaitContextSwitchUK, "cond var wait context switch- user/kernel");
+    Measure(CondWaitContextSwitchKK, "cond var wait context switch- kernel/kernel");
+
+	PR_DestroyMonitor(mon);
+
+	if (debug_mode) printf("%s\n", (failed) ? "FAILED" : "PASSED");
+
+	if(failed)
+		return 1;
+	else
+		return 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/cvar2.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/cvar2.c
new file mode 100644
index 0000000..5c33c61
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/cvar2.c
@@ -0,0 +1,992 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: cvar2.c
+**
+** Description: Simple test creates several local and global threads;
+**              half use a single,shared condvar, and the
+**              other half have their own condvar. The main thread then loops
+**				notifying them to wakeup. 
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+
+#include "nspr.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int _debug_on = 0;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+#define DEFAULT_COUNT   100
+#define DEFAULT_THREADS 5
+PRInt32 count = DEFAULT_COUNT;
+
+typedef struct threadinfo {
+    PRThread        *thread;
+    PRInt32          id;
+    PRBool           internal;
+    PRInt32         *tcount;
+    PRLock          *lock;
+    PRCondVar       *cvar;
+    PRIntervalTime   timeout;
+    PRInt32          loops;
+
+    PRLock          *exitlock;
+    PRCondVar       *exitcvar;
+    PRInt32         *exitcount;
+} threadinfo;
+
+/*
+** Make exitcount, tcount static. for Win16.
+*/
+static PRInt32 exitcount=0;
+static PRInt32 tcount=0;
+
+
+/* Thread that gets notified; many threads share the same condvar */
+void PR_CALLBACK
+SharedCondVarThread(void *_info)
+{
+    threadinfo *info = (threadinfo *)_info;
+    PRInt32 index;
+
+    for (index=0; index<info->loops; index++) {
+        PR_Lock(info->lock);
+        if (*info->tcount == 0)
+            PR_WaitCondVar(info->cvar, info->timeout);
+#if 0
+        printf("shared thread %ld notified in loop %ld\n", info->id, index);
+#endif
+        (*info->tcount)--;
+        PR_Unlock(info->lock);
+
+        PR_Lock(info->exitlock);
+        (*info->exitcount)++;
+        PR_NotifyCondVar(info->exitcvar);
+        PR_Unlock(info->exitlock);
+    }
+#if 0
+    printf("shared thread %ld terminating\n", info->id);
+#endif
+}
+
+/* Thread that gets notified; no other threads use the same condvar */
+void PR_CALLBACK
+PrivateCondVarThread(void *_info)
+{
+    threadinfo *info = (threadinfo *)_info;
+    PRInt32 index;
+
+    for (index=0; index<info->loops; index++) {
+        PR_Lock(info->lock);
+        if (*info->tcount == 0) {
+	    DPRINTF(("PrivateCondVarThread: thread 0x%lx waiting on cvar = 0x%lx\n",
+				PR_GetCurrentThread(), info->cvar));
+            PR_WaitCondVar(info->cvar, info->timeout);
+	}
+#if 0
+        printf("solo   thread %ld notified in loop %ld\n", info->id, index);
+#endif
+        (*info->tcount)--;
+        PR_Unlock(info->lock);
+
+        PR_Lock(info->exitlock);
+        (*info->exitcount)++;
+        PR_NotifyCondVar(info->exitcvar);
+DPRINTF(("PrivateCondVarThread: thread 0x%lx notified exitcvar = 0x%lx cnt = %ld\n",
+			PR_GetCurrentThread(), info->exitcvar,(*info->exitcount)));
+        PR_Unlock(info->exitlock);
+    }
+#if 0
+    printf("solo   thread %ld terminating\n", info->id);
+#endif
+}
+
+void 
+CreateTestThread(threadinfo *info, 
+                 PRInt32 id,
+                 PRLock *lock,
+                 PRCondVar *cvar,
+                 PRInt32 loops,
+                 PRIntervalTime timeout,
+                 PRInt32 *tcount,
+                 PRLock *exitlock,
+                 PRCondVar *exitcvar,
+                 PRInt32 *exitcount,
+                 PRBool shared, 
+                 PRThreadScope scope)
+{
+    info->id = id;
+    info->internal = (shared) ? PR_FALSE : PR_TRUE;
+    info->lock = lock;
+    info->cvar = cvar;
+    info->loops = loops;
+    info->timeout = timeout;
+    info->tcount = tcount;
+    info->exitlock = exitlock;
+    info->exitcvar = exitcvar;
+    info->exitcount = exitcount;
+    info->thread = PR_CreateThread(
+                           PR_USER_THREAD,
+                           shared?SharedCondVarThread:PrivateCondVarThread,
+                           info,
+                           PR_PRIORITY_NORMAL,
+                           scope,
+                           PR_JOINABLE_THREAD,
+                           0);
+    if (!info->thread)
+        PL_PrintError("error creating thread\n");
+}
+
+
+void 
+CondVarTestSUU(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    
+    exitcount=0;
+    tcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_LOCAL_THREAD);
+        index++;
+	DPRINTF(("CondVarTestSUU: created thread 0x%lx\n",list[index].thread));
+    }
+
+    for (loops = 0; loops < count; loops++) {
+        /* Notify the threads */
+        for(index=0; index<(arg); index++) {
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+	    DPRINTF(("PrivateCondVarThread: thread 0x%lx notified cvar = 0x%lx\n",
+				PR_GetCurrentThread(), list[index].cvar));
+        }
+
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg);
+        exitcount -= arg;
+        PR_Unlock(exitlock);
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg); index++) 
+        PR_JoinThread(list[index].thread);
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+}
+
+void 
+CondVarTestSUK(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    exitcount=0;
+    tcount=0;
+
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_GLOBAL_THREAD);
+        index++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+        /* Notify the threads */
+        for(index=0; index<(arg); index++) {
+
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+        }
+
+#if 0
+        printf("wait for threads to be done\n");
+#endif
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg);
+        exitcount -= arg;
+        PR_Unlock(exitlock);
+#if 0
+        printf("threads ready\n");
+#endif
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg); index++) 
+        PR_JoinThread(list[index].thread);
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+}
+
+void 
+CondVarTestPUU(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    PRInt32 *tcount, *saved_tcount;
+
+    exitcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+    saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg; ) {
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_LOCAL_THREAD);
+
+	DPRINTF(("CondVarTestPUU: created thread 0x%lx\n",list[index].thread));
+        index++;
+	tcount++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+        /* Notify the threads */
+        for(index=0; index<(arg); index++) {
+
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+        }
+
+	PR_Lock(exitlock);
+        /* Wait for threads to finish */
+        while(exitcount < arg) {
+DPRINTF(("CondVarTestPUU: thread 0x%lx waiting on exitcvar = 0x%lx cnt = %ld\n",
+				PR_GetCurrentThread(), exitcvar, exitcount));
+            	PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+	}
+        PR_ASSERT(exitcount >= arg);
+        exitcount -= arg;
+        PR_Unlock(exitlock);
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg); index++)  {
+	DPRINTF(("CondVarTestPUU: joining thread 0x%lx\n",list[index].thread));
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+    PR_DELETE(saved_tcount);
+}
+
+void 
+CondVarTestPUK(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    PRInt32 *tcount, *saved_tcount;
+
+    exitcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+    saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg; ) {
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_GLOBAL_THREAD);
+
+        index++;
+        tcount++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+        /* Notify the threads */
+        for(index=0; index<(arg); index++) {
+
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+        }
+
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg);
+        exitcount -= arg;
+        PR_Unlock(exitlock);
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg); index++) {
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+    PR_DELETE(saved_tcount);
+}
+
+void 
+CondVarTest(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    PRInt32 *ptcount, *saved_ptcount;
+
+    exitcount=0;
+    tcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+    saved_ptcount = ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg*4; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_LOCAL_THREAD);
+
+        index++;
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_GLOBAL_THREAD);
+
+        index++;
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         ptcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_LOCAL_THREAD);
+        index++;
+	ptcount++;
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         ptcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_GLOBAL_THREAD);
+
+        index++;
+	ptcount++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+
+        /* Notify the threads */
+        for(index=0; index<(arg*4); index++) {
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+        }
+
+#if 0
+        printf("wait for threads done\n");
+#endif
+
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg*4)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg*4);
+        exitcount -= arg*4;
+        PR_Unlock(exitlock);
+#if 0
+        printf("threads ready\n");
+#endif
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg*4); index++) {
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+    PR_DELETE(saved_ptcount);
+}
+
+void 
+CondVarTimeoutTest(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg*4; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_LOCAL_THREAD);
+        index++;
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_GLOBAL_THREAD);
+        index++;
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_LOCAL_THREAD);
+        index++;
+
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_GLOBAL_THREAD);
+
+        index++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg*4)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg*4);
+        exitcount -= arg*4;
+        PR_Unlock(exitlock);
+    }
+
+
+    /* Join all the threads */
+    for(index=0; index<(arg*4); index++) {
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+}
+
+void 
+CondVarMixedTest(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    PRInt32 *ptcount;
+
+    exitcount=0;
+    tcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+    ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg*4; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_LOCAL_THREAD);
+        index++;
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_GLOBAL_THREAD);
+        index++;
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         ptcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_LOCAL_THREAD);
+        index++;
+	ptcount++;
+
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         ptcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_GLOBAL_THREAD);
+        index++;
+	ptcount++;
+    }
+
+
+    /* Notify every 3rd thread */
+    for (loops = 0; loops < count; loops++) {
+
+        /* Notify the threads */
+        for(index=0; index<(arg*4); index+=3) {
+
+            PR_Lock(list[index].lock);
+            *list[index].tcount++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+
+        }
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg*4)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg*4);
+        exitcount -= arg*4;
+        PR_Unlock(exitlock);
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg*4); index++) {
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+
+    PR_DELETE(list);
+}
+
+void 
+CondVarCombinedTest(void *arg)
+{
+    PRThread *threads[3];
+
+    threads[0] = PR_CreateThread(PR_USER_THREAD,
+                                 CondVarTest,
+                                 (void *)arg,
+                                 PR_PRIORITY_NORMAL,
+                                 PR_GLOBAL_THREAD,
+                                 PR_JOINABLE_THREAD,
+                                 0);
+    threads[1] = PR_CreateThread(PR_USER_THREAD,
+                                 CondVarTimeoutTest,
+                                 (void *)arg,
+                                 PR_PRIORITY_NORMAL,
+                                 PR_GLOBAL_THREAD,
+                                 PR_JOINABLE_THREAD,
+                                 0);
+    threads[2] = PR_CreateThread(PR_USER_THREAD,
+                                 CondVarMixedTest,
+                                 (void *)arg,
+                                 PR_PRIORITY_NORMAL,
+                                 PR_GLOBAL_THREAD,
+                                 PR_JOINABLE_THREAD,
+                                 0);
+
+    PR_JoinThread(threads[0]);
+    PR_JoinThread(threads[1]);
+    PR_JoinThread(threads[2]);
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void *), PRInt32 arg, const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)((void *)arg);
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    printf("%40s: %6.2f usec\n", msg, d / count);
+}
+
+static PRIntn PR_CALLBACK RealMain(int argc, char **argv)
+{
+    PRInt32 threads, default_threads = DEFAULT_THREADS;
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "vc:t:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'v':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 'c':  /* loop counter */
+			count = atoi(opt->value);
+            break;
+        case 't':  /* number of threads involved */
+			default_threads = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (0 == count) count = DEFAULT_COUNT;
+    if (0 == default_threads) default_threads = DEFAULT_THREADS;
+
+    printf("\n\
+CondVar Test:                                                           \n\
+                                                                        \n\
+Simple test creates several local and global threads; half use a single,\n\
+shared condvar, and the other half have their own condvar.  The main    \n\
+thread then loops notifying them to wakeup.                             \n\
+                                                                        \n\
+The timeout test is very similar except that the threads are not        \n\
+notified.  They will all wakeup on a 1 second timeout.                  \n\
+                                                                        \n\
+The mixed test combines the simple test and the timeout test; every     \n\
+third thread is notified, the other threads are expected to timeout     \n\
+correctly.                                                              \n\
+                                                                        \n\
+Lastly, the combined test creates a thread for each of the above three  \n\
+cases and they all run simultaneously.                                  \n\
+                                                                        \n\
+This test is run with %d, %d, %d, and %d threads of each type.\n\n",
+default_threads, default_threads*2, default_threads*3, default_threads*4);
+
+    PR_SetConcurrency(2);
+
+    for (threads = default_threads; threads < default_threads*5; threads+=default_threads) {
+        printf("\n%ld Thread tests\n", threads);
+        Measure(CondVarTestSUU, threads, "Condvar simple test shared UU");
+        Measure(CondVarTestSUK, threads, "Condvar simple test shared UK");
+        Measure(CondVarTestPUU, threads, "Condvar simple test priv UU");
+        Measure(CondVarTestPUK, threads, "Condvar simple test priv UK");
+        Measure(CondVarTest, threads, "Condvar simple test All");
+        Measure(CondVarTimeoutTest, threads,  "Condvar timeout test");
+#if 0
+        Measure(CondVarMixedTest, threads,  "Condvar mixed timeout test");
+        Measure(CondVarCombinedTest, threads, "Combined condvar test");
+#endif
+    }
+
+    printf("PASS\n");
+
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dbmalloc.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dbmalloc.c
new file mode 100644
index 0000000..ed500b7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dbmalloc.c
@@ -0,0 +1,342 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: dbmalloc.c
+**
+** Description: Testing malloc (OBSOLETE)
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "nspr.h"
+
+void
+usage
+(
+    void
+)
+{
+    fprintf(stderr, "Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename [...]\n");
+    exit(0);
+}
+
+typedef struct node_struct
+{
+    struct node_struct *next, *prev;
+    int line;
+    char value[4];
+}
+    node_t,
+   *node_pt;
+
+node_pt get_node(const char *line)
+{
+    node_pt rv;
+    int l = strlen(line);
+    rv = (node_pt)PR_MALLOC(sizeof(node_t) + l + 1 - 4);
+    if( (node_pt)0 == rv ) return (node_pt)0;
+    memcpy(&rv->value[0], line, l+1);
+    rv->next = rv->prev = (node_pt)0;
+    return rv;
+}
+
+void
+dump
+(
+    const char *name,
+    node_pt     node,
+    int         mf,
+    int         debug
+)
+{
+    if( (node_pt)0 != node->prev ) dump(name, node->prev, mf, debug);
+    if( 0 != debug ) printf("[%s]: %6d: %s", name, node->line, node->value);
+    if( node->line == mf ) fprintf(stderr, "[%s]: Line %d was allocated!\n", name, node->line);
+    if( (node_pt)0 != node->next ) dump(name, node->next, mf, debug);
+    return;
+}
+
+void
+release
+(
+    node_pt node
+)
+{
+    if( (node_pt)0 != node->prev ) release(node->prev);
+    if( (node_pt)0 != node->next ) release(node->next);
+    PR_DELETE(node);
+}
+
+int
+t2
+(
+    const char *name,
+    int         mf,
+    int         debug
+)
+{
+    int rv;
+    FILE *fp;
+    int l = 0;
+    node_pt head = (node_pt)0;
+    char buffer[ BUFSIZ ];
+
+    fp = fopen(name, "r");
+    if( (FILE *)0 == fp )
+    {
+        fprintf(stderr, "[%s]: Cannot open \"%s.\"\n", name, name);
+        return -1;
+    }
+
+    /* fgets mallocs a buffer, first time through. */
+    if( (char *)0 == fgets(buffer, BUFSIZ, fp) )
+    {
+        fprintf(stderr, "[%s]: \"%s\" is empty.\n", name, name);
+        (void)fclose(fp);
+        return -1;
+    }
+
+    rewind(fp);
+
+    if( PR_SUCCESS != PR_ClearMallocCount() )
+    {
+        fprintf(stderr, "[%s]: Cannot clear malloc count.\n", name);
+        (void)fclose(fp);
+        return -1;
+    }
+
+    if( PR_SUCCESS != PR_SetMallocCountdown(mf) )
+    {
+        fprintf(stderr, "[%s]: Cannot set malloc countdown to %d\n", name, mf);
+        (void)fclose(fp);
+        return -1;
+    }
+
+    while( fgets(buffer, BUFSIZ, fp) )
+    {
+        node_pt n;
+        node_pt *w = &head;
+
+        if( (strlen(buffer) == (BUFSIZ-1)) && (buffer[BUFSIZ-2] != '\n') )
+            buffer[BUFSIZ-2] == '\n';
+
+        l++;
+
+        n = get_node(buffer);
+        if( (node_pt)0 == n ) 
+        {
+            printf("[%s]: Line %d: malloc failure!\n", name, l);
+            continue;
+        }
+
+        n->line = l;
+
+        while( 1 )
+        {
+            int comp;
+
+            if( (node_pt)0 == *w )
+            {
+                *w = n;
+                break;
+            }
+
+            comp = strcmp((*w)->value, n->value);
+            if( comp < 0 ) w = &(*w)->next;
+            else w = &(*w)->prev;
+        }
+    }
+
+    (void)fclose(fp);
+
+    dump(name, head, mf, debug);
+
+    rv = PR_GetMallocCount();
+    PR_ClearMallocCountdown();
+
+    release(head);
+
+    return rv;
+}
+
+int nf = 0;
+int debug = 0;
+
+void
+test
+(
+    const char *name
+)
+{
+    int n, i;
+
+    extern int nf, debug;
+
+    printf("[%s]: starting test 0\n", name);
+    n = t2(name, 0, debug);
+    if( -1 == n ) return;
+    printf("[%s]: test 0 had %ld allocations.\n", name, n);
+
+    if( 0 >= n ) return;
+
+    for( i = 0; i < nf; i++ )
+    {
+        int which = rand() % n;
+        if( 0 == which ) printf("[%s]: starting test %d -- no allocation should fail\n", name, i+1);
+        else printf("[%s]: starting test %d -- allocation %d should fail\n", name, i+1, which);
+        (void)t2(name, which, debug);
+        printf("[%s]: test %d done.\n", name, i+1);
+    }
+
+    return;
+}
+
+int main(int argc, char **argv)
+{
+    int okay = 0;
+    int multithread = 0;
+
+    struct threadlist
+    {
+        struct threadlist *next;
+        PRThread *thread;
+    }
+        *threadhead = (struct threadlist *)0;
+
+    extern int nf, debug;
+
+    srand(time(0));
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    printf("[main]: We %s using the debugging malloc.\n",
+           PR_IsDebuggingMalloc() ? "ARE" : "ARE NOT");
+
+    while( argv++, --argc )
+    {
+        if( '-' == argv[0][0] )
+        {
+            switch( argv[0][1] )
+            {
+                case 'f':
+                    nf = atoi(argv[0][2] ? &argv[0][2] :
+                              --argc ? *++argv : "0");
+                    break;
+                case 'd':
+                    debug = 1;
+                    break;
+                case 'n':
+                    debug = 0;
+                    break;
+                case 'm':
+                    multithread = 1;
+                    break;
+                case 's':
+                    multithread = 0;
+                    break;
+                default:
+                    usage();
+                    break;
+            }
+        }
+        else
+        {
+            FILE *fp = fopen(*argv, "r");
+            if( (FILE *)0 == fp )
+            {
+                fprintf(stderr, "Cannot open \"%s.\"\n", *argv);
+                continue;
+            }
+
+            okay++;
+            (void)fclose(fp);
+            if( multithread )
+            {
+                struct threadlist *n;
+
+                n = (struct threadlist *)malloc(sizeof(struct threadlist));
+                if( (struct threadlist *)0 == n ) 
+                {
+                    fprintf(stderr, "This is getting tedious. \"%s\"\n", *argv);
+                    continue;
+                }
+
+                n->next = threadhead;
+                n->thread = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))test, 
+                                            *argv, PR_PRIORITY_NORMAL, 
+                                            PR_LOCAL_THREAD, PR_JOINABLE_THREAD,
+                                            0);
+                if( (PRThread *)0 == n->thread )
+                {
+                    fprintf(stderr, "Can't create thread for \"%s.\"\n", *argv);
+                    continue;
+                }
+                else
+                {
+                    threadhead = n;
+                }
+            }
+            else
+            {
+                test(*argv);
+            }
+        }
+    }
+
+    if( okay == 0 ) usage();
+    else while( (struct threadlist *)0 != threadhead )
+    {
+        struct threadlist *x = threadhead->next;
+        (void)PR_JoinThread(threadhead->thread);
+        PR_DELETE(threadhead);
+        threadhead = x;
+    }
+
+    return 0;
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dbmalloc1.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dbmalloc1.c
new file mode 100644
index 0000000..f12a27c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dbmalloc1.c
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: dbmalloc1.c (OBSOLETE)
+**
+** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions.
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+**
+** 12-June-97 AGarcia Revert to return code 0 and 1, remove debug option (obsolete).
+***********************************************************************/
+
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include "nspr.h"
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+/* variable used for both r1 and r2 tests */
+int should_fail =0;
+int actually_failed=0;
+
+
+void
+r1
+(
+    void
+)
+{
+    int i;
+	actually_failed=0;
+    for(  i = 0; i < 5; i++ )
+    {
+        void *x = PR_MALLOC(128);
+        if( (void *)0 == x ) {
+			if (debug_mode) printf("\tMalloc %d failed.\n", i+1);
+			actually_failed = 1;
+		}
+        PR_DELETE(x);
+    }
+
+	if (((should_fail != actually_failed) & (!debug_mode))) failed_already=1;
+
+
+    return;
+}
+
+void
+r2
+(
+    void
+)
+{
+    int i;
+
+    for( i = 0; i <= 5; i++ )
+    {
+		should_fail =0;
+        if( 0 == i ) {
+			if (debug_mode) printf("No malloc should fail:\n");
+		}
+        else {
+			if (debug_mode) printf("Malloc %d should fail:\n", i);
+			should_fail = 1;
+		}
+        PR_SetMallocCountdown(i);
+        r1();
+        PR_ClearMallocCountdown();
+    }
+}
+
+int main(int argc, char **argv)
+{
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+    r2();
+
+    if(failed_already)    
+        return 1;
+    else
+        return 0;
+
+    
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dceemu.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dceemu.c
new file mode 100644
index 0000000..5e09a20
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dceemu.c
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        dceemu.c
+** Description: testing the DCE emulation api
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**             have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**            recognize the return code from tha main program.
+** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete).
+**/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+#include "prlog.h"
+#include "prinit.h"
+#include "prpdce.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_PR_DCETHREADS)
+
+PRIntn failed_already=0;
+PRIntn debug_mode=0;
+
+static PRIntn prmain(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PRP_NewNakedCondVar();
+    PRIntervalTime tenmsecs = PR_MillisecondsToInterval(10);
+
+    rv = PRP_TryLock(ml);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; 
+    
+    rv = PRP_TryLock(ml);
+    PR_ASSERT(PR_FAILURE == rv);
+    if ((rv != PR_FAILURE) & (!debug_mode)) failed_already=1; 
+
+    rv = PRP_NakedNotify(cv);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; 
+
+    rv = PRP_NakedBroadcast(cv);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; 
+
+    rv = PRP_NakedWait(cv, ml, tenmsecs);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1;     
+
+    PR_Unlock(ml);    
+        
+    rv = PRP_NakedNotify(cv);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1;     
+
+    rv = PRP_NakedBroadcast(cv);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1;     
+
+    PRP_DestroyNakedCondVar(cv);
+    PR_DestroyLock(ml);
+
+    if (debug_mode) printf("Test succeeded\n");
+
+    return 0;
+
+}  /* prmain */
+
+#endif /* #if defined(_PR_DCETHREADS) */
+
+int main(int argc, char **argv)
+{
+
+#if defined(_PR_DCETHREADS)
+    PR_Initialize(prmain, argc, argv, 0);
+    if(failed_already)    
+        return 1;
+    else
+        return 0;
+#else
+    return 0;
+#endif
+}  /* main */
+
+
+/* decemu.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/depend.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/depend.c
new file mode 100644
index 0000000..e3fb691
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/depend.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+**
+** Name:		depend.c
+** Description: Test to enumerate the dependencies
+*
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+#include "prinit.h"
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void PrintVersion(
+    const char *msg, const PRVersion* info, PRIntn tab)
+{
+    static const len = 20;
+    static const char *tabs = {"                    "};
+
+    tab *= 2;
+    if (tab > len) tab = len;
+    printf("%s", &tabs[len - tab]);
+    printf("%s ", msg);
+    printf("%s ", info->id);
+    printf("%d.%d", info->major, info->minor);
+    if (0 != info->patch)
+        printf(".p%d", info->patch);
+    printf("\n");
+}  /* PrintDependency */
+
+static void ChaseDependents(const PRVersionInfo *info, PRIntn tab)
+{
+    PrintVersion("exports", &info->selfExport, tab);
+    if (NULL != info->importEnumerator)
+    {
+        const PRDependencyInfo *dependent = NULL;
+        while (NULL != (dependent = info->importEnumerator(dependent)))
+        {
+            const PRVersionInfo *import = dependent->exportInfoFn();
+            PrintVersion("imports", &dependent->importNeeded, tab);
+            ChaseDependents(import, tab + 1);
+        }
+    }
+}  /* ChaseDependents */
+
+static PRVersionInfo hack_export;
+static PRVersionInfo dummy_export;
+static PRDependencyInfo dummy_imports[2];
+
+static const PRVersionInfo *HackExportInfo(void)
+{
+    hack_export.selfExport.major = 11;
+    hack_export.selfExport.minor = 10;
+    hack_export.selfExport.patch = 200;
+    hack_export.selfExport.id = "Hack";
+    hack_export.importEnumerator = NULL;
+    return &hack_export;
+}
+
+static const PRDependencyInfo *DummyImports(
+    const PRDependencyInfo *previous)
+{
+    if (NULL == previous) return &dummy_imports[0];
+    else if (&dummy_imports[0] == previous) return &dummy_imports[1];
+    else if (&dummy_imports[1] == previous) return NULL;
+}  /* DummyImports */
+
+static const PRVersionInfo *DummyLibVersion(void)
+{
+    dummy_export.selfExport.major = 1;
+    dummy_export.selfExport.minor = 0;
+    dummy_export.selfExport.patch = 0;
+    dummy_export.selfExport.id = "Dumbass application";
+    dummy_export.importEnumerator = DummyImports;
+
+    dummy_imports[0].importNeeded.major = 2;
+    dummy_imports[0].importNeeded.minor = 0;
+    dummy_imports[0].importNeeded.patch = 0;
+    dummy_imports[0].importNeeded.id = "Netscape Portable Runtime";
+    dummy_imports[0].exportInfoFn = PR_ExportInfo;
+
+    dummy_imports[1].importNeeded.major = 5;
+    dummy_imports[1].importNeeded.minor = 1;
+    dummy_imports[1].importNeeded.patch = 2;
+    dummy_imports[1].importNeeded.id = "Hack Library";
+    dummy_imports[1].exportInfoFn = HackExportInfo;
+
+    return &dummy_export;
+}  /* DummyLibVersion */
+
+int main(int argc, char **argv)
+{
+    PRIntn tab = 0;
+    const PRVersionInfo *info = DummyLibVersion();
+    const char *buildDate = __DATE__, *buildTime = __TIME__;
+
+    printf("Depend.c build time is %s %s\n", buildDate, buildTime);
+    
+    if (NULL != info) ChaseDependents(info, tab);
+
+    return 0;
+}  /* main */
+
+/* depend.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/Makefile.in
new file mode 100644
index 0000000..da2ae5a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/Makefile.in
@@ -0,0 +1,116 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+# Disable optimization of the nspr on SunOS4.1.3
+ifeq ($(OS_ARCH),SunOS)
+ifeq ($(OS_RELEASE),4.1.3_U1)
+OPTIMIZER =
+endif
+endif
+
+CSRCS = mygetval.c mysetval.c
+
+INCLUDES = -I$(dist_includedir)
+
+OBJS = $(OBJDIR)/mygetval.$(OBJ_SUFFIX) \
+	$(OBJDIR)/mysetval.$(OBJ_SUFFIX)
+
+ifeq ($(OS_TARGET), WIN16)
+W16OBJS = $(subst $(space),$(comma)$(space),$(OBJS))
+endif
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+# do nothing
+else
+RES=$(OBJDIR)/my.res
+RESNAME=../../../pr/src/nspr.rc
+endif
+endif
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+IMPORT_LIBRARY	= $(OBJDIR)/my.$(LIB_SUFFIX)
+SHARED_LIBRARY	= $(OBJDIR)/my.dll
+ifeq ($(OS_ARCH), OS2)
+MAPFILE		= $(OBJDIR)/my.def
+GARBAGE		+= $(MAPFILE)
+MKSHLIB		+= $(MAPFILE)
+endif
+TARGETS		= $(SHARED_LIBRARY) $(IMPORT_LIBRARY)
+else
+ifdef MKSHLIB
+SHARED_LIBRARY	= $(OBJDIR)/libmy.$(DLL_SUFFIX)
+endif
+TARGETS		= $(SHARED_LIBRARY)
+endif
+
+#
+# To create a loadable module on Darwin, we must override
+# -dynamiclib with -bundle.
+#
+ifeq ($(OS_ARCH),Darwin)
+DSO_LDOPTS = -bundle
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+ifeq ($(OS_TARGET), WIN16)
+# Note: The Win16 target: my.dll requires these macros
+# to be overridden to build the test .dll
+# default values in win16...mk are for release targets.
+#
+OS_DLL_OPTION = NOCASEEXACT
+OS_LIB_FLAGS = -irn
+endif
+
+ifdef SHARED_LIBRARY
+export:: $(TARGETS)
+
+clean::
+	rm -rf $(TARGETS)
+endif
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/my.def b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/my.def
new file mode 100644
index 0000000..76cdfd9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/my.def
@@ -0,0 +1,58 @@
+;+#
+;+# ***** BEGIN LICENSE BLOCK *****
+;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+;+#
+;+# The contents of this file are subject to the Mozilla Public License Version
+;+# 1.1 (the "License"); you may not use this file except in compliance with
+;+# the License. You may obtain a copy of the License at
+;+# http://www.mozilla.org/MPL/
+;+#
+;+# Software distributed under the License is distributed on an "AS IS" basis,
+;+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+;+# for the specific language governing rights and limitations under the
+;+# License.
+;+#
+;+# The Original Code is the Netscape Portable Runtime (NSPR).
+;+#
+;+# The Initial Developer of the Original Code is
+;+# Netscape Communications Corporation.
+;+# Portions created by the Initial Developer are Copyright (C) 2002-2003
+;+# the Initial Developer. All Rights Reserved.
+;+#
+;+# Contributor(s):
+;+#
+;+# Alternatively, the contents of this file may be used under the terms of
+;+# either the GNU General Public License Version 2 or later (the "GPL"), or
+;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+;+# in which case the provisions of the GPL or the LGPL are applicable instead
+;+# of those above. If you wish to allow use of your version of this file only
+;+# under the terms of either the GPL or the LGPL, and not to allow others to
+;+# use your version of this file under the terms of the MPL, indicate your
+;+# decision by deleting the provisions above and replace them with the notice
+;+# and other provisions required by the GPL or the LGPL. If you do not delete
+;+# the provisions above, a recipient may use your version of this file under
+;+# the terms of any one of the MPL, the GPL or the LGPL.
+;+#
+;+# ***** END LICENSE BLOCK *****
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS
+;+#   1. For all unix platforms, the string ";-"  means "remove this line"
+;+#   2. For all unix platforms, the string " DATA " will be removed from any 
+;+#     line on which it occurs.
+;+#   3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+#      On AIX, lines containing ";+" will be removed.
+;+#   4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+#   5. For all unix platforms, after the above processing has taken place,
+;+#    all characters after the first ";" on the line will be removed.
+;+#    And for AIX, the first ";" will also be removed.
+;+#  This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+#   directives are hidden behind ";", ";+", and ";-"
+;+#
+;+MY_1.0 {
+;+	global:
+LIBRARY my ;-
+EXPORTS ;-
+		My_GetValue;
+		My_SetValue;
+;+	local: *;
+;+};
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/mygetval.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/mygetval.c
new file mode 100644
index 0000000..17f3679
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/mygetval.c
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#if defined(WIN16)
+#include <windows.h>
+#endif
+#include "prtypes.h"
+
+extern PRIntn my_global;
+
+PR_IMPLEMENT(PRIntn) My_GetValue()
+{
+    return my_global;
+}
+
+#if defined(WIN16)
+int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg, 
+                      WORD cbHeapSize, LPSTR lpszCmdLine )
+{
+    return TRUE;
+}
+#endif /* WIN16 */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/mysetval.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/mysetval.c
new file mode 100644
index 0000000..982f077
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dll/mysetval.c
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prtypes.h"
+
+PRIntn my_global = 0;
+
+PR_IMPLEMENT(void) My_SetValue(PRIntn val)
+{
+    my_global = val;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dlltest.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dlltest.c
new file mode 100644
index 0000000..82a2db5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dlltest.c
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: dlltest.c
+**
+** Description: test dll functionality.
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+** 12-June-97 Revert to return code 0 and 1.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+#include "prinit.h"
+#include "prlink.h"
+#include "prmem.h"
+#include "prerror.h"
+
+#include "plstr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef PRIntn (PR_CALLBACK *GetFcnType)(void);
+typedef void (PR_CALLBACK *SetFcnType)(PRIntn);
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char** argv)
+{
+    PRLibrary *lib, *lib2;  /* two handles to the same library */
+    GetFcnType getFcn;
+    SetFcnType setFcn;
+    PRIntn value;
+    PRStatus status;
+    char *libName;
+
+    if (argc >= 2 && PL_strcmp(argv[1], "-d") == 0) {
+        debug_mode = 1;
+    }
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    /*
+     * Test 1: load the library, look up the symbols, call the functions,
+     * and check the results.
+     */
+
+    libName = PR_GetLibraryName("dll", "my");
+    if (debug_mode) printf("Loading library %s\n", libName);
+    lib = PR_LoadLibrary(libName);
+    PR_FreeLibraryName(libName);
+    if (lib == NULL) {
+        PRInt32 textLength = PR_GetErrorTextLength();
+        char *text = (char*)PR_MALLOC(textLength + 1);
+        text[0] = '\0';
+        (void)PR_GetErrorText(text);
+        fprintf(
+            stderr, "PR_LoadLibrary failed (%d, %d, %s)\n",
+            PR_GetError(), PR_GetOSError(), text);
+        if (!debug_mode) failed_already=1;
+    }
+    getFcn = (GetFcnType) PR_FindSymbol(lib, "My_GetValue");
+    setFcn = (SetFcnType) PR_FindFunctionSymbol(lib, "My_SetValue");
+    (*setFcn)(888);
+    value = (*getFcn)();
+    if (value != 888) {
+        fprintf(stderr, "Test 1 failed: set value to 888, but got %d\n", value);
+        if (!debug_mode) failed_already=1;
+    }
+    if (debug_mode) printf("Test 1 passed\n");
+
+    /*
+     * Test 2: get a second handle to the same library (this should increment
+     * the reference count), look up the symbols, call the functions, and
+     * check the results.
+     */
+
+    getFcn = (GetFcnType) PR_FindSymbolAndLibrary("My_GetValue", &lib2);
+    if (NULL == getFcn || lib != lib2) {
+        fprintf(stderr, "Test 2 failed: handles for the same library are not "
+            "equal: handle 1: %p, handle 2: %p\n", lib, lib2);
+        if (!debug_mode) failed_already=1;
+    }
+    setFcn = (SetFcnType) PR_FindSymbol(lib2, "My_SetValue");
+    value = (*getFcn)();
+    if (value != 888) {
+        fprintf(stderr, "Test 2 failed: value should be 888, but got %d\n",
+            value);
+        if (!debug_mode) failed_already=1;
+    }
+    (*setFcn)(777);
+    value = (*getFcn)();
+    if (value != 777) {
+        fprintf(stderr, "Test 2 failed: set value to 777, but got %d\n", value);
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    if (debug_mode) printf("Test 2 passed\n");
+
+    /*
+     * Test 3: unload the library.  The library should still be accessible
+     * via the second handle.  do the same things as above.
+     */
+
+    status = PR_UnloadLibrary(lib);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "Test 3 failed: cannot unload library: (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    getFcn = (GetFcnType) PR_FindFunctionSymbol(lib2, "My_GetValue");
+    setFcn = (SetFcnType) PR_FindSymbol(lib2, "My_SetValue");
+    (*setFcn)(666);
+    value = (*getFcn)();
+    if (value != 666) {
+        fprintf(stderr, "Test 3 failed: set value to 666, but got %d\n", value);
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    if (debug_mode) printf("Test 3 passed\n");
+
+    /*
+     * Test 4: unload the library, testing the reference count mechanism.
+     */
+
+    status = PR_UnloadLibrary(lib2);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "Test 4 failed: cannot unload library: (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    getFcn = (GetFcnType) PR_FindFunctionSymbolAndLibrary("My_GetValue", &lib2);
+    if (NULL != getFcn) {
+        fprintf(stderr, "Test 4 failed: how can we find a symbol "
+            "in an already unloaded library?\n");
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    if (debug_mode) {
+        printf("Test 4 passed\n");
+    }
+
+    /*
+    ** Test 5: LoadStaticLibrary()
+    */
+    {
+        PRStaticLinkTable   slt[10];
+        PRLibrary           *lib;
+        
+        lib = PR_LoadStaticLibrary( "my.dll", slt );
+        if ( lib == NULL )
+        {
+            fprintf(stderr, "Test 5: LoadStatiLibrary() failed\n" );
+            goto exit_now;
+        }
+        if (debug_mode)
+        {
+            printf("Test 5 passed\n");
+        }
+    }
+
+    goto exit_now;
+exit_now: 
+    PR_Cleanup();
+
+    if (failed_already) {
+        printf("FAILED\n");
+        return 1;
+    } else {
+        printf("PASSED\n");
+        return 0;
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/dtoa.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dtoa.c
new file mode 100644
index 0000000..f4939ac
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/dtoa.c
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/******************************************************************************
+ *
+ * This file contains a test program for the function conversion functions
+ * for double precision code:
+ * PR_strtod
+ * PR_dtoa
+ * PR_cnvtf
+ *
+ * This file was ns/nspr/tests/dtoa.c, created by rrj on 1996/06/22.
+ *
+ *****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <locale.h>
+#include "prprf.h"
+#include "prdtoa.h"
+
+static int failed_already = 0;
+
+int main(int argc, char **argv)
+{
+    double num;
+    double num1;
+    double zero = 0.0;
+    char   cnvt[50];
+    char  *thousands;
+    
+    num = 1e24;
+    num1 = PR_strtod("1e24",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1e24");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1e+24",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 0.001e7;
+    num1 = PR_strtod("0.001e7",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","0.001e7");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("10000",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 0.0000000000000753;
+    num1 = PR_strtod("0.0000000000000753",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"0.0000000000000753");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("7.53e-14",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 1.867e73;
+    num1 = PR_strtod("1.867e73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1.867e73");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1.867e+73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+
+    num = -1.867e73;
+    num1 = PR_strtod("-1.867e73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e73");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.867e+73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = -1.867e-73;
+    num1 = PR_strtod("-1.867e-73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e-73");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.867e-73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    /* Testing for infinity */
+    num = 1.0 / zero;
+    num1 = PR_strtod("1.867e765",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1.867e765");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("Infinity",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = -1.0 / zero;
+    num1 = PR_strtod("-1.867e765",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e765");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-Infinity",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    /* Testing for NaN. PR_strtod can't parse "NaN" and "Infinity" */
+    num = zero / zero;
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("NaN",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = - zero / zero;
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("NaN",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 1.0000000001e21;
+    num1 = PR_strtod("1.0000000001e21",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"1.0000000001e21");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1.0000000001e+21",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = -1.0000000001e-21;
+    num1 = PR_strtod("-1.0000000001e-21",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"-1.0000000001e-21");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.0000000001e-21",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    /*
+     * Bug 414772: should not exit with "Zero passed to d2b" in debug
+     * build.
+     */
+    num1 = PR_strtod("4e-356",NULL);
+
+    /*
+     * A very long input with ~384K digits.
+     * Bug 516396: Should not crash.
+     * Bug 521306: Should return 0 without converting the input.
+     */
+#define LENGTH (384 * 1024)
+    thousands = (char *)malloc(LENGTH);
+    thousands[0] = '0';
+    thousands[1] = '.';
+    memset(&thousands[2], '1', LENGTH - 3);
+    thousands[LENGTH - 1] = '\0';
+    num = 0;
+    num1 = PR_strtod(thousands,NULL);
+    free(thousands);
+    if(num1 != num){
+        fprintf(stderr,"Failed to convert numeric value %s\n",
+                "0.1111111111111111...");
+        failed_already = 1;
+    }
+
+    if (failed_already) {
+        printf("FAILED\n");
+    } else {
+        printf("PASSED\n");
+    }
+    return failed_already;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/env.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/env.c
new file mode 100644
index 0000000..ac1c441
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/env.c
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        env.c
+** Description: Testing environment variable operations
+**
+*/
+#include "prenv.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn  debug = 0;
+PRIntn  verbose = 0;
+PRBool  failedAlready = PR_FALSE;
+
+#define  ENVNAME    "NSPR_ENVIRONMENT_TEST_VARIABLE"
+#define  ENVVALUE   "The expected result"
+#define  ENVBUFSIZE 256
+
+char    *envBuf; /* buffer pointer. We leak memory here on purpose! */
+
+static char * NewBuffer( size_t size )
+{
+    char *buf = malloc( size );
+    if ( NULL == buf ) {
+        printf("env: NewBuffer() failed\n");
+        exit(1);
+    }
+    return(buf);
+} /* end NewBuffer() */
+
+int main(int argc, char **argv)
+{
+    char    *value;
+    PRStatus    rc;
+
+    {   /* Get command line options */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "vd");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+                break;
+            case 'v':  /* verbose */
+                verbose = 1;
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    } /* end block "Get command line options" */
+
+#if 0 
+    {
+        /*
+        ** This uses Windows native environment manipulation
+        ** as an experiment. Note the separation of namespace!
+        */
+        BOOL rv;
+        DWORD   size;
+        rv = SetEnvironmentVariable( ENVNAME, ENVVALUE );
+        if ( rv == 0 )  {
+            if (debug) printf("env: Shit! SetEnvironmentVariable() failed\n");
+            failedAlready = PR_TRUE;
+        }
+        if (verbose) printf("env: SetEnvironmentVariable() worked\n");
+
+        size = GetEnvironmentVariable( ENVNAME, envBuf, ENVBUFSIZE );    
+        if ( size == 0 )  {
+            if (debug) printf("env: Shit! GetEnvironmentVariable() failed. Found: %s\n", envBuf );
+            failedAlready = PR_TRUE;
+        }
+        if (verbose) printf("env: GetEnvironmentVariable() worked. Found: %s\n", envBuf);
+
+        value = PR_GetEnv( ENVNAME );
+        if ( (NULL == value ) || (strcmp( value, ENVVALUE)))  {
+            if (debug) printf( "env: PR_GetEnv() failed retrieving WinNative. Found: %s\n", value);
+            failedAlready = PR_TRUE;
+        }
+        if (verbose) printf("env: PR_GetEnv() worked. Found: %s\n", value);
+    }
+#endif
+
+    /* set an environment variable, read it back */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME "=" ENVVALUE );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (debug) printf( "env: PR_SetEnv() failed setting\n");
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_SetEnv() worked.\n");
+    }
+
+    value = PR_GetEnv( ENVNAME );
+    if ( (NULL == value ) || (strcmp( value, ENVVALUE)))  {
+        if (debug) printf( "env: PR_GetEnv() Failed after setting\n" );
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_GetEnv() worked after setting it. Found: %s\n", value );
+    }
+
+/* ---------------------------------------------------------------------- */
+    /* un-set the variable, using RAW name... should not work */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (verbose) printf( "env: PR_SetEnv() not un-set using RAW name. Good!\n");
+    } else {
+        if (debug) printf("env: PR_SetEnv() un-set using RAW name. Bad!\n" );
+        failedAlready = PR_TRUE;
+    }
+
+    value = PR_GetEnv( ENVNAME );
+    if ( NULL == value ) {
+        if (debug) printf("env: PR_GetEnv() after un-set using RAW name. Bad!\n" );
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf( "env: PR_GetEnv() after RAW un-set found: %s\n", value );
+    }
+    
+/* ---------------------------------------------------------------------- */
+    /* set it again ... */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME "=" ENVVALUE );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (debug) printf( "env: PR_SetEnv() failed setting the second time.\n");
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_SetEnv() worked.\n");
+    }
+
+    /* un-set the variable using the form name= */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME "=" );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (debug) printf( "env: PR_SetEnv() failed un-setting using name=\n");
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_SetEnv() un-set using name= worked\n" );
+    }
+
+    value = PR_GetEnv( ENVNAME );
+    if (( NULL == value ) || ( 0x00 == *value )) {
+        if (verbose) printf("env: PR_GetEnv() after un-set using name= worked\n" );
+    } else {
+        if (debug) printf( "env: PR_GetEnv() after un-set using name=. Found: %s\n", value );
+        failedAlready = PR_TRUE;
+    }
+/* ---------------------------------------------------------------------- */
+    /* un-set the variable using the form name= */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME "999=" );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (debug) printf( "env: PR_SetEnv() failed un-setting using name=\n");
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_SetEnv() un-set using name= worked\n" );
+    }
+
+    value = PR_GetEnv( ENVNAME "999" );
+    if (( NULL == value ) || ( 0x00 == *value )) {
+        if (verbose) printf("env: PR_GetEnv() after un-set using name= worked\n" );
+    } else {
+        if (debug) printf( "env: PR_GetEnv() after un-set using name=. Found: %s\n", value );
+        failedAlready = PR_TRUE;
+    }
+
+/* ---------------------------------------------------------------------- */
+    if (debug || verbose) printf("\n%s\n", (failedAlready)? "FAILED" : "PASSED" );
+    return( (failedAlready)? 1 : 0 );
+}  /* main() */
+
+/* env.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/errcodes.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/errcodes.c
new file mode 100644
index 0000000..9e9c573
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/errcodes.c
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: errcodes.c
+**
+** Description: print nspr error codes
+**
+*/
+#include "prerror.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+static int _debug_on = 0;
+
+struct errinfo {
+	PRErrorCode errcode;
+	char 		*errname;
+};
+
+struct errinfo errcodes[] = {
+{PR_OUT_OF_MEMORY_ERROR,			"PR_OUT_OF_MEMORY_ERROR"},
+{PR_BAD_DESCRIPTOR_ERROR,			"PR_BAD_DESCRIPTOR_ERROR"},
+{PR_WOULD_BLOCK_ERROR,				"PR_WOULD_BLOCK_ERROR"},
+{PR_ACCESS_FAULT_ERROR,				"PR_ACCESS_FAULT_ERROR"},
+{PR_INVALID_METHOD_ERROR,			"PR_INVALID_METHOD_ERROR"},
+{PR_ILLEGAL_ACCESS_ERROR,			"PR_ILLEGAL_ACCESS_ERROR"},
+{PR_UNKNOWN_ERROR,					"PR_UNKNOWN_ERROR"},
+{PR_PENDING_INTERRUPT_ERROR,		"PR_PENDING_INTERRUPT_ERROR"},
+{PR_NOT_IMPLEMENTED_ERROR,			"PR_NOT_IMPLEMENTED_ERROR"},
+{PR_IO_ERROR,						"PR_IO_ERROR"},
+{PR_IO_TIMEOUT_ERROR,				"PR_IO_TIMEOUT_ERROR"},
+{PR_IO_PENDING_ERROR,				"PR_IO_PENDING_ERROR"},
+{PR_DIRECTORY_OPEN_ERROR,			"PR_DIRECTORY_OPEN_ERROR"},
+{PR_INVALID_ARGUMENT_ERROR,			"PR_INVALID_ARGUMENT_ERROR"},
+{PR_ADDRESS_NOT_AVAILABLE_ERROR,	"PR_ADDRESS_NOT_AVAILABLE_ERROR"},
+{PR_ADDRESS_NOT_SUPPORTED_ERROR,	"PR_ADDRESS_NOT_SUPPORTED_ERROR"},
+{PR_IS_CONNECTED_ERROR,				"PR_IS_CONNECTED_ERROR"},
+{PR_BAD_ADDRESS_ERROR,				"PR_BAD_ADDRESS_ERROR"},
+{PR_ADDRESS_IN_USE_ERROR,			"PR_ADDRESS_IN_USE_ERROR"},
+{PR_CONNECT_REFUSED_ERROR,			"PR_CONNECT_REFUSED_ERROR"},
+{PR_NETWORK_UNREACHABLE_ERROR,		"PR_NETWORK_UNREACHABLE_ERROR"},
+{PR_CONNECT_TIMEOUT_ERROR,			"PR_CONNECT_TIMEOUT_ERROR"},
+{PR_NOT_CONNECTED_ERROR,			"PR_NOT_CONNECTED_ERROR"},
+{PR_LOAD_LIBRARY_ERROR,				"PR_LOAD_LIBRARY_ERROR"},
+{PR_UNLOAD_LIBRARY_ERROR,			"PR_UNLOAD_LIBRARY_ERROR"},
+{PR_FIND_SYMBOL_ERROR,				"PR_FIND_SYMBOL_ERROR"},
+{PR_INSUFFICIENT_RESOURCES_ERROR,	"PR_INSUFFICIENT_RESOURCES_ERROR"},
+{PR_DIRECTORY_LOOKUP_ERROR,			"PR_DIRECTORY_LOOKUP_ERROR"},
+{PR_TPD_RANGE_ERROR,				"PR_TPD_RANGE_ERROR"},
+{PR_PROC_DESC_TABLE_FULL_ERROR,		"PR_PROC_DESC_TABLE_FULL_ERROR"},
+{PR_SYS_DESC_TABLE_FULL_ERROR,		"PR_SYS_DESC_TABLE_FULL_ERROR"},
+{PR_NOT_SOCKET_ERROR,				"PR_NOT_SOCKET_ERROR"},
+{PR_NOT_TCP_SOCKET_ERROR,			"PR_NOT_TCP_SOCKET_ERROR"},
+{PR_SOCKET_ADDRESS_IS_BOUND_ERROR,	"PR_SOCKET_ADDRESS_IS_BOUND_ERROR"},
+{PR_NO_ACCESS_RIGHTS_ERROR,			"PR_NO_ACCESS_RIGHTS_ERROR"},
+{PR_OPERATION_NOT_SUPPORTED_ERROR,	"PR_OPERATION_NOT_SUPPORTED_ERROR"},
+{PR_PROTOCOL_NOT_SUPPORTED_ERROR,	"PR_PROTOCOL_NOT_SUPPORTED_ERROR"},
+{PR_REMOTE_FILE_ERROR,				"PR_REMOTE_FILE_ERROR"},
+{PR_BUFFER_OVERFLOW_ERROR,			"PR_BUFFER_OVERFLOW_ERROR"},
+{PR_CONNECT_RESET_ERROR,			"PR_CONNECT_RESET_ERROR"},
+{PR_RANGE_ERROR,					"PR_RANGE_ERROR"},
+{PR_DEADLOCK_ERROR,					"PR_DEADLOCK_ERROR"},
+{PR_FILE_IS_LOCKED_ERROR,			"PR_FILE_IS_LOCKED_ERROR"},
+{PR_FILE_TOO_BIG_ERROR,				"PR_FILE_TOO_BIG_ERROR"},
+{PR_NO_DEVICE_SPACE_ERROR,			"PR_NO_DEVICE_SPACE_ERROR"},
+{PR_PIPE_ERROR,						"PR_PIPE_ERROR"},
+{PR_NO_SEEK_DEVICE_ERROR,			"PR_NO_SEEK_DEVICE_ERROR"},
+{PR_IS_DIRECTORY_ERROR,				"PR_IS_DIRECTORY_ERROR"},
+{PR_LOOP_ERROR,						"PR_LOOP_ERROR"},
+{PR_NAME_TOO_LONG_ERROR,			"PR_NAME_TOO_LONG_ERROR"},
+{PR_FILE_NOT_FOUND_ERROR,			"PR_FILE_NOT_FOUND_ERROR"},
+{PR_NOT_DIRECTORY_ERROR,			"PR_NOT_DIRECTORY_ERROR"},
+{PR_READ_ONLY_FILESYSTEM_ERROR,		"PR_READ_ONLY_FILESYSTEM_ERROR"},
+{PR_DIRECTORY_NOT_EMPTY_ERROR,		"PR_DIRECTORY_NOT_EMPTY_ERROR"},
+{PR_FILESYSTEM_MOUNTED_ERROR,		"PR_FILESYSTEM_MOUNTED_ERROR"},
+{PR_NOT_SAME_DEVICE_ERROR,			"PR_NOT_SAME_DEVICE_ERROR"},
+{PR_DIRECTORY_CORRUPTED_ERROR,		"PR_DIRECTORY_CORRUPTED_ERROR"},
+{PR_FILE_EXISTS_ERROR,				"PR_FILE_EXISTS_ERROR"},
+{PR_MAX_DIRECTORY_ENTRIES_ERROR,	"PR_MAX_DIRECTORY_ENTRIES_ERROR"},
+{PR_INVALID_DEVICE_STATE_ERROR,		"PR_INVALID_DEVICE_STATE_ERROR"},
+{PR_DEVICE_IS_LOCKED_ERROR,			"PR_DEVICE_IS_LOCKED_ERROR"},
+{PR_NO_MORE_FILES_ERROR,			"PR_NO_MORE_FILES_ERROR"},
+{PR_END_OF_FILE_ERROR,				"PR_END_OF_FILE_ERROR"},
+{PR_FILE_SEEK_ERROR,				"PR_FILE_SEEK_ERROR"},
+{PR_FILE_IS_BUSY_ERROR,				"PR_FILE_IS_BUSY_ERROR"},
+{PR_IN_PROGRESS_ERROR,				"PR_IN_PROGRESS_ERROR"},
+{PR_ALREADY_INITIATED_ERROR,		"PR_ALREADY_INITIATED_ERROR"},
+{PR_GROUP_EMPTY_ERROR,				"PR_GROUP_EMPTY_ERROR"},
+{PR_INVALID_STATE_ERROR,			"PR_INVALID_STATE_ERROR"},
+{PR_NETWORK_DOWN_ERROR,				"PR_NETWORK_DOWN_ERROR"},
+{PR_SOCKET_SHUTDOWN_ERROR,			"PR_SOCKET_SHUTDOWN_ERROR"},
+{PR_CONNECT_ABORTED_ERROR,			"PR_CONNECT_ABORTED_ERROR"},
+{PR_HOST_UNREACHABLE_ERROR,			"PR_HOST_UNREACHABLE_ERROR"}
+};
+
+int main(int argc, char **argv)
+{
+
+	int count, errnum;
+
+    /*
+     * -d           debug mode
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+	count = sizeof(errcodes)/sizeof(errcodes[0]);
+	printf("\nNumber of error codes = %d\n\n",count);
+	for (errnum = 0; errnum < count; errnum++) {
+		printf("%-40s = %d\n",errcodes[errnum].errname,
+						errcodes[errnum].errcode);
+	}
+
+	return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/errset.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/errset.c
new file mode 100644
index 0000000..0e690c0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/errset.c
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: errset.c
+**
+** Description: errset.c exercises the functions in prerror.c.
+** This code is a unit test of the prerror.c capability.
+**
+** Note: There's some fluff in here. The guts of the test
+** were plagerized from another test. So, sue me.
+**
+**
+*/
+#include "prerror.h"
+#include "plgetopt.h"
+#include "prlog.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static int _debug_on = 0;
+
+struct errinfo {
+	PRErrorCode errcode;
+	char 		*errname;
+};
+
+struct errinfo errcodes[] = {
+{PR_OUT_OF_MEMORY_ERROR,			"PR_OUT_OF_MEMORY_ERROR"},
+{PR_UNKNOWN_ERROR, "An intentionally long error message text intended to force a delete of the current errorString buffer and get another one."},
+{PR_BAD_DESCRIPTOR_ERROR,			"PR_BAD_DESCRIPTOR_ERROR"},
+{PR_WOULD_BLOCK_ERROR,				"PR_WOULD_BLOCK_ERROR"},
+{PR_ACCESS_FAULT_ERROR,				"PR_ACCESS_FAULT_ERROR"},
+{PR_INVALID_METHOD_ERROR,			"PR_INVALID_METHOD_ERROR"},
+{PR_ILLEGAL_ACCESS_ERROR,			"PR_ILLEGAL_ACCESS_ERROR"},
+{PR_UNKNOWN_ERROR,					"PR_UNKNOWN_ERROR"},
+{PR_PENDING_INTERRUPT_ERROR,		"PR_PENDING_INTERRUPT_ERROR"},
+{PR_NOT_IMPLEMENTED_ERROR,			"PR_NOT_IMPLEMENTED_ERROR"},
+{PR_IO_ERROR,						"PR_IO_ERROR"},
+{PR_IO_TIMEOUT_ERROR,				"PR_IO_TIMEOUT_ERROR"},
+{PR_IO_PENDING_ERROR,				"PR_IO_PENDING_ERROR"},
+{PR_DIRECTORY_OPEN_ERROR,			"PR_DIRECTORY_OPEN_ERROR"},
+{PR_INVALID_ARGUMENT_ERROR,			"PR_INVALID_ARGUMENT_ERROR"},
+{PR_ADDRESS_NOT_AVAILABLE_ERROR,	"PR_ADDRESS_NOT_AVAILABLE_ERROR"},
+{PR_ADDRESS_NOT_SUPPORTED_ERROR,	"PR_ADDRESS_NOT_SUPPORTED_ERROR"},
+{PR_IS_CONNECTED_ERROR,				"PR_IS_CONNECTED_ERROR"},
+{PR_BAD_ADDRESS_ERROR,				"PR_BAD_ADDRESS_ERROR"},
+{PR_ADDRESS_IN_USE_ERROR,			"PR_ADDRESS_IN_USE_ERROR"},
+{PR_CONNECT_REFUSED_ERROR,			"PR_CONNECT_REFUSED_ERROR"},
+{PR_NETWORK_UNREACHABLE_ERROR,		"PR_NETWORK_UNREACHABLE_ERROR"},
+{PR_CONNECT_TIMEOUT_ERROR,			"PR_CONNECT_TIMEOUT_ERROR"},
+{PR_NOT_CONNECTED_ERROR,			"PR_NOT_CONNECTED_ERROR"},
+{PR_LOAD_LIBRARY_ERROR,				"PR_LOAD_LIBRARY_ERROR"},
+{PR_UNLOAD_LIBRARY_ERROR,			"PR_UNLOAD_LIBRARY_ERROR"},
+{PR_FIND_SYMBOL_ERROR,				"PR_FIND_SYMBOL_ERROR"},
+{PR_INSUFFICIENT_RESOURCES_ERROR,	"PR_INSUFFICIENT_RESOURCES_ERROR"},
+{PR_DIRECTORY_LOOKUP_ERROR,			"PR_DIRECTORY_LOOKUP_ERROR"},
+{PR_TPD_RANGE_ERROR,				"PR_TPD_RANGE_ERROR"},
+{PR_PROC_DESC_TABLE_FULL_ERROR,		"PR_PROC_DESC_TABLE_FULL_ERROR"},
+{PR_SYS_DESC_TABLE_FULL_ERROR,		"PR_SYS_DESC_TABLE_FULL_ERROR"},
+{PR_NOT_SOCKET_ERROR,				"PR_NOT_SOCKET_ERROR"},
+{PR_NOT_TCP_SOCKET_ERROR,			"PR_NOT_TCP_SOCKET_ERROR"},
+{PR_SOCKET_ADDRESS_IS_BOUND_ERROR,	"PR_SOCKET_ADDRESS_IS_BOUND_ERROR"},
+{PR_NO_ACCESS_RIGHTS_ERROR,			"PR_NO_ACCESS_RIGHTS_ERROR"},
+{PR_OPERATION_NOT_SUPPORTED_ERROR,	"PR_OPERATION_NOT_SUPPORTED_ERROR"},
+{PR_PROTOCOL_NOT_SUPPORTED_ERROR,	"PR_PROTOCOL_NOT_SUPPORTED_ERROR"},
+{PR_REMOTE_FILE_ERROR,				"PR_REMOTE_FILE_ERROR"},
+{PR_BUFFER_OVERFLOW_ERROR,			"PR_BUFFER_OVERFLOW_ERROR"},
+{PR_CONNECT_RESET_ERROR,			"PR_CONNECT_RESET_ERROR"},
+{PR_RANGE_ERROR,					"PR_RANGE_ERROR"},
+{PR_DEADLOCK_ERROR,					"PR_DEADLOCK_ERROR"},
+{PR_FILE_IS_LOCKED_ERROR,			"PR_FILE_IS_LOCKED_ERROR"},
+{PR_FILE_TOO_BIG_ERROR,				"PR_FILE_TOO_BIG_ERROR"},
+{PR_NO_DEVICE_SPACE_ERROR,			"PR_NO_DEVICE_SPACE_ERROR"},
+{PR_PIPE_ERROR,						"PR_PIPE_ERROR"},
+{PR_NO_SEEK_DEVICE_ERROR,			"PR_NO_SEEK_DEVICE_ERROR"},
+{PR_IS_DIRECTORY_ERROR,				"PR_IS_DIRECTORY_ERROR"},
+{PR_LOOP_ERROR,						"PR_LOOP_ERROR"},
+{PR_NAME_TOO_LONG_ERROR,			"PR_NAME_TOO_LONG_ERROR"},
+{PR_FILE_NOT_FOUND_ERROR,			"PR_FILE_NOT_FOUND_ERROR"},
+{PR_NOT_DIRECTORY_ERROR,			"PR_NOT_DIRECTORY_ERROR"},
+{PR_READ_ONLY_FILESYSTEM_ERROR,		"PR_READ_ONLY_FILESYSTEM_ERROR"},
+{PR_DIRECTORY_NOT_EMPTY_ERROR,		"PR_DIRECTORY_NOT_EMPTY_ERROR"},
+{PR_FILESYSTEM_MOUNTED_ERROR,		"PR_FILESYSTEM_MOUNTED_ERROR"},
+{PR_NOT_SAME_DEVICE_ERROR,			"PR_NOT_SAME_DEVICE_ERROR"},
+{PR_DIRECTORY_CORRUPTED_ERROR,		"PR_DIRECTORY_CORRUPTED_ERROR"},
+{PR_FILE_EXISTS_ERROR,				"PR_FILE_EXISTS_ERROR"},
+{PR_MAX_DIRECTORY_ENTRIES_ERROR,	"PR_MAX_DIRECTORY_ENTRIES_ERROR"},
+{PR_INVALID_DEVICE_STATE_ERROR,		"PR_INVALID_DEVICE_STATE_ERROR"},
+{PR_DEVICE_IS_LOCKED_ERROR,			"PR_DEVICE_IS_LOCKED_ERROR"},
+{PR_NO_MORE_FILES_ERROR,			"PR_NO_MORE_FILES_ERROR"},
+{PR_END_OF_FILE_ERROR,				"PR_END_OF_FILE_ERROR"},
+{PR_FILE_SEEK_ERROR,				"PR_FILE_SEEK_ERROR"},
+{PR_FILE_IS_BUSY_ERROR,				"PR_FILE_IS_BUSY_ERROR"},
+{PR_IN_PROGRESS_ERROR,				"PR_IN_PROGRESS_ERROR"},
+{PR_ALREADY_INITIATED_ERROR,		"PR_ALREADY_INITIATED_ERROR"},
+{PR_GROUP_EMPTY_ERROR,				"PR_GROUP_EMPTY_ERROR"},
+{PR_INVALID_STATE_ERROR,			"PR_INVALID_STATE_ERROR"},
+{PR_NETWORK_DOWN_ERROR,				"PR_NETWORK_DOWN_ERROR"},
+{PR_SOCKET_SHUTDOWN_ERROR,			"PR_SOCKET_SHUTDOWN_ERROR"},
+{PR_CONNECT_ABORTED_ERROR,			"PR_CONNECT_ABORTED_ERROR"},
+{PR_HOST_UNREACHABLE_ERROR,			"PR_HOST_UNREACHABLE_ERROR"}
+};
+
+int main(int argc, char **argv)
+{
+
+	int count, errnum;
+
+    /*
+     * -d           debug mode
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+	count = sizeof(errcodes)/sizeof(errcodes[0]);
+	printf("\nNumber of error codes = %d\n\n",count);
+	for (errnum = 0; errnum < count; errnum++) {
+        PRInt32 len1, len2, err;
+        char    msg[256];
+
+        PR_SetError( errnum, -5 );
+        err = PR_GetError();
+        PR_ASSERT( err == errnum );
+        err = PR_GetOSError();
+        PR_ASSERT( err == -5 );
+        PR_SetErrorText( strlen(errcodes[errnum].errname), errcodes[errnum].errname );
+        len1 = PR_GetErrorTextLength();
+        len2 = PR_GetErrorText( msg );
+        PR_ASSERT( len1 == len2 );
+        printf("%5.5d -- %s\n", errnum, msg );
+    }
+
+	return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/exit.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/exit.c
new file mode 100644
index 0000000..8ecf50a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/exit.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prprf.h"
+#include "prinit.h"
+#include "prthread.h"
+#include "prproces.h"
+#include "prinrval.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+static PRInt32 dally = 0;
+static PRFileDesc *err = NULL;
+static PRBool verbose = PR_FALSE, force = PR_FALSE;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-t s] [-h]\n");
+    PR_fprintf(err, "\t-d   Verbose output              (default: FALSE)\n");
+    PR_fprintf(err, "\t-x   Forced termination          (default: FALSE)\n");
+    PR_fprintf(err, "\t-t   Time for thread to block    (default: 10 seconds)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+static void Dull(void *arg)
+{
+    PR_Sleep(PR_SecondsToInterval(dally));
+    if (verbose && force)
+        PR_fprintf(err, "If you see this, the test failed\n");
+}  /* Dull */
+
+static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv)
+{
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "ht:dx");
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* verbosity */
+            verbose = PR_TRUE;
+            break;
+        case 'x':  /* force exit */
+            force = PR_TRUE;
+            break;
+        case 't':  /* seconds to dally in child */
+            dally = atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+        default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (0 == dally) dally = 10;
+
+	/*
+	 * Create LOCAL and GLOBAL threads
+	 */
+    (void)PR_CreateThread(
+        PR_USER_THREAD, Dull, NULL, PR_PRIORITY_NORMAL,
+			  PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    (void)PR_CreateThread(
+        PR_USER_THREAD, Dull, NULL, PR_PRIORITY_NORMAL,
+			  PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    if (verbose)
+        PR_fprintf(
+            err, "Main is exiting now. Program should exit %s.\n",
+            (force) ? "immediately" : "after child dally time");
+
+    if (force)
+    {
+        PR_ProcessExit(0);
+        if (verbose)
+        {
+            PR_fprintf(err, "You should not have gotten here.\n");
+            return 1;
+        }
+    }
+    return 0;
+        
+}
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/fdcach.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/fdcach.c
new file mode 100644
index 0000000..33382fa
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/fdcach.c
@@ -0,0 +1,259 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: fdcach.c
+ * Description:
+ *   This test verifies that the fd cache and stack are working
+ *   correctly.
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Define ORDER_PRESERVED if the implementation of PR_SetFDCacheSize
+ * preserves the ordering of the fd's when moving them between the
+ * cache and the stack.
+ */
+#define ORDER_PRESERVED 1
+
+/*
+ * NUM_FDS must be <= FD_CACHE_SIZE.
+ */
+#define FD_CACHE_SIZE 1024
+#define NUM_FDS 20
+
+int main(int argc, char **argv)
+{
+    int i;
+    PRFileDesc *fds[NUM_FDS];
+    PRFileDesc *savefds[NUM_FDS];
+    int numfds = sizeof(fds)/sizeof(fds[0]);
+
+    /*
+     * Switch between cache and stack when they are empty.
+     * Then start with the fd cache.
+     */
+    PR_SetFDCacheSize(0, FD_CACHE_SIZE);
+    PR_SetFDCacheSize(0, 0);
+    PR_SetFDCacheSize(0, FD_CACHE_SIZE);
+
+    /* Add some fd's to the fd cache. */
+    for (i = 0; i < numfds; i++) {
+        savefds[i] = PR_NewTCPSocket();
+        if (NULL == savefds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /*
+     * Create some fd's.  These fd's should come from
+     * the fd cache.  Verify the FIFO ordering of the fd
+     * cache.
+     */
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (fds[i] != savefds[i]) {
+            fprintf(stderr, "fd cache malfunctioned\n");
+            exit(1);
+        }
+    }
+    /* Put the fd's back to the fd cache. */
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /* Switch to the fd stack. */
+    PR_SetFDCacheSize(0, 0);
+
+    /*
+     * Create some fd's.  These fd's should come from
+     * the fd stack.
+     */
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+#ifdef ORDER_PRESERVED
+        if (fds[i] != savefds[numfds-1-i]) {
+            fprintf(stderr, "fd stack malfunctioned\n");
+            exit(1);
+        }
+#else
+        savefds[numfds-1-i] = fds[i];
+#endif
+    }
+    /* Put the fd's back to the fd stack. */
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /*
+     * Now create some fd's and verify the LIFO ordering of
+     * the fd stack.
+     */
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (fds[i] != savefds[numfds-1-i]) {
+            fprintf(stderr, "fd stack malfunctioned\n");
+            exit(1);
+        }
+    }
+    /* Put the fd's back to the fd stack. */
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /* Switch to the fd cache. */
+    PR_SetFDCacheSize(0, FD_CACHE_SIZE);
+
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+#ifdef ORDER_PRESERVED
+        if (fds[i] != savefds[i]) {
+            fprintf(stderr, "fd cache malfunctioned\n");
+            exit(1);
+        }
+#else
+        savefds[i] = fds[i];
+#endif
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (fds[i] != savefds[i]) {
+            fprintf(stderr, "fd cache malfunctioned\n");
+            exit(1);
+        }
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /* Switch to the fd stack. */
+    PR_SetFDCacheSize(0, 0);
+
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+#ifdef ORDER_PRESERVED
+        if (fds[i] != savefds[numfds-1-i]) {
+            fprintf(stderr, "fd stack malfunctioned\n");
+            exit(1);
+        }
+#else
+        savefds[numfds-1-i];
+#endif
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (fds[i] != savefds[numfds-1-i]) {
+            fprintf(stderr, "fd stack malfunctioned\n");
+            exit(1);
+        }
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    PR_Cleanup();
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/fileio.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/fileio.c
new file mode 100644
index 0000000..efd4235
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/fileio.c
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: fileio.c
+**
+** Description: Program to copy one file to another. 
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete).
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+#include "prinit.h"
+#include "prthread.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "prmon.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prlog.h"
+
+#include <stdio.h>
+
+#include "obsolete/prsem.h"
+
+
+#define TBSIZE 1024
+
+static PRUint8 tbuf[TBSIZE];
+
+static PRFileDesc *t1, *t2;
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+static void InitialSetup(void)
+{
+	PRUintn	i;
+	PRInt32 nWritten, rv;
+	
+	t1 = PR_Open("t1.tmp", PR_CREATE_FILE | PR_RDWR, 0);
+	PR_ASSERT(t1 != NULL);	
+	
+	for (i=0; i<TBSIZE; i++)
+		tbuf[i] = i;
+		
+	nWritten = PR_Write((PRFileDesc*)t1, tbuf, TBSIZE);
+	PR_ASSERT(nWritten == TBSIZE);	
+   		
+	rv = PR_Seek(t1,0,PR_SEEK_SET);
+	PR_ASSERT(rv == 0);	
+
+   	t2 = PR_Open("t2.tmp", PR_CREATE_FILE | PR_RDWR, 0);
+	PR_ASSERT(t2 != NULL);	
+}
+
+
+static void VerifyAndCleanup(void)
+{
+	PRUintn	i;
+	PRInt32 nRead, rv;
+	
+	for (i=0; i<TBSIZE; i++)
+		tbuf[i] = 0;
+		
+	rv = PR_Seek(t2,0,PR_SEEK_SET);
+	PR_ASSERT(rv == 0);	
+
+	nRead = PR_Read((PRFileDesc*)t2, tbuf, TBSIZE);
+	PR_ASSERT(nRead == TBSIZE);	
+   		
+	for (i=0; i<TBSIZE; i++)
+		if (tbuf[i] != (PRUint8)i) {
+			if (debug_mode) printf("data mismatch for index= %d \n", i);
+			else failed_already=1;
+		}
+   	PR_Close(t1);
+   	PR_Close(t2);
+
+   	PR_Delete("t1.tmp");
+   	PR_Delete("t2.tmp");
+
+    if (debug_mode) printf("fileio test passed\n");
+}
+
+
+/*------------------ Following is the real test program ---------*/
+/*
+	Program to copy one file to another.  Two temporary files get
+	created.  First one gets written in one write call.  Then,
+	a reader thread reads from this file into a double buffer.
+	The writer thread writes from double buffer into the other
+	temporary file.  The second temporary file gets verified
+	for accurate data.
+*/
+
+PRSemaphore	*emptyBufs;	/* number of empty buffers */
+PRSemaphore *fullBufs;	/* number of buffers that are full */
+
+#define BSIZE	100
+
+struct {
+	char data[BSIZE];
+	PRUintn nbytes;		/* number of bytes in this buffer */
+} buf[2];
+
+static void PR_CALLBACK reader(void *arg)
+{
+	PRUintn	i = 0;
+	PRInt32	nbytes;
+	
+	do {
+		(void) PR_WaitSem(emptyBufs);
+		nbytes = PR_Read((PRFileDesc*)arg, buf[i].data, BSIZE);
+		if (nbytes >= 0) {
+			buf[i].nbytes = nbytes;
+			PR_PostSem(fullBufs);
+			i = (i + 1) % 2;
+		}
+	} while (nbytes > 0);
+}
+
+static void PR_CALLBACK writer(void *arg)
+{
+	PRUintn	i = 0;
+	PRInt32	nbytes;
+	
+	do {
+		(void) PR_WaitSem(fullBufs);
+		nbytes = buf[i].nbytes;
+		if (nbytes > 0) {
+			nbytes = PR_Write((PRFileDesc*)arg, buf[i].data, nbytes);
+			PR_PostSem(emptyBufs);
+			i = (i + 1) % 2;
+		}
+	} while (nbytes > 0);
+}
+
+int main(int argc, char **argv)
+{
+	PRThread *r, *w;
+
+
+	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    emptyBufs = PR_NewSem(2);	/* two empty buffers */
+
+    fullBufs = PR_NewSem(0);	/* zero full buffers */
+
+	/* Create initial temp file setup */
+	InitialSetup();
+	
+	/* create the reader thread */
+	
+	r = PR_CreateThread(PR_USER_THREAD,
+				      reader, t1, 
+				      PR_PRIORITY_NORMAL,
+				      PR_LOCAL_THREAD,
+    				  PR_JOINABLE_THREAD,
+				      0);
+
+	w = PR_CreateThread(PR_USER_THREAD,
+				      writer, t2, 
+				      PR_PRIORITY_NORMAL,
+                      PR_LOCAL_THREAD,
+                      PR_JOINABLE_THREAD,
+                      0);
+
+    /* Do the joining for both threads */
+    (void) PR_JoinThread(r);
+    (void) PR_JoinThread(w);
+
+    /* Do the verification and clean up */
+    VerifyAndCleanup();
+
+    PR_DestroySem(emptyBufs);
+    PR_DestroySem(fullBufs);
+
+    PR_Cleanup();
+
+    if(failed_already)
+    {
+        printf("Fail\n");
+        return 1;
+    }
+    else
+    {
+        printf("PASS\n");
+        return 0;
+    }
+
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/foreign.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/foreign.c
new file mode 100644
index 0000000..68acc16
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/foreign.c
@@ -0,0 +1,385 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        foreign.c
+** Description: Testing various functions w/ foreign threads
+**
+**      We create a thread and get it to call exactly one runtime function.
+**      The thread is allowed to be created by some other environment that
+**      NSPR, but it does not announce itself to the runtime prior to calling
+**      in.
+**
+**      The goal: try to survive.
+**      
+*/
+
+#include "prcvar.h"
+#include "prenv.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmem.h"
+#include "prthread.h"
+#include "prtypes.h"
+#include "prprf.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static enum {
+    thread_nspr, thread_pthread, thread_sproc, thread_win32
+} thread_provider;
+
+typedef void (*StartFn)(void*);
+typedef struct StartObject
+{
+    StartFn start;
+    void *arg;
+} StartObject;
+
+static PRFileDesc *output;
+
+static int _debug_on = 0;
+
+#define DEFAULT_THREAD_COUNT	10
+
+#define DPRINTF(arg)	if (_debug_on) PR_fprintf arg
+
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#include "md/_pth.h"
+static void *pthread_start(void *arg)
+{
+    StartFn start = ((StartObject*)arg)->start;
+    void *data = ((StartObject*)arg)->arg;
+    PR_Free(arg);
+    start(data);
+    return NULL;
+}  /* pthread_start */
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+#include <sys/types.h>
+#include <sys/prctl.h>
+static void sproc_start(void *arg, PRSize size)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+}  /* sproc_start */
+#endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
+
+#if defined(WIN32)
+#if defined(WINCE)
+#include <windows.h>
+#endif
+#include <process.h>  /* for _beginthreadex() */
+
+static PRUintn __stdcall windows_start(void *arg)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+    return 0;
+}  /* windows_start */
+#endif /* defined(WIN32) */
+
+static PRStatus NSPRPUB_TESTS_CreateThread(StartFn start, void *arg)
+{
+    PRStatus rv;
+
+    switch (thread_provider)
+    {
+    case thread_nspr:
+        {
+            PRThread *thread = PR_CreateThread(
+                PR_USER_THREAD, start, arg,
+                PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+                PR_UNJOINABLE_THREAD, 0);
+            rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS;
+        }
+        break;
+    case thread_pthread:
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+        {
+            int rv;
+            pthread_t id;
+            pthread_attr_t tattr;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+
+            rv = _PT_PTHREAD_ATTR_INIT(&tattr);
+            PR_ASSERT(0 == rv);
+
+            rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+            PR_ASSERT(0 == rv);
+
+            rv = pthread_attr_setstacksize(&tattr, 64 * 1024);
+            PR_ASSERT(0 == rv);
+
+            rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object);
+            (void)_PT_PTHREAD_ATTR_DESTROY(&tattr);
+            return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+        break;
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+
+    case thread_sproc:
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+        {
+            PRInt32 pid;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+            pid = sprocsp(
+                sproc_start, PR_SALL, start_object, NULL, 64 * 1024);
+            rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
+        break;
+    case thread_win32:
+#if defined(WIN32)
+        {
+            void *th;
+            PRUintn id;       
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+            th = (void*)_beginthreadex(
+                NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */  
+                0U, /* DWORD - initial thread stack size, in bytes */
+                windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */
+                start_object, /* LPVOID - argument for new thread */
+                0U, /*DWORD dwCreationFlags - creation flags */
+                &id /* LPDWORD - pointer to returned thread identifier */ );
+
+            rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif
+        break;
+    default:
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+    }
+    return rv;
+}  /* NSPRPUB_TESTS_CreateThread */
+
+static void PR_CALLBACK lazyEntry(void *arg)
+{
+    PR_ASSERT(NULL == arg);
+}  /* lazyEntry */
+
+
+static void OneShot(void *arg)
+{
+    PRUintn pdkey;
+    PRLock *lock;
+    PRFileDesc *fd;
+    PRDir *dir;
+    PRFileDesc *pair[2];
+    PRIntn test = (PRIntn)arg;
+
+	for (test = 0; test < 12; ++test) {
+
+    switch (test)
+    {
+        case 0:
+            lock = PR_NewLock(); 
+			DPRINTF((output,"Thread[0x%x] called PR_NewLock\n",
+			PR_GetCurrentThread()));
+            PR_DestroyLock(lock);
+            break;
+            
+        case 1:
+            (void)PR_SecondsToInterval(1);
+			DPRINTF((output,"Thread[0x%x] called PR_SecondsToInterval\n",
+			PR_GetCurrentThread()));
+            break;
+            
+        case 2: (void)PR_CreateThread(
+            PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); 
+			DPRINTF((output,"Thread[0x%x] called PR_CreateThread\n",
+			PR_GetCurrentThread()));
+            break;
+            
+        case 3:
+            fd = PR_Open("foreign.tmp", PR_CREATE_FILE | PR_RDWR, 0666); 
+			DPRINTF((output,"Thread[0x%x] called PR_Open\n",
+			PR_GetCurrentThread()));
+            PR_Close(fd);
+            break;
+            
+        case 4:
+            fd = PR_NewUDPSocket(); 
+			DPRINTF((output,"Thread[0x%x] called PR_NewUDPSocket\n",
+			PR_GetCurrentThread()));
+            PR_Close(fd);
+            break;
+            
+        case 5:
+            fd = PR_NewTCPSocket(); 
+			DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocket\n",
+			PR_GetCurrentThread()));
+            PR_Close(fd);
+            break;
+            
+        case 6:
+#ifdef SYMBIAN
+#define TEMP_DIR "c:\\data\\"
+#else
+#define TEMP_DIR "/tmp/"
+#endif
+            dir = PR_OpenDir(TEMP_DIR);
+			DPRINTF((output,"Thread[0x%x] called PR_OpenDir\n",
+			PR_GetCurrentThread()));
+            PR_CloseDir(dir);
+            break;
+            
+        case 7:
+            (void)PR_NewThreadPrivateIndex(&pdkey, NULL);
+			DPRINTF((output,"Thread[0x%x] called PR_NewThreadPrivateIndex\n",
+			PR_GetCurrentThread()));
+            break;
+        
+        case 8:
+            (void)PR_GetEnv("PATH");
+			DPRINTF((output,"Thread[0x%x] called PR_GetEnv\n",
+			PR_GetCurrentThread()));
+            break;
+            
+        case 9:
+            (void)PR_NewTCPSocketPair(pair);
+			DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocketPair\n",
+			PR_GetCurrentThread()));
+            PR_Close(pair[0]);
+            PR_Close(pair[1]);
+            break;
+            
+        case 10:
+            PR_SetConcurrency(2);
+			DPRINTF((output,"Thread[0x%x] called PR_SetConcurrency\n",
+			PR_GetCurrentThread()));
+            break;
+
+        case 11:
+            PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH);
+			DPRINTF((output,"Thread[0x%x] called PR_SetThreadPriority\n",
+			PR_GetCurrentThread()));
+            break;
+            
+        default: 
+            break;
+    } /* switch() */
+	}
+}  /* OneShot */
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+	PRInt32	thread_cnt = DEFAULT_THREAD_COUNT;
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:");
+
+#if defined(WIN32)
+	thread_provider = thread_win32;
+#elif defined(_PR_PTHREADS)
+	thread_provider = thread_pthread;
+#elif defined(IRIX)
+	thread_provider = thread_sproc;
+#else
+    thread_provider = thread_nspr;
+#endif
+
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 't':  /* thread count */
+            thread_cnt = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	PR_SetConcurrency(2);
+
+	output = PR_GetSpecialFD(PR_StandardOutput);
+
+    while (thread_cnt-- > 0)
+    {
+        rv = NSPRPUB_TESTS_CreateThread(OneShot, (void*)thread_cnt);
+        PR_ASSERT(PR_SUCCESS == rv);
+        PR_Sleep(PR_MillisecondsToInterval(5));
+    }
+    PR_Sleep(PR_SecondsToInterval(3));
+    return (PR_SUCCESS == PR_Cleanup()) ? 0 : 1;
+}  /* main */
+
+/* foreign.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/forktest.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/forktest.c
new file mode 100644
index 0000000..f018798
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/forktest.c
@@ -0,0 +1,343 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: forktest.c
+**
+** Description: UNIX test for fork functions.
+**
+** Modification History:
+** 15-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**                 The debug mode will print all of the printfs associated with this test.
+**                         The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**                         have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**                        recognize the return code from tha main program.
+** 12-June-97 AGarcic - Revert to return code 0 and 1, remove debug option (obsolete).
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+
+#ifdef XP_UNIX
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+static char *message = "Hello world!";
+
+static void
+ClientThreadFunc(void *arg)
+{
+    PRNetAddr addr;
+    PRFileDesc *sock = NULL;
+    PRInt32 tmp = (PRInt32)arg;
+
+    /*
+     * Make sure the PR_Accept call will block
+     */
+
+    printf("Wait one second before connect\n");
+    fflush(stdout);
+    PR_Sleep(PR_SecondsToInterval(1));
+
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = 0;
+    if ((sock = PR_NewTCPSocket()) == NULL) {
+        fprintf(stderr, "failed to create TCP socket: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    if (PR_Bind(sock, &addr) != PR_SUCCESS) {
+        fprintf(stderr, "PR_Bind failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+    addr.inet.port = PR_htons((PRInt16)tmp);
+    printf("Connecting to port %hu\n", PR_ntohs(addr.inet.port));
+    fflush(stdout);
+    if (PR_Connect(sock, &addr, PR_SecondsToInterval(5)) !=
+        PR_SUCCESS) {
+        fprintf(stderr, "PR_Connect failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    printf("Writing message \"%s\"\n", message);
+    fflush(stdout);
+    if (PR_Send(sock, message, strlen(message) + 1, 0, PR_INTERVAL_NO_TIMEOUT) ==
+        -1) {
+        fprintf(stderr, "PR_Send failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+finish:
+    if (sock) {
+        PR_Close(sock);
+    }
+    return;
+}
+
+/*
+ * DoIO --
+ *     This function creates a thread that acts as a client and itself.
+ *     acts as a server.  Then it joins the client thread.
+ */
+static void
+DoIO(void)
+{
+    PRThread *clientThread;
+    PRFileDesc *listenSock = NULL;
+    PRFileDesc *sock = NULL;
+    PRNetAddr addr;
+    PRInt32 nBytes;
+    char buf[128];
+
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+        fprintf(stderr, "failed to create a TCP socket: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = 0;
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "failed to bind socket: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "failed to get socket port number: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    clientThread = PR_CreateThread( PR_USER_THREAD, ClientThreadFunc,
+        (void *) PR_ntohs(addr.inet.port), PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+        PR_JOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+        fprintf(stderr, "Cannot create client thread: (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already = 1;
+        goto finish;
+    }
+    printf("Accepting connection at port %hu\n", PR_ntohs(addr.inet.port));
+    fflush(stdout);
+    sock = PR_Accept(listenSock, &addr, PR_SecondsToInterval(5));
+    if (!sock) {
+        fprintf(stderr, "PR_Accept failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    nBytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nBytes == -1) {
+        fprintf(stderr, "PR_Recv failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+
+    /*
+     * Make sure it has proper null byte to mark end of string 
+     */
+
+    buf[sizeof(buf) - 1] = '\0';
+    printf("Received \"%s\" from the client\n", buf);
+    fflush(stdout);
+    if (!strcmp(buf, message)) {
+        PR_JoinThread(clientThread);
+
+        printf("The message is received correctly\n");
+        fflush(stdout);
+    } else {
+        fprintf(stderr, "The message should be \"%s\"\n",
+            message);
+        failed_already = 1;
+    }
+
+finish:
+    if (listenSock) {
+        PR_Close(listenSock);
+    }
+    if (sock) {
+        PR_Close(sock);
+    }
+    return;
+}
+
+#ifdef _PR_DCETHREADS
+
+#include <syscall.h>
+
+pid_t PR_UnixFork1(void)
+{
+    pid_t parent = getpid();
+    int rv = syscall(SYS_fork);
+
+    if (rv == -1) {
+        return (pid_t) -1;
+    } else {
+        /* For each process, rv is the pid of the other process */
+        if (rv == parent) {
+            /* the child */
+            return 0;
+        } else {
+            /* the parent */
+            return rv;
+        }
+    }
+}
+
+#elif defined(SOLARIS)
+
+/*
+ * It seems like that in Solaris 2.4 one must call fork1() if the
+ * the child process is going to use thread functions.  Solaris 2.5
+ * doesn't have this problem. Calling fork() also works. 
+ */
+
+pid_t PR_UnixFork1(void)
+{
+    return fork1();
+}
+
+#else
+
+pid_t PR_UnixFork1(void)
+{
+    return fork();
+}
+
+#endif  /* PR_DCETHREADS */
+
+int main(int argc, char **argv)
+{
+    pid_t pid;
+	int rv;
+
+    /* main test program */
+
+    DoIO();
+
+    pid = PR_UnixFork1();
+
+    if (pid  == (pid_t) -1) {
+        fprintf(stderr, "Fork failed: errno %d\n", errno);
+        failed_already=1;
+        return 1;
+    } else if (pid > 0) {
+        int childStatus;
+
+        printf("Fork succeeded.  Parent process continues.\n");
+        DoIO();
+        if ((rv = waitpid(pid, &childStatus, 0)) != pid) {
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+			/*
+			 * nspr may handle SIGCLD signal
+			 */
+			if ((rv < 0) && (errno == ECHILD)) {
+			} else 
+#endif
+			{
+				fprintf(stderr, "waitpid failed: %d\n", errno);
+				failed_already = 1;
+			}
+        } else if (!WIFEXITED(childStatus)
+                || WEXITSTATUS(childStatus) != 0) {
+            failed_already = 1;
+        }
+        printf("Parent process exits.\n");
+        if (!failed_already) {
+            printf("PASSED\n");
+        } else {
+            printf("FAILED\n");
+        }
+        return failed_already;
+    } else {
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+		extern void _PR_IRIX_CHILD_PROCESS(void);
+		_PR_IRIX_CHILD_PROCESS();
+#endif
+        printf("Fork succeeded.  Child process continues.\n");
+        DoIO();
+        printf("Child process exits.\n");
+        return failed_already;
+    }
+}
+
+#else  /* XP_UNIX */
+
+int main(    int     argc,
+char   *argv[]
+)
+{
+
+    printf("The fork test is applicable to Unix only.\n");
+    return 0;
+
+}
+
+#endif  /* XP_UNIX */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/formattm.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/formattm.c
new file mode 100644
index 0000000..0ab630b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/formattm.c
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* A test program for PR_FormatTime and PR_FormatTimeUSEnglish */
+
+#include "prtime.h"
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    char buffer[256];
+    char small_buffer[8];
+    PRTime now;
+    PRExplodedTime tod;
+
+    now = PR_Now();
+    PR_ExplodeTime(now, PR_LocalTimeParameters, &tod);
+
+    if (PR_FormatTime(buffer, sizeof(buffer),
+            "%a %b %d %H:%M:%S %Z %Y", &tod) != 0) {
+        printf("%s\n", buffer);
+    } else {
+        fprintf(stderr, "PR_FormatTime(buffer) failed\n");
+        return 1;
+    }
+
+    small_buffer[0] = '?';
+    if (PR_FormatTime(small_buffer, sizeof(small_buffer),
+            "%a %b %d %H:%M:%S %Z %Y", &tod) == 0) {
+        if (small_buffer[0] != '\0') {
+            fprintf(stderr, "PR_FormatTime(small_buffer) did not output "
+                            "an empty string on failure\n");
+            return 1;
+        }
+        printf("%s\n", small_buffer);
+    } else {
+        fprintf(stderr, "PR_FormatTime(small_buffer) succeeded "
+                        "unexpectedly\n");
+        return 1;
+    }
+
+    (void)PR_FormatTimeUSEnglish(buffer, sizeof(buffer),
+        "%a %b %d %H:%M:%S %Z %Y", &tod);
+    printf("%s\n", buffer);
+
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/freeif.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/freeif.c
new file mode 100644
index 0000000..4bf2994
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/freeif.c
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * A test to see if the macros PR_DELETE and PR_FREEIF are
+ * properly defined.  (See Bugzilla bug #39110.)
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void Noop(void) { }
+
+static void Fail(void)
+{
+    printf("FAIL\n");
+    exit(1);
+}
+
+int main(int argc, char **argv)
+{
+    int foo = 1;
+    char *ptr = NULL;
+
+    /* this fails to compile with the old definition of PR_DELETE */
+    if (foo)
+        PR_DELETE(ptr);
+    else
+        Noop();
+
+    /* this nests incorrectly with the old definition of PR_FREEIF */
+    if (foo)
+        PR_FREEIF(ptr);
+    else
+        Fail();
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/fsync.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/fsync.c
new file mode 100644
index 0000000..149a5b5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/fsync.c
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prinrval.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+static PRFileDesc *err = NULL;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-S] [-K <n>] [-h] <filename>\n");
+    PR_fprintf(err, "\t-c   Nuber of iterations     (default: 10)\n");
+    PR_fprintf(err, "\t-S   Sync the file           (default: FALSE)\n");
+    PR_fprintf(err, "\t-K   Size of file (K bytes)  (default: 10)\n");
+    PR_fprintf(err, "\t     Name of file to write   (default: /usr/tmp/sync.dat)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+    PLOptStatus os;
+    PRUint8 *buffer;
+    PRFileDesc *file = NULL;
+    const char *filename = "sync.dat";
+    PRUint32 index, loops, iterations = 10, filesize = 10;
+    PRIntn flags = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hSK:c:");
+    PRIntervalTime time, total = 0, shortest = 0x7fffffff, longest = 0;
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:       /* Name of file to create */
+            filename = opt->value;
+            break;
+        case 'S':       /* Use sych option on file */
+            flags |= PR_SYNC;
+            break;
+        case 'K':       /* Size of file to write */
+            filesize = atoi(opt->value);
+            break;
+        case 'c':       /* Number of iterations */
+            iterations = atoi(opt->value);
+            break;
+        case 'h':       /* user wants some guidance */
+        default:        /* user needs some guidance */
+            Help();     /* so give him an earful */
+            return 2;   /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    file = PR_Open(filename, flags, 0666);
+    if (NULL == file)
+    {
+        PL_FPrintError(err, "Failed to open file");
+        return 1;
+    }
+
+    buffer = (PRUint8*)PR_CALLOC(1024);
+    if (NULL == buffer)
+    {
+        PL_FPrintError(err, "Cannot allocate buffer");
+        return 1;
+    }
+
+    for (index = 0; index < sizeof(buffer); ++index)
+        buffer[index] = (PRUint8)index;
+
+    for (loops = 0; loops < iterations; ++loops)
+    {
+        time = PR_IntervalNow();
+        for (index = 0; index < filesize; ++index)
+        {
+            PR_Write(file, buffer, 1024);
+        }
+        time = (PR_IntervalNow() - time);
+
+        total += time;
+        if (time < shortest) shortest = time;
+        else if (time > longest) longest = time;
+        if (0 != PR_Seek(file, 0, PR_SEEK_SET))
+        {
+           PL_FPrintError(err, "Rewinding file");
+           return 1;
+        }
+    }
+
+    total = total / iterations;
+    PR_fprintf(
+        err, "%u iterations over a %u kbyte %sfile: %u [%u] %u\n",
+        iterations, filesize, ((flags & PR_SYNC) ? "SYNCH'd " : ""),
+        PR_IntervalToMicroseconds(shortest),
+        PR_IntervalToMicroseconds(total),
+        PR_IntervalToMicroseconds(longest));
+
+    PR_DELETE(buffer);
+    rv = PR_Close(file);
+    if (PR_SUCCESS != rv)
+    {
+        PL_FPrintError(err, "Closing file failed");
+        return 1;
+    }
+    rv = PR_Delete(filename);
+    if (PR_SUCCESS != rv)
+    {
+        PL_FPrintError(err, "Deleting file failed");
+        return 1;
+    }
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/getai.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/getai.c
new file mode 100644
index 0000000..eaa41d4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/getai.c
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+    PRAddrInfo *ai;
+    void *iter;
+    PRNetAddr addr;
+
+    ai = PR_GetAddrInfoByName(argv[1], PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+    if (ai == NULL) {
+        fprintf(stderr, "PR_GetAddrInfoByName failed: (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    printf("%s\n", PR_GetCanonNameFromAddrInfo(ai));
+    iter = NULL;
+    while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+        char buf[128];
+        PR_NetAddrToString(&addr, buf, sizeof buf);
+        printf("%s\n", buf);
+    }
+    PR_FreeAddrInfo(ai);
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/gethost.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/gethost.c
new file mode 100644
index 0000000..3af41a3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/gethost.c
@@ -0,0 +1,291 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: gethost.c
+ *
+ * Description: tests various functions in prnetdb.h
+ *
+ * Usage: gethost [-6] [hostname]
+ */
+
+#include "prio.h"
+#include "prnetdb.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DEFAULT_HOST_NAME "mcom.com"
+
+static void Help(void)
+{
+    fprintf(stderr, "Usage: gethost [-h] [hostname]\n");
+    fprintf(stderr, "\t-h          help\n");
+    fprintf(stderr, "\thostname    Name of host    (default: %s)\n",
+            DEFAULT_HOST_NAME);
+}  /* Help */
+
+/*
+ * Prints the contents of a PRHostEnt structure
+ */
+void PrintHostent(const PRHostEnt *he)
+{
+    int i;
+    int j;
+
+    printf("h_name: %s\n", he->h_name);
+    for (i = 0; he->h_aliases[i]; i++) {
+        printf("h_aliases[%d]: %s\n", i, he->h_aliases[i]);
+    }
+    printf("h_addrtype: %d\n", he->h_addrtype);
+    printf("h_length: %d\n", he->h_length);
+    for (i = 0; he->h_addr_list[i]; i++) {
+        printf("h_addr_list[%d]: ", i);
+        for (j = 0; j < he->h_length; j++) {
+            if (j != 0) printf(".");
+            printf("%u", (unsigned char)he->h_addr_list[i][j]);
+        }
+        printf("\n");
+    }
+}
+
+int main(int argc, char **argv)
+{
+    const char *hostName = DEFAULT_HOST_NAME;
+    PRHostEnt he, reversehe;
+    char buf[PR_NETDB_BUF_SIZE];
+    char reversebuf[PR_NETDB_BUF_SIZE];
+    PRIntn idx;
+    PRNetAddr addr;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 0:  /* naked */
+                hostName = opt->value;
+                break;
+            case 'h':  /* Help message */
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (PR_GetHostByName(hostName, buf, sizeof(buf), &he) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetHostByName failed\n");
+        exit(1);
+    }
+    PrintHostent(&he);
+    idx = 0;
+    while (1) {
+        idx = PR_EnumerateHostEnt(idx, &he, 0, &addr);
+        if (idx == -1) {
+            fprintf(stderr, "PR_EnumerateHostEnt failed\n");
+            exit(1);
+        }
+        if (idx == 0) break;  /* normal loop termination */
+        printf("reverse lookup\n");
+        if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf),
+                &reversehe) == PR_FAILURE) {
+            fprintf(stderr, "PR_GetHostByAddr failed\n");
+            exit(1);
+        }
+        PrintHostent(&reversehe);
+    }
+
+    printf("PR_GetIPNodeByName with PR_AF_INET\n");
+    if (PR_GetIPNodeByName(hostName, PR_AF_INET, PR_AI_DEFAULT,
+            buf, sizeof(buf), &he) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetIPNodeByName failed\n");
+        exit(1);
+    }
+    PrintHostent(&he);
+    printf("PR_GetIPNodeByName with PR_AF_INET6\n");
+    if (PR_GetIPNodeByName(hostName, PR_AF_INET6, PR_AI_DEFAULT,
+            buf, sizeof(buf), &he) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetIPNodeByName failed\n");
+        exit(1);
+    }
+    PrintHostent(&he);
+    idx = 0;
+    printf("PR_GetHostByAddr with PR_AF_INET6\n");
+    while (1) {
+        idx = PR_EnumerateHostEnt(idx, &he, 0, &addr);
+        if (idx == -1) {
+            fprintf(stderr, "PR_EnumerateHostEnt failed\n");
+            exit(1);
+        }
+        if (idx == 0) break;  /* normal loop termination */
+        printf("reverse lookup\n");
+        if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf),
+                &reversehe) == PR_FAILURE) {
+            fprintf(stderr, "PR_GetHostByAddr failed\n");
+            exit(1);
+        }
+        PrintHostent(&reversehe);
+    }
+    printf("PR_GetHostByAddr with PR_AF_INET6 done\n");
+  
+    PR_StringToNetAddr("::1", &addr);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_TRUE) {
+        fprintf(stderr, "addr should not be ipv4 mapped address\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+
+    PR_StringToNetAddr("127.0.0.1", &addr);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+    PR_StringToNetAddr("::FFFF:127.0.0.1", &addr);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_FALSE) {
+        fprintf(stderr, "addr should be ipv4 mapped address\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+
+    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
+        fprintf(stderr, "addr should be unspecified address\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+
+    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
+        fprintf(stderr, "addr should be unspecified address\n");
+        exit(1);
+    }
+    if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = 0;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
+        fprintf(stderr, "addr should be unspecified address\n");
+        exit(1);
+    }
+	{
+		char buf[256];
+		PR_NetAddrToString(&addr, buf, 256);
+		printf("IPv4 INADDRANY: %s\n", buf);
+	}
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = 0;
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+	{
+		char buf[256];
+		PR_NetAddrToString(&addr, buf, 256);
+		printf("IPv4 LOOPBACK: %s\n", buf);
+	}
+
+    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
+        fprintf(stderr, "addr should be unspecified address\n");
+        exit(1);
+    }
+	{
+		char buf[256];
+		PR_NetAddrToString(&addr, buf, 256);
+		printf("IPv6 INADDRANY: %s\n", buf);
+	}
+    if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+	{
+		char buf[256];
+		PR_NetAddrToString(&addr, buf, 256);
+		printf("IPv6 LOOPBACK: %s\n", buf);
+	}
+	{
+		PRIPv6Addr v6addr;
+		char tmp_buf[256];
+
+    	PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr);
+
+		PR_ConvertIPv4AddrToIPv6(addr.inet.ip, &v6addr);
+    	PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr);
+		addr.ipv6.ip = v6addr;
+		PR_NetAddrToString(&addr, tmp_buf, 256);
+		printf("IPv4-mapped IPv6 LOOPBACK: %s\n", tmp_buf);
+	}
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/getproto.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/getproto.c
new file mode 100644
index 0000000..fe847a0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/getproto.c
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *************************************************************************
+ *
+ * File: getproto.c
+ *
+ * A test program for PR_GetProtoByName and PR_GetProtoByNumber
+ *
+ *************************************************************************
+ */
+
+#include "plstr.h"
+#include "plerror.h"
+#include "prinit.h"
+#include "prprf.h"
+#include "prnetdb.h"
+#include "prerror.h"
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *prstderr = PR_GetSpecialFD(PR_StandardError);
+    PRBool failed = PR_FALSE;
+    PRProtoEnt proto;
+    char buf[2048];
+    PRStatus rv;
+
+    PR_STDIO_INIT();
+    rv = PR_GetProtoByName("tcp", buf, sizeof(buf), &proto);
+    if (PR_FAILURE == rv) {
+        failed = PR_TRUE;
+        PL_FPrintError(prstderr, "PR_GetProtoByName failed");
+    }
+    else if (6 != proto.p_num) {
+        PR_fprintf(
+            prstderr,"tcp is usually 6, but is %d on this machine\n",
+            proto.p_num);
+    }
+    else PR_fprintf(prstderr, "tcp is protocol number %d\n", proto.p_num);
+
+    rv = PR_GetProtoByName("udp", buf, sizeof(buf), &proto);
+    if (PR_FAILURE == rv) {
+        failed = PR_TRUE;
+        PL_FPrintError(prstderr, "PR_GetProtoByName failed");
+    }
+    else if (17 != proto.p_num) {
+        PR_fprintf(
+            prstderr, "udp is usually 17, but is %d on this machine\n",
+            proto.p_num);
+    }
+    else PR_fprintf(prstderr, "udp is protocol number %d\n", proto.p_num);
+
+    rv = PR_GetProtoByNumber(6, buf, sizeof(buf), &proto);
+    if (PR_FAILURE == rv) {
+        failed = PR_TRUE;
+        PL_FPrintError(prstderr, "PR_GetProtoByNumber failed");
+    }
+    else if (PL_strcmp("tcp", proto.p_name)) {
+        PR_fprintf(
+            prstderr, "Protocol number 6 is usually tcp, but is %s"
+            " on this platform\n", proto.p_name);
+    }
+    else PR_fprintf(prstderr, "Protocol number 6 is %s\n", proto.p_name);
+
+    rv = PR_GetProtoByNumber(17, buf, sizeof(buf), &proto);
+    if (PR_FAILURE == rv) {
+        failed = PR_TRUE;
+        PL_FPrintError(prstderr, "PR_GetProtoByNumber failed");
+    }
+    else if (PL_strcmp("udp", proto.p_name)) {
+        PR_fprintf(
+            prstderr, "Protocol number 17 is usually udp, but is %s"
+            " on this platform\n", proto.p_name);
+    }
+    else PR_fprintf(prstderr, "Protocol number 17 is %s\n", proto.p_name);
+
+    PR_fprintf(prstderr, (failed) ? "FAILED\n" : "PASSED\n");
+    return (failed) ? 1 : 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/i2l.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/i2l.c
new file mode 100644
index 0000000..a2e4a54
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/i2l.c
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+
+#include "prio.h"
+#include "prinit.h"
+#include "prprf.h"
+#include "prlong.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+typedef union Overlay_i
+{
+    PRInt32 i;
+    PRInt64 l;
+} Overlay_i;
+
+typedef union Overlay_u
+{
+    PRUint32 i;
+    PRUint64 l;
+} Overlay_u;
+
+static PRFileDesc *err = NULL;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: -i n | -u n | -h\n");
+    PR_fprintf(err, "\t-i n treat following number as signed integer\n");
+    PR_fprintf(err, "\t-u n treat following number as unsigned integer\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv)
+{
+    Overlay_i si;
+    Overlay_u ui;
+    PLOptStatus os;
+    PRBool bsi = PR_FALSE, bui = PR_FALSE;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hi:u:");
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'i':  /* signed integer */
+            si.i = (PRInt32)atoi(opt->value);
+            bsi = PR_TRUE;
+            break;
+        case 'u':  /* unsigned */
+            ui.i = (PRUint32)atoi(opt->value);
+            bui = PR_TRUE;
+            break;
+        case 'h':  /* user wants some guidance */
+         default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+#if defined(HAVE_LONG_LONG)
+    PR_fprintf(err, "We have long long\n");
+#else
+    PR_fprintf(err, "We don't have long long\n");
+#endif
+
+    if (bsi)
+    {
+        PR_fprintf(err, "Converting %ld: ", si.i);
+        LL_I2L(si.l, si.i);
+        PR_fprintf(err, "%lld\n", si.l);
+    }
+
+    if (bui)
+    {
+        PR_fprintf(err, "Converting %lu: ", ui.i);
+        LL_I2L(ui.l, ui.i);
+        PR_fprintf(err, "%llu\n", ui.l);
+    }
+    return 0;
+
+}  /* main */
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
+
+/* i2l.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/initclk.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/initclk.c
new file mode 100644
index 0000000..24e80f8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/initclk.c
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This is a regression test for the bug that the interval timer
+ * is not initialized when _PR_CreateCPU calls PR_IntervalNow.
+ * The bug would make this test program finish prematurely,
+ * when the SHORT_TIMEOUT period expires.  The correct behavior
+ * is for the test to finish when the LONG_TIMEOUT period expires.
+ */
+
+#include "prlock.h"
+#include "prcvar.h"
+#include "prthread.h"
+#include "prinrval.h"
+#include "prlog.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+/* The timeouts, in milliseconds */
+#define SHORT_TIMEOUT 1000
+#define LONG_TIMEOUT 3000
+
+PRLock *lock1, *lock2;
+PRCondVar *cv1, *cv2;
+
+void ThreadFunc(void *arg)
+{
+    PR_Lock(lock1);
+    PR_WaitCondVar(cv1, PR_MillisecondsToInterval(SHORT_TIMEOUT));
+    PR_Unlock(lock1);
+}
+
+int main(int argc, char **argv)
+{
+    PRThread *thread;
+    PRIntervalTime start, end;
+    PRUint32 elapsed_ms;
+
+    lock1 = PR_NewLock();
+    PR_ASSERT(NULL != lock1);
+    cv1 = PR_NewCondVar(lock1);
+    PR_ASSERT(NULL != cv1);
+    lock2 = PR_NewLock();
+    PR_ASSERT(NULL != lock2);
+    cv2 = PR_NewCondVar(lock2);
+    PR_ASSERT(NULL != cv2);
+    start = PR_IntervalNow();
+    thread = PR_CreateThread(
+            PR_USER_THREAD,
+            ThreadFunc,
+            NULL,
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_JOINABLE_THREAD,
+            0);
+    PR_ASSERT(NULL != thread);
+    PR_Lock(lock2);
+    PR_WaitCondVar(cv2, PR_MillisecondsToInterval(LONG_TIMEOUT));
+    PR_Unlock(lock2);
+    PR_JoinThread(thread);
+    end = PR_IntervalNow();
+    elapsed_ms = PR_IntervalToMilliseconds((PRIntervalTime)(end - start));
+    /* Allow 100ms imprecision */
+    if (elapsed_ms < LONG_TIMEOUT - 100 || elapsed_ms > LONG_TIMEOUT + 100) {
+        printf("Elapsed time should be %u ms but is %u ms\n",
+                LONG_TIMEOUT, elapsed_ms);
+        printf("FAIL\n");
+        exit(1);
+    }
+	printf("Elapsed time: %u ms, expected time: %u ms\n",
+               LONG_TIMEOUT, elapsed_ms);
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/inrval.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/inrval.c
new file mode 100644
index 0000000..1fb35d1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/inrval.c
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** file:            inrval.c
+** description:     Interval conversion test.
+** Modification History:
+** 15-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+**/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "obsolete/pralarm.h"
+
+#include "prio.h"
+#include "prprf.h"
+#include "prlock.h"
+#include "prlong.h"
+#include "prcvar.h"
+#include "prinrval.h"
+#include "prtime.h"
+
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static PRIntn debug_mode;
+static PRFileDesc *output;
+
+
+static void TestConversions(void)
+{
+    PRIntervalTime ticks = PR_TicksPerSecond();
+
+	if (debug_mode) {
+    PR_fprintf(output, "PR_TicksPerSecond: %ld\n\n", ticks);
+    PR_fprintf(output, "PR_SecondsToInterval(1): %ld\n", PR_SecondsToInterval(1));
+    PR_fprintf(output, "PR_MillisecondsToInterval(1000): %ld\n", PR_MillisecondsToInterval(1000));
+    PR_fprintf(output, "PR_MicrosecondsToInterval(1000000): %ld\n\n", PR_MicrosecondsToInterval(1000000));
+
+    PR_fprintf(output, "PR_SecondsToInterval(3): %ld\n", PR_SecondsToInterval(3));
+    PR_fprintf(output, "PR_MillisecondsToInterval(3000): %ld\n", PR_MillisecondsToInterval(3000));
+    PR_fprintf(output, "PR_MicrosecondsToInterval(3000000): %ld\n\n", PR_MicrosecondsToInterval(3000000));
+
+    PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks));
+    PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks));
+    PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks));
+
+    ticks *= 3;
+    PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks));
+    PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks));
+    PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks));
+	} /*end debug mode */
+}  /* TestConversions */
+
+static void TestIntervalOverhead(void)
+{
+    /* Hopefully the optimizer won't delete this function */
+    PRUint32 elapsed, per_call, loops = 1000000;
+
+    PRIntervalTime timeout, timein = PR_IntervalNow();
+    while (--loops > 0)
+        timeout = PR_IntervalNow();
+
+    elapsed = 1000U * PR_IntervalToMicroseconds(timeout - timein);
+    per_call = elapsed / 1000000U;
+    PR_fprintf(
+        output, "Overhead of 'PR_IntervalNow()' is %u nsecs\n\n", per_call);
+}  /* TestIntervalOverhead */
+
+static void TestNowOverhead(void)
+{
+    PRTime timeout, timein;
+    PRInt32 overhead, loops = 1000000;
+    PRInt64 elapsed, per_call, ten23rd, ten26th;
+
+    LL_I2L(ten23rd, 1000);
+    LL_I2L(ten26th, 1000000);
+
+    timein = PR_Now();
+    while (--loops > 0)
+        timeout = PR_Now();
+
+    LL_SUB(elapsed, timeout, timein);
+    LL_MUL(elapsed, elapsed, ten23rd);
+    LL_DIV(per_call, elapsed, ten26th);
+    LL_L2I(overhead, per_call);
+    PR_fprintf(
+        output, "Overhead of 'PR_Now()' is %u nsecs\n\n", overhead);
+}  /* TestNowOverhead */
+
+static void TestIntervals(void)
+{
+    PRStatus rv;
+    PRUint32 delta;
+    PRInt32 seconds;
+    PRUint64 elapsed, thousand;
+    PRTime timein, timeout;
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+    for (seconds = 0; seconds < 10; ++seconds)
+    {
+        PRIntervalTime ticks = PR_SecondsToInterval(seconds);
+        PR_Lock(ml);
+        timein = PR_Now();
+        rv = PR_WaitCondVar(cv, ticks);
+        timeout = PR_Now();
+        PR_Unlock(ml);
+        LL_SUB(elapsed, timeout, timein);
+        LL_I2L(thousand, 1000);
+        LL_DIV(elapsed, elapsed, thousand);
+        LL_L2UI(delta, elapsed);
+        if (debug_mode) PR_fprintf(output, 
+            "TestIntervals: %swaiting %ld seconds took %ld msecs\n",
+            ((rv == PR_SUCCESS) ? "" : "FAILED "), seconds, delta);
+    }
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    if (debug_mode) PR_fprintf(output, "\n");
+}  /* TestIntervals */
+
+static PRIntn PR_CALLBACK RealMain(int argc, char** argv)
+{
+    PRUint32 vcpu, cpus = 0, loops = 1000;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+
+ /* main test */
+	
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dl:c:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'c':  /* concurrency counter */
+			cpus = atoi(opt->value);
+            break;
+        case 'l':  /* loop counter */
+			loops = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+	
+    output = PR_GetSpecialFD(PR_StandardOutput);
+    PR_fprintf(output, "inrval: Examine stdout to determine results.\n");
+
+    if (cpus == 0) cpus = 8;
+    if (loops == 0) loops = 1000;
+
+    if (debug_mode > 0)
+    {
+        PR_fprintf(output, "Inrval: Using %d loops\n", loops);
+        PR_fprintf(output, "Inrval: Using 1 and %d cpu(s)\n", cpus);
+    }
+
+    for (vcpu = 1; vcpu <= cpus; vcpu += cpus - 1)
+    {
+        if (debug_mode)
+            PR_fprintf(output, "\nInrval: Using %d CPU(s)\n\n", vcpu);
+        PR_SetConcurrency(vcpu);
+
+        TestNowOverhead();
+        TestIntervalOverhead();
+        TestConversions();
+        TestIntervals();
+    }
+        
+    return 0;
+}
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/instrumt.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/instrumt.c
new file mode 100644
index 0000000..3b57ea9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/instrumt.c
@@ -0,0 +1,507 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:    instrumt.c
+** Description: This test is for the NSPR debug aids defined in
+** prcountr.h, prtrace.h, prolock.h
+**
+** The test case tests the three debug aids in NSPR:
+**
+** Diagnostic messages can be enabled using "instrumt -v 6"
+** This sets the msgLevel to something that PR_LOG() likes.
+** Also define in the environment "NSPR_LOG_MODULES=Test:6"
+**
+** CounterTest() tests the counter facility. This test
+** creates 4 threads. Each thread either increments, decrements,
+** adds to or subtracts from a counter, depending on an argument
+** passed to the thread at thread-create time. Each of these threads
+** does COUNT_LIMIT iterations doing its thing. When all 4 threads
+** are done, the result of the counter is evaluated. If all was atomic,
+** the the value of the counter should be zero.
+**
+** TraceTest():
+** This test mingles with the counter test. Counters trace.
+** A thread to extract trace entries on the fly is started.
+** A thread to dump trace entries to a file is started.
+**
+** OrderedLockTest():
+**
+**
+**
+**
+**
+*/
+
+#include <stdio.h>
+#include <plstr.h>
+#include <prclist.h>
+#include <prmem.h>
+#include <plgetopt.h> 
+#include <prlog.h> 
+#include <prmon.h> 
+#include <pratom.h> 
+#include <prtrace.h> 
+#include <prcountr.h> 
+#include <prolock.h> 
+
+#define COUNT_LIMIT  (10 * ( 1024))
+
+#define SMALL_TRACE_BUFSIZE  ( 60 * 1024 )
+
+typedef enum 
+{
+    CountLoop = 1,
+    TraceLoop = 2,
+    TraceFlow = 3
+} TraceTypes;
+
+
+PRLogModuleLevel msgLevel = PR_LOG_ALWAYS;
+
+PRBool  help = PR_FALSE;
+PRBool  failed = PR_FALSE;
+
+
+PRLogModuleInfo *lm;
+PRMonitor   *mon;
+PRInt32     activeThreads = 0;
+PR_DEFINE_COUNTER( hCounter );
+PR_DEFINE_TRACE( hTrace );
+
+static void Help(void)
+{
+    printf("Help? ... Ha!\n");
+}    
+
+static void ListCounters(void)
+{
+    PR_DEFINE_COUNTER( qh );
+    PR_DEFINE_COUNTER( rh );
+    const char *qn, *rn, *dn;
+    const char **qname = &qn, **rname = &rn, **desc = &dn;
+    PRUint32    tCtr;
+
+    PR_INIT_COUNTER_HANDLE( qh, NULL );
+    PR_FIND_NEXT_COUNTER_QNAME(qh, qh );
+    while ( qh != NULL )
+    {
+        PR_INIT_COUNTER_HANDLE( rh, NULL );
+        PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );
+        while ( rh != NULL )
+        {
+            PR_GET_COUNTER_NAME_FROM_HANDLE( rh, qname, rname, desc );
+            tCtr = PR_GET_COUNTER(tCtr, rh);
+            PR_LOG( lm, msgLevel,
+                ( "QName: %s  RName: %s  Desc: %s  Value: %ld\n", 
+                qn, rn, dn, tCtr ));
+            PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );
+        } 
+        PR_FIND_NEXT_COUNTER_QNAME(qh, qh);
+    }
+    return;    
+} /* end ListCounters() */
+
+static void ListTraces(void)
+{
+    PR_DEFINE_TRACE( qh );
+    PR_DEFINE_TRACE( rh );
+    const char *qn, *rn, *dn;
+    const char **qname = &qn, **rname = &rn, **desc = &dn;
+
+    PR_INIT_TRACE_HANDLE( qh, NULL );
+    PR_FIND_NEXT_TRACE_QNAME(qh, qh );
+    while ( qh != NULL )
+    {
+        PR_INIT_TRACE_HANDLE( rh, NULL );
+        PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );
+        while ( rh != NULL )
+        {
+            PR_GET_TRACE_NAME_FROM_HANDLE( rh, qname, rname, desc );
+            PR_LOG( lm, msgLevel,
+                ( "QName: %s  RName: %s  Desc: %s", 
+                qn, rn, dn ));
+            PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );
+        } 
+        PR_FIND_NEXT_TRACE_QNAME(qh, qh);
+    }
+    return;    
+} /* end ListCounters() */
+
+
+static PRInt32 one = 1;
+static PRInt32 two = 2;
+static PRInt32 three = 3;
+static PRInt32 four = 4;
+
+/*
+** Thread to iteratively count something.
+*/
+static void PR_CALLBACK CountSomething( void *arg )
+{
+    PRInt32 switchVar = *((PRInt32 *)arg);
+    PRInt32 i;
+
+    PR_LOG( lm, msgLevel,
+        ("CountSomething: begin thread %ld", switchVar ));
+    
+    for ( i = 0; i < COUNT_LIMIT ; i++)
+    {
+        switch ( switchVar )
+        {
+        case 1 :
+            PR_INCREMENT_COUNTER( hCounter );
+            break;
+        case 2 :
+            PR_DECREMENT_COUNTER( hCounter );
+            break;
+        case 3 :
+            PR_ADD_TO_COUNTER( hCounter, 1 );
+            break;
+        case 4 :
+            PR_SUBTRACT_FROM_COUNTER( hCounter, 1 );
+            break;
+        default :
+            PR_ASSERT( 0 );
+            break;
+        }
+        PR_TRACE( hTrace, CountLoop, switchVar, i, 0, 0, 0, 0, 0 );
+    } /* end for() */
+
+    PR_LOG( lm, msgLevel,
+        ("CounterSomething: end thread %ld", switchVar ));
+    
+    PR_EnterMonitor(mon);
+    --activeThreads;
+    PR_Notify( mon );
+    PR_ExitMonitor(mon);
+
+    return;    
+} /* end CountSomething() */
+
+/*
+** Create the counter threads.
+*/
+static void CounterTest( void )
+{
+    PRThread *t1, *t2, *t3, *t4;
+    PRIntn i = 0;
+    PR_DEFINE_COUNTER( tc );
+    PR_DEFINE_COUNTER( zCounter );
+
+    PR_LOG( lm, msgLevel,
+        ("Begin CounterTest"));
+    
+    /*
+    ** Test Get and Set of a counter.
+    **
+    */
+    PR_CREATE_COUNTER( zCounter, "Atomic", "get/set test", "test get and set of counter" );
+    PR_SET_COUNTER( zCounter, 9 );
+    PR_GET_COUNTER( i, zCounter );
+    if ( i != 9 )
+    {
+        failed = PR_TRUE;
+        PR_LOG( lm, msgLevel,
+            ("Counter set/get failed"));
+    }
+
+    activeThreads += 4;
+    PR_CREATE_COUNTER( hCounter, "Atomic", "SMP Tests", "test atomic nature of counter" );
+
+    PR_GET_COUNTER_HANDLE_FROM_NAME( tc, "Atomic", "SMP Tests" );
+    PR_ASSERT( tc == hCounter );
+
+	t1 = PR_CreateThread(PR_USER_THREAD,
+	        CountSomething, &one, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t1);
+
+	t2 = PR_CreateThread(PR_USER_THREAD,
+			CountSomething, &two, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t2);
+        
+	t3 = PR_CreateThread(PR_USER_THREAD,
+			CountSomething, &three, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t3);
+        
+	t4 = PR_CreateThread(PR_USER_THREAD,
+			CountSomething, &four, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t4);
+
+    PR_LOG( lm, msgLevel,
+        ("Counter Threads started"));
+
+    ListCounters();
+    return;
+} /* end CounterTest() */
+
+/*
+** Thread to dump trace buffer to a file.
+*/
+static void PR_CALLBACK RecordTrace(void *arg )
+{
+    PR_RECORD_TRACE_ENTRIES();
+
+    PR_EnterMonitor(mon);
+    --activeThreads;
+    PR_Notify( mon );
+    PR_ExitMonitor(mon);
+
+    return;    
+} /* end RecordTrace() */
+
+
+
+#define NUM_TRACE_RECORDS ( 10000 )
+/*
+** Thread to extract and print trace entries from the buffer.
+*/
+static void PR_CALLBACK SampleTrace( void *arg )
+{
+#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
+    PRInt32 found, rc;
+    PRTraceEntry    *foundEntries;
+    PRInt32 i;
+    
+    foundEntries = (PRTraceEntry *)PR_Malloc( NUM_TRACE_RECORDS * sizeof(PRTraceEntry));
+    PR_ASSERT(foundEntries != NULL );
+
+    do
+    {
+        rc = PR_GetTraceEntries( foundEntries, NUM_TRACE_RECORDS, &found);
+        PR_LOG( lm, msgLevel,
+            ("SampleTrace: Lost Data: %ld found: %ld", rc, found ));
+
+        if ( found != 0)
+        {
+            for ( i = 0 ; i < found; i++ )
+            {
+                PR_LOG( lm, msgLevel,
+                    ("SampleTrace, detail: Thread: %p, Time: %llX, UD0: %ld, UD1: %ld, UD2: %8.8ld",
+                        (foundEntries +i)->thread,
+                        (foundEntries +i)->time,
+                        (foundEntries +i)->userData[0], 
+                        (foundEntries +i)->userData[1], 
+                        (foundEntries +i)->userData[2] )); 
+            }
+        }
+        PR_Sleep(PR_MillisecondsToInterval(50));
+    }
+    while( found != 0 && activeThreads >= 1 );
+
+    PR_Free( foundEntries );
+
+    PR_EnterMonitor(mon);
+    --activeThreads;
+    PR_Notify( mon );
+    PR_ExitMonitor(mon);
+
+    PR_LOG( lm, msgLevel,
+        ("SampleTrace(): exiting"));
+
+#endif
+    return;    
+} /* end RecordTrace() */
+
+/*
+** Basic trace test.
+*/
+static void TraceTest( void )
+{
+    PRInt32 i;
+    PRInt32 size;
+    PR_DEFINE_TRACE( th );
+    PRThread *t1, *t2;
+    
+    PR_LOG( lm, msgLevel,
+        ("Begin TraceTest"));    
+
+    size = SMALL_TRACE_BUFSIZE;
+    PR_SET_TRACE_OPTION( PRTraceBufSize, &size );
+    PR_GET_TRACE_OPTION( PRTraceBufSize, &i );
+    
+    PR_CREATE_TRACE( th, "TraceTest", "tt2", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt3", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt4", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt5", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt6", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt7", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt8", "A description for the trace test" );
+
+    PR_CREATE_TRACE( th, "Trace Test", "tt0", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt1", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt2", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt3", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt4", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt5", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt6", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt7", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt8", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt9", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt10", "QName is Trace Test, not TraceTest" );
+
+
+
+    activeThreads += 2;
+	t1 = PR_CreateThread(PR_USER_THREAD,
+			RecordTrace, NULL, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t1);
+
+	t2 = PR_CreateThread(PR_USER_THREAD,
+			SampleTrace, 0, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t2);
+        
+    ListTraces();
+
+    PR_GET_TRACE_HANDLE_FROM_NAME( th, "TraceTest","tt1" );
+    PR_ASSERT( th == hTrace );
+
+    PR_LOG( lm, msgLevel,
+        ("End TraceTest"));    
+    return;
+} /* end TraceTest() */
+
+
+/*
+** Ordered lock test.
+*/
+static void OrderedLockTest( void )
+{
+    PR_LOG( lm, msgLevel,
+        ("Begin OrderedLockTest"));    
+
+    
+} /* end OrderedLockTest() */
+
+
+int main(int argc, char **argv)
+{
+#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
+    PRUint32    counter;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hdv:");
+    lm = PR_NewLogModule("Test");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'v':  /* verbose mode */
+			msgLevel = (PRLogModuleLevel)atol( opt->value);
+            break;
+        case 'h':  /* help message */
+			Help();
+			help = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_CREATE_TRACE( hTrace, "TraceTest", "tt1", "A description for the trace test" );
+    mon = PR_NewMonitor();
+    PR_EnterMonitor( mon );
+
+    TraceTest();
+    CounterTest();
+    OrderedLockTest();
+
+    /* Wait for all threads to exit */
+    while ( activeThreads > 0 ) {
+        if ( activeThreads == 1 )
+            PR_SET_TRACE_OPTION( PRTraceStopRecording, NULL );
+    	PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+        PR_GET_COUNTER( counter, hCounter );
+    }
+    PR_ExitMonitor( mon );
+
+    /*
+    ** Evaluate results
+    */
+    PR_GET_COUNTER( counter, hCounter );
+    if ( counter != 0 )
+    {
+        failed = PR_TRUE;
+        PR_LOG( lm, msgLevel,
+            ("Expected counter == 0, found: %ld", counter));
+        printf("FAIL\n");
+    }
+    else
+    {
+        printf("PASS\n");
+    }
+
+
+    PR_DESTROY_COUNTER( hCounter );
+
+    PR_DestroyMonitor( mon );
+
+    PR_TRACE( hTrace, TraceFlow, 0xfff,0,0,0,0,0,0);
+    PR_DESTROY_TRACE( hTrace );
+#else
+    printf("Test not defined\n");
+#endif
+    return 0;
+}  /* main() */
+/* end instrumt.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/intrio.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/intrio.c
new file mode 100644
index 0000000..3e7c9c1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/intrio.c
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:        intrio.c
+ * Purpose:     testing i/o interrupts (see Bugzilla bug #31120)
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* for synchronization between the main thread and iothread */
+static PRLock *lock;
+static PRCondVar *cvar;
+static PRBool iothread_ready;
+
+static void PR_CALLBACK AbortIO(void *arg)
+{
+    PRStatus rv;
+    PR_Sleep(PR_SecondsToInterval(2));
+    rv = PR_Interrupt((PRThread*)arg);
+    PR_ASSERT(PR_SUCCESS == rv);
+}  /* AbortIO */
+
+static void PR_CALLBACK IOThread(void *arg)
+{
+    PRFileDesc *sock, *newsock;
+    PRNetAddr addr;
+
+    sock = PR_OpenTCPSocket(PR_AF_INET6);
+    if (sock == NULL) {
+        fprintf(stderr, "PR_OpenTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Bind(sock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    if (PR_Listen(sock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+    /* tell the main thread that we are ready */
+    PR_Lock(lock);
+    iothread_ready = PR_TRUE;
+    PR_NotifyCondVar(cvar);
+    PR_Unlock(lock);
+    newsock = PR_Accept(sock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (newsock != NULL) {
+        fprintf(stderr, "PR_Accept shouldn't have succeeded\n");
+        exit(1);
+    }
+    if (PR_GetError() != PR_PENDING_INTERRUPT_ERROR) {
+        fprintf(stderr, "PR_Accept failed (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    printf("PR_Accept() is interrupted as expected\n");
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+static void Test(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *iothread, *abortio;
+
+    printf("A %s thread will be interrupted by a %s thread\n",
+        (scope1 == PR_LOCAL_THREAD ? "local" : "global"),
+        (scope2 == PR_LOCAL_THREAD ? "local" : "global"));
+    iothread_ready = PR_FALSE;
+    iothread = PR_CreateThread(
+        PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL,
+        scope1, PR_JOINABLE_THREAD, 0);
+    if (iothread == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        exit(1);
+    }
+    PR_Lock(lock);
+    while (!iothread_ready)
+        PR_WaitCondVar(cvar, PR_INTERVAL_NO_TIMEOUT);
+    PR_Unlock(lock);
+    abortio = PR_CreateThread(
+        PR_USER_THREAD, AbortIO, iothread, PR_PRIORITY_NORMAL,
+        scope2, PR_JOINABLE_THREAD, 0);
+    if (abortio == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        exit(1);
+    }
+    if (PR_JoinThread(iothread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(abortio) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+    lock = PR_NewLock();
+    if (lock == NULL) {
+        fprintf(stderr, "PR_NewLock failed\n");
+        exit(1);
+    }
+    cvar = PR_NewCondVar(lock);
+    if (cvar == NULL) {
+        fprintf(stderr, "PR_NewCondVar failed\n");
+        exit(1);
+    }
+    /* test all four combinations */
+    Test(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+    Test(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+    Test(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+    Test(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+    printf("PASSED\n");
+    return 0;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/intrupt.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/intrupt.c
new file mode 100644
index 0000000..1d9dc69
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/intrupt.c
@@ -0,0 +1,362 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:        intrupt.c
+ * Purpose:     testing thread interrupts
+ */
+
+#include "plgetopt.h"
+#include "prcvar.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prthread.h"
+#include "prtypes.h"
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#define DEFAULT_TCP_PORT 12500
+
+static PRLock *ml = NULL;
+static PRCondVar *cv = NULL;
+
+static PRBool passed = PR_TRUE;
+static PRBool debug_mode = PR_FALSE;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+static void PR_CALLBACK AbortCV(void *arg)
+{
+    PRStatus rv;
+    PRThread *me = PR_GetCurrentThread();
+
+    /* some other thread (main) is doing the interrupt */
+    PR_Lock(ml);
+    rv = PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+    if (debug_mode) printf( "Expected interrupt on wait CV and ");
+    if (PR_FAILURE == rv)
+    {
+        if (PR_PENDING_INTERRUPT_ERROR == PR_GetError())
+        {
+            if (debug_mode) printf("got it\n");
+        }
+        else
+        {
+            if (debug_mode) printf("got random error\n");
+            passed = PR_FALSE;
+        }
+    }
+    else
+    {
+        if (debug_mode) printf("got a successful completion\n");
+        passed = PR_FALSE;
+    }
+
+    rv = PR_WaitCondVar(cv, 10);
+    if (debug_mode)
+    {
+        printf(
+            "Expected success on wait CV and %s\n",
+            (PR_SUCCESS == rv) ? "got it" : "failed");
+    }
+    passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
+
+    /* interrupt myself, then clear */
+    PR_Interrupt(me);
+    PR_ClearInterrupt();
+    rv = PR_WaitCondVar(cv, 10);
+    if (debug_mode)
+    {
+        printf("Expected success on wait CV and ");
+        if (PR_FAILURE == rv)
+        {
+            printf(
+                "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ?
+                "got interrupted" : "a random failure");
+        }
+        printf("got it\n");
+    }
+    passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
+
+    /* set, then wait - interrupt - then wait again */
+    PR_Interrupt(me);
+    rv = PR_WaitCondVar(cv, 10);
+    if (debug_mode) printf( "Expected interrupt on wait CV and ");
+    if (PR_FAILURE == rv)
+    {
+        if (PR_PENDING_INTERRUPT_ERROR == PR_GetError())
+        {
+            if (debug_mode) printf("got it\n");
+        }
+        else
+        {
+            if (debug_mode) printf("failed\n");
+            passed = PR_FALSE;
+        }
+    }
+    else
+    {
+        if (debug_mode) printf("got a successful completion\n");
+        passed = PR_FALSE;
+    }
+
+    rv = PR_WaitCondVar(cv, 10);
+    if (debug_mode)
+    {
+        printf(
+            "Expected success on wait CV and %s\n",
+            (PR_SUCCESS == rv) ? "got it" : "failed");
+    }
+    passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
+
+    PR_Unlock(ml);
+
+}  /* AbortCV */
+
+static void PR_CALLBACK AbortIO(void *arg)
+{
+    PRStatus rv;
+    PR_Sleep(PR_SecondsToInterval(2));
+    rv = PR_Interrupt((PRThread*)arg);
+    PR_ASSERT(PR_SUCCESS == rv);
+}  /* AbortIO */
+
+static void PR_CALLBACK AbortJoin(void *arg)
+{
+}  /* AbortJoin */
+
+static void setup_listen_socket(PRFileDesc **listner, PRNetAddr *netaddr)
+{
+    PRStatus rv;
+    PRInt16 port = DEFAULT_TCP_PORT;
+
+    *listner = PR_NewTCPSocket();
+    PR_ASSERT(*listner != NULL);
+    memset(netaddr, 0, sizeof(*netaddr));
+    (*netaddr).inet.ip = PR_htonl(PR_INADDR_ANY);
+    (*netaddr).inet.family = PR_AF_INET;
+    do
+    {
+        (*netaddr).inet.port = PR_htons(port);
+        rv = PR_Bind(*listner, netaddr);
+        port += 1;
+        PR_ASSERT(port < (DEFAULT_TCP_PORT + 10));
+    } while (PR_FAILURE == rv);
+
+    rv = PR_Listen(*listner, 5);
+
+	if (PR_GetSockName(*listner, netaddr) < 0) {
+		if (debug_mode) printf("intrupt: ERROR - PR_GetSockName failed\n");
+		passed = PR_FALSE;
+		return;
+	}
+
+}
+
+static void PR_CALLBACK IntrBlock(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr netaddr;
+    PRFileDesc *listner;
+
+    /* some other thread (main) is doing the interrupt */
+	/* block the interrupt */
+	PR_BlockInterrupt();
+    PR_Lock(ml);
+    rv = PR_WaitCondVar(cv, PR_SecondsToInterval(4));
+	PR_Unlock(ml);
+    if (debug_mode)
+    {
+        printf("Expected success on wait CV and ");
+        if (PR_FAILURE == rv)
+        {
+            printf(
+                "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ?
+                "got interrupted" : "got a random failure");
+        } else
+        	printf("got it\n");
+    }
+    passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
+
+	setup_listen_socket(&listner, &netaddr);
+	PR_UnblockInterrupt();
+    if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL)
+    {
+        PRInt32 error = PR_GetError();
+        if (debug_mode) printf("Expected interrupt on PR_Accept() and ");
+        if (PR_PENDING_INTERRUPT_ERROR == error)
+        {
+            if (debug_mode) printf("got it\n");
+        }
+        else
+        {
+            if (debug_mode) printf("failed\n");
+            passed = PR_FALSE;
+        }
+    }
+    else
+    {
+        if (debug_mode) printf("Failed to interrupt PR_Accept()\n");
+        passed = PR_FALSE;
+    }
+
+    (void)PR_Close(listner); listner = NULL;
+}  /* TestIntrBlock */
+
+void PR_CALLBACK Intrupt(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr netaddr;
+    PRFileDesc *listner;
+    PRThread *abortCV, *abortIO, *abortJoin, *intrBlock;
+
+    ml = PR_NewLock();
+    cv = PR_NewCondVar(ml);
+
+    /* Part I */
+    if (debug_mode) printf("Part I\n");
+    abortCV = PR_CreateThread(
+        PR_USER_THREAD, AbortCV, 0, PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+
+    PR_Sleep(PR_SecondsToInterval(2));
+    rv = PR_Interrupt(abortCV);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(abortCV);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    /* Part II */
+    if (debug_mode) printf("Part II\n");
+    abortJoin = PR_CreateThread(
+        PR_USER_THREAD, AbortJoin, 0, PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+    PR_Sleep(PR_SecondsToInterval(2));
+    if (debug_mode) printf("Expecting to interrupt an exited thread ");
+    rv = PR_Interrupt(abortJoin);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(abortJoin);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (debug_mode) printf("and succeeded\n");
+
+    /* Part III */
+    if (debug_mode) printf("Part III\n");
+	setup_listen_socket(&listner, &netaddr);
+    abortIO = PR_CreateThread(
+        PR_USER_THREAD, AbortIO, PR_GetCurrentThread(), PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+
+    if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL)
+    {
+        PRInt32 error = PR_GetError();
+        if (debug_mode) printf("Expected interrupt on PR_Accept() and ");
+        if (PR_PENDING_INTERRUPT_ERROR == error)
+        {
+            if (debug_mode) printf("got it\n");
+        }
+        else
+        {
+            if (debug_mode) printf("failed\n");
+            passed = PR_FALSE;
+        }
+    }
+    else
+    {
+        if (debug_mode) printf("Failed to interrupt PR_Accept()\n");
+        passed = PR_FALSE;
+    }
+
+    (void)PR_Close(listner); listner = NULL;
+
+    rv = PR_JoinThread(abortIO);
+    PR_ASSERT(PR_SUCCESS == rv);
+    /* Part VI */
+    if (debug_mode) printf("Part VI\n");
+    intrBlock = PR_CreateThread(
+        PR_USER_THREAD, IntrBlock, 0, PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+
+    PR_Sleep(PR_SecondsToInterval(2));
+    rv = PR_Interrupt(intrBlock);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(intrBlock);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);    
+}  /* Intrupt */
+
+int main(int argc, char **argv)
+{
+    PRThread *intrupt;
+	PLOptStatus os;
+  	PLOptState *opt = PL_CreateOptState(argc, argv, "dG");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+    intrupt = PR_CreateThread(
+        PR_USER_THREAD, Intrupt, NULL, PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+    if (intrupt == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        passed = PR_FALSE;
+    } else {
+        PRStatus rv;
+        rv = PR_JoinThread(intrupt);
+        PR_ASSERT(rv == PR_SUCCESS);
+    }
+    printf("%s\n", ((passed) ? "PASSED" : "FAILED"));
+	return ((passed) ? 0 : 1);
+}  /* main */
+
+/* intrupt.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeout.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeout.c
new file mode 100644
index 0000000..617d6e8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeout.c
@@ -0,0 +1,288 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Test socket IO timeouts
+**
+**
+**
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include "nspr.h"
+
+#define NUM_THREADS 1
+#define BASE_PORT   8000
+#define DEFAULT_ACCEPT_TIMEOUT 2
+
+typedef struct threadInfo {
+    PRInt16 id;
+    PRInt16 accept_timeout;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32   *alive;
+} threadInfo;
+
+PRIntn failed_already = 0;
+PRIntn debug_mode = 0;
+
+#define	LOCAL_SCOPE_STRING			"LOCAL scope"
+#define	GLOBAL_SCOPE_STRING			"GLOBAL scope"
+#define	GLOBAL_BOUND_SCOPE_STRING	"GLOBAL_BOUND scope"
+
+void 
+thread_main(void *_info)
+{
+    threadInfo *info = (threadInfo *)_info;
+    PRNetAddr listenAddr;
+    PRNetAddr clientAddr;
+    PRFileDesc *listenSock = NULL;
+    PRFileDesc *clientSock;
+    PRStatus rv;
+	PRThreadScope tscope;
+	char *scope_str;
+
+ 
+	if (debug_mode)
+    	printf("thread %d is alive\n", info->id);
+	tscope = PR_GetThreadScope(PR_GetCurrentThread());
+
+	switch(tscope) {
+		case PR_LOCAL_THREAD:
+			scope_str = LOCAL_SCOPE_STRING;
+			break;
+		case PR_GLOBAL_THREAD:
+			scope_str = GLOBAL_SCOPE_STRING;
+			break;
+		case PR_GLOBAL_BOUND_THREAD:
+			scope_str = GLOBAL_BOUND_SCOPE_STRING;
+			break;
+		default:
+			PR_ASSERT(!"Invalid thread scope");
+			break;
+	}
+	printf("thread id %d, scope %s\n", info->id, scope_str);
+
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+		if (debug_mode)
+        	printf("unable to create listen socket\n");
+		failed_already=1;
+        goto dead;
+    }
+  
+    listenAddr.inet.family = PR_AF_INET;
+    listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
+    listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    rv = PR_Bind(listenSock, &listenAddr);
+    if (rv == PR_FAILURE) {
+		if (debug_mode)
+        	printf("unable to bind\n");
+		failed_already=1;
+        goto dead;
+    }
+
+    rv = PR_Listen(listenSock, 4);
+    if (rv == PR_FAILURE) {
+		if (debug_mode)
+        	printf("unable to listen\n");
+		failed_already=1;
+        goto dead;
+    }
+
+	if (debug_mode)
+    	printf("thread %d going into accept for %d seconds\n", 
+        	info->id, info->accept_timeout + info->id);
+
+    clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id));
+
+    if (clientSock == NULL) {
+        if (PR_GetError() == PR_IO_TIMEOUT_ERROR) {
+			if (debug_mode) {	
+            	printf("PR_Accept() timeout worked!\n"); 
+				printf("TEST PASSED! PR_Accept() returned error %d\n",
+							PR_IO_TIMEOUT_ERROR);
+			}
+    	} else {
+			if (debug_mode)
+            	printf("TEST FAILED! PR_Accept() returned error %d\n",
+														PR_GetError());
+			failed_already=1;
+		}
+    } else {
+		if (debug_mode)
+        	printf ("TEST FAILED! PR_Accept() succeeded?\n");
+		failed_already=1;
+		PR_Close(clientSock);
+    }
+
+dead:
+    if (listenSock) {
+		PR_Close(listenSock);
+    }
+    PR_Lock(info->dead_lock);
+    (*info->alive)--;
+    PR_NotifyCondVar(info->dead_cv);
+    PR_Unlock(info->dead_lock);
+
+	if (debug_mode)
+    	printf("thread %d is dead\n", info->id);
+
+    PR_Free(info);
+}
+
+void
+thread_test(PRThreadScope scope, PRInt32 num_threads)
+{
+    PRInt32 index;
+    PRThread *thr;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32 alive;
+
+	if (debug_mode)
+    	printf("IO Timeout test started with %d threads\n", num_threads);
+
+    dead_lock = PR_NewLock();
+    dead_cv = PR_NewCondVar(dead_lock);
+    alive = num_threads;
+    
+    for (index = 0; index < num_threads; index++) {
+        threadInfo *info = (threadInfo *)PR_Malloc(sizeof(threadInfo));
+
+        info->id = index;
+        info->dead_lock = dead_lock;
+        info->dead_cv = dead_cv;
+        info->alive = &alive;
+        info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT;
+        
+        thr = PR_CreateThread( PR_USER_THREAD,
+                               thread_main,
+                               (void *)info,
+                               PR_PRIORITY_NORMAL,
+                               scope,
+                               PR_UNJOINABLE_THREAD,
+                               0);
+
+        if (!thr) {
+        	printf("Failed to create thread, error = %d(%d)\n",
+											PR_GetError(), PR_GetOSError());
+			failed_already=1;
+
+            PR_Lock(dead_lock);
+            alive--;
+            PR_Unlock(dead_lock);
+        }
+    }
+
+    PR_Lock(dead_lock);
+    while(alive) {
+		if (debug_mode)
+        	printf("main loop awake; alive = %d\n", alive);
+        PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(dead_lock);
+
+    PR_DestroyCondVar(dead_cv);
+    PR_DestroyLock(dead_lock);
+}
+
+int main(int argc, char **argv)
+{
+    PRInt32 num_threads = 0;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name [-d] [-t <threads>]
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 't':  /* threads to involve */
+			num_threads = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    if (0 == num_threads)
+        num_threads = NUM_THREADS;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0);
+    PR_STDIO_INIT();
+
+    printf("test with global bound thread\n");
+    thread_test(PR_GLOBAL_BOUND_THREAD, num_threads);
+
+    printf("test with local thread\n");
+    thread_test(PR_LOCAL_THREAD, num_threads);
+
+    printf("test with global thread\n");
+    thread_test(PR_GLOBAL_THREAD, num_threads);
+
+    PR_Cleanup();
+
+	if (failed_already)
+		return 1;
+	else
+    	return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeoutk.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeoutk.c
new file mode 100644
index 0000000..26e3bee
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeoutk.c
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** name io_timeoutk.c
+** Description:Test socket IO timeouts (kernel level)
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include "nspr.h"
+
+#define NUM_THREADS 1
+#define BASE_PORT   8000
+#define DEFAULT_ACCEPT_TIMEOUT 2
+
+typedef struct threadInfo {
+    PRInt16 id;
+    PRInt16 accept_timeout;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32   *alive;
+} threadInfo;
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+void 
+thread_main(void *_info)
+{
+    threadInfo *info = (threadInfo *)_info;
+    PRNetAddr listenAddr;
+    PRNetAddr clientAddr;
+    PRFileDesc *listenSock = NULL;
+    PRFileDesc *clientSock;
+    PRStatus rv;
+ 
+    if (debug_mode) printf("thread %d is alive\n", info->id);
+
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+        if (debug_mode) printf("unable to create listen socket\n");
+        goto dead;
+    }
+  
+    listenAddr.inet.family = AF_INET;
+    listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
+    listenAddr.inet.ip = PR_htonl(INADDR_ANY);
+    rv = PR_Bind(listenSock, &listenAddr);
+    if (rv == PR_FAILURE) {
+        if (debug_mode) printf("unable to bind\n");
+        goto dead;
+    }
+
+    rv = PR_Listen(listenSock, 4);
+    if (rv == PR_FAILURE) {
+        if (debug_mode) printf("unable to listen\n");
+        goto dead;
+    }
+
+    if (debug_mode) printf("thread %d going into accept for %d seconds\n", 
+        info->id, info->accept_timeout + info->id);
+
+    clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id));
+
+    if (clientSock == NULL) {
+        if (PR_GetError() == PR_IO_TIMEOUT_ERROR) 
+            if (debug_mode) {
+				printf("PR_Accept() timeout worked!\n");
+                printf("TEST FAILED! PR_Accept() returned error %d\n",
+								   PR_GetError());
+			}
+			else failed_already=1;
+    } else {
+        if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n");
+		else failed_already=1;
+	PR_Close(clientSock);
+    }
+
+dead:
+    if (listenSock) {
+	PR_Close(listenSock);
+    }
+    PR_Lock(info->dead_lock);
+    (*info->alive)--;
+    PR_NotifyCondVar(info->dead_cv);
+    PR_Unlock(info->dead_lock);
+
+    if (debug_mode) printf("thread %d is dead\n", info->id);
+}
+
+void
+thread_test(PRInt32 scope, PRInt32 num_threads)
+{
+    PRInt32 index;
+    PRThread *thr;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32 alive;
+
+    if (debug_mode) printf("IO Timeout test started with %d threads\n", num_threads);
+
+    dead_lock = PR_NewLock();
+    dead_cv = PR_NewCondVar(dead_lock);
+    alive = num_threads;
+    
+    for (index = 0; index < num_threads; index++) {
+        threadInfo *info = (threadInfo *)malloc(sizeof(threadInfo));
+
+        info->id = index;
+        info->dead_lock = dead_lock;
+        info->dead_cv = dead_cv;
+        info->alive = &alive;
+        info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT;
+        
+        thr = PR_CreateThread( PR_USER_THREAD,
+                               thread_main,
+                               (void *)info,
+                               PR_PRIORITY_NORMAL,
+                               scope,
+                               PR_UNJOINABLE_THREAD,
+                               0);
+
+        if (!thr) {
+            PR_Lock(dead_lock);
+            alive--;
+            PR_Unlock(dead_lock);
+        }
+    }
+
+    PR_Lock(dead_lock);
+    while(alive) {
+        if (debug_mode) printf("main loop awake; alive = %d\n", alive);
+        PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(dead_lock);
+}
+
+int main(int argc, char **argv)
+{
+    PRInt32 num_threads;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    if (argc > 2)
+        num_threads = atoi(argv[2]);
+    else
+        num_threads = NUM_THREADS;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode)     printf("kernel level test\n");
+    thread_test(PR_GLOBAL_THREAD, num_threads);
+
+     PR_Cleanup();
+     
+     if(failed_already)    
+        return 1;
+    else
+        return 0;
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeoutu.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeoutu.c
new file mode 100644
index 0000000..c17a93f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/io_timeoutu.c
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/*
+** name io_timeoutu.c
+** Description: Test socket IO timeouts (user level)
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include "nspr.h"
+
+#define NUM_THREADS 1
+#define BASE_PORT   8000
+#define DEFAULT_ACCEPT_TIMEOUT 2
+
+typedef struct threadInfo {
+    PRInt16 id;
+    PRInt16 accept_timeout;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32   *alive;
+} threadInfo;
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+void 
+thread_main(void *_info)
+{
+    threadInfo *info = (threadInfo *)_info;
+    PRNetAddr listenAddr;
+    PRNetAddr clientAddr;
+    PRFileDesc *listenSock = NULL;
+    PRFileDesc *clientSock;
+    PRStatus rv;
+ 
+    if (debug_mode) printf("thread %d is alive\n", info->id);
+
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+        if (debug_mode) printf("unable to create listen socket\n");
+        goto dead;
+    }
+  
+    listenAddr.inet.family = AF_INET;
+    listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
+    listenAddr.inet.ip = PR_htonl(INADDR_ANY);
+    rv = PR_Bind(listenSock, &listenAddr);
+    if (rv == PR_FAILURE) {
+        if (debug_mode) printf("unable to bind\n");
+        goto dead;
+    }
+
+    rv = PR_Listen(listenSock, 4);
+    if (rv == PR_FAILURE) {
+        if (debug_mode) printf("unable to listen\n");
+        goto dead;
+    }
+
+    if (debug_mode) printf("thread %d going into accept for %d seconds\n", 
+        info->id, info->accept_timeout + info->id);
+
+    clientSock = PR_Accept(
+		listenSock, &clientAddr, PR_SecondsToInterval(
+			info->accept_timeout + info->id));
+
+    if (clientSock == NULL) {
+        if (PR_GetError() == PR_IO_TIMEOUT_ERROR) 
+            if (debug_mode) {
+				printf("PR_Accept() timeout worked!\n");
+                printf("TEST FAILED! PR_Accept() returned error %d\n",
+			}
+								   PR_GetError());
+			else failed_already=1;
+    } else {
+        if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n");
+		else failed_already=1;
+	PR_Close(clientSock);
+    }
+
+dead:
+    if (listenSock) {
+	PR_Close(listenSock);
+    }
+    PR_Lock(info->dead_lock);
+    (*info->alive)--;
+    PR_NotifyCondVar(info->dead_cv);
+    PR_Unlock(info->dead_lock);
+
+    if (debug_mode) printf("thread %d is dead\n", info->id);
+}
+
+void
+thread_test(PRInt32 scope, PRInt32 num_threads)
+{
+    PRInt32 index;
+    PRThread *thr;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32 alive;
+
+    if (debug_mode) printf("IO Timeout test started with %d threads\n", num_threads);
+
+    dead_lock = PR_NewLock();
+    dead_cv = PR_NewCondVar(dead_lock);
+    alive = num_threads;
+    
+    for (index = 0; index < num_threads; index++) {
+        threadInfo *info = (threadInfo *)malloc(sizeof(threadInfo));
+
+        info->id = index;
+        info->dead_lock = dead_lock;
+        info->dead_cv = dead_cv;
+        info->alive = &alive;
+        info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT;
+        
+        thr = PR_CreateThread( PR_USER_THREAD,
+                               thread_main,
+                               (void *)info,
+                               PR_PRIORITY_NORMAL,
+                               scope,
+                               PR_UNJOINABLE_THREAD,
+                               0);
+
+        if (!thr) {
+            PR_Lock(dead_lock);
+            alive--;
+            PR_Unlock(dead_lock);
+        }
+    }
+
+    PR_Lock(dead_lock);
+    while(alive) {
+        if (debug_mode) printf("main loop awake; alive = %d\n", alive);
+        PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(dead_lock);
+}
+
+int main(int argc, char **argv)
+{
+    PRInt32 num_threads;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    if (argc > 2)
+        num_threads = atoi(argv[2]);
+    else
+        num_threads = NUM_THREADS;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) printf("user level test\n");
+    thread_test(PR_LOCAL_THREAD, num_threads);
+
+     PR_Cleanup();
+     if(failed_already)    
+        return 1;
+     else
+        return 0;
+     
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/ioconthr.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ioconthr.c
new file mode 100644
index 0000000..2e39522
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ioconthr.c
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This is a test for the io continuation thread machinery
+ * in pthreads.
+ */
+
+#include "nspr.h"
+#include <stdio.h>
+
+int num_threads = 10;  /* must be an even number */
+PRThreadScope thread_scope = PR_GLOBAL_THREAD;
+
+void ThreadFunc(void *arg)
+{
+    PRFileDesc *fd = (PRFileDesc *) arg;
+    char buf[1024];
+    PRInt32 nbytes;
+    PRErrorCode err;
+
+    nbytes = PR_Recv(fd, buf, sizeof(buf), 0, PR_SecondsToInterval(20));
+    if (nbytes == -1) {
+        err = PR_GetError();
+        if (err != PR_PENDING_INTERRUPT_ERROR) {
+            fprintf(stderr, "PR_Recv failed: (%d, %d)\n",
+                    err, PR_GetOSError());
+            PR_ProcessExit(1);
+        }
+        /*
+         * After getting an I/O interrupt, this thread must
+         * close the fd before it exits due to a limitation
+         * of our NT implementation.
+         */
+        if (PR_Close(fd) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            PR_ProcessExit(1);
+        }
+    } else {
+        fprintf(stderr, "PR_Recv received %d bytes!?\n", nbytes);
+        PR_ProcessExit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc **fds;
+    PRThread **threads;
+    PRIntervalTime start, elapsed;
+    int index;
+
+    fds = (PRFileDesc **) PR_MALLOC(2 * num_threads * sizeof(PRFileDesc *));
+    PR_ASSERT(fds != NULL);
+    threads = (PRThread **) PR_MALLOC(num_threads * sizeof(PRThread *));
+    PR_ASSERT(threads != NULL);
+
+    for (index = 0; index < num_threads; index++) {
+        if (PR_NewTCPSocketPair(&fds[2 * index]) == PR_FAILURE) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            PR_ProcessExit(1);
+        }
+        threads[index] = PR_CreateThread(
+                PR_USER_THREAD, ThreadFunc, fds[2 * index],
+                PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 0);
+        if (NULL == threads[index]) {
+            fprintf(stderr, "PR_CreateThread failed\n");
+            PR_ProcessExit(1);
+        }
+    }
+
+    /* Let the threads block in PR_Recv */
+    PR_Sleep(PR_SecondsToInterval(2));
+
+    printf("Interrupting the threads\n");
+    fflush(stdout);
+    start = PR_IntervalNow();
+    for (index = 0; index < num_threads; index++) {
+        if (PR_Interrupt(threads[index]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Interrupt failed\n");
+            PR_ProcessExit(1);
+        }
+    }
+    for (index = 0; index < num_threads; index++) {
+        if (PR_JoinThread(threads[index]) == PR_FAILURE) {
+            fprintf(stderr, "PR_JoinThread failed\n");
+            PR_ProcessExit(1);
+        }
+    }
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start);
+    printf("Threads terminated in %d milliseconds\n",
+            PR_IntervalToMilliseconds(elapsed));
+    fflush(stdout);
+    
+    /* We are being very generous and allow 10 seconds. */
+    if (elapsed >= PR_SecondsToInterval(10)) {
+        fprintf(stderr, "Interrupting threads took longer than 10 seconds!!\n");
+        PR_ProcessExit(1);
+    }
+
+    for (index = 0; index < num_threads; index++) {
+        /* fds[2 * index] was passed to and closed by threads[index]. */
+        if (PR_Close(fds[2 * index + 1]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            PR_ProcessExit(1);
+        }
+    }
+    PR_DELETE(threads);
+    PR_DELETE(fds);
+    printf("PASS\n");
+    PR_Cleanup();
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/ipv6.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ipv6.c
new file mode 100644
index 0000000..571716f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ipv6.c
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prenv.h"
+#include "prmem.h"
+#include "prlink.h"
+#include "prsystem.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prvrsion.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+#include "obsolete/probslet.h"
+
+#include <string.h>
+
+#define DNS_BUFFER 100
+#define ADDR_BUFFER 100
+#define HOST_BUFFER 1024
+#define PROTO_BUFFER 1500
+
+#define NETADDR_SIZE(addr) \
+    (PR_AF_INET == (addr)->raw.family ? \
+    sizeof((addr)->inet) : sizeof((addr)->ipv6))
+
+static PRFileDesc *err = NULL;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-V] [-h]\n");
+    PR_fprintf(err, "\t<nul>    Name of host to lookup          (default: self)\n");
+    PR_fprintf(err, "\t-V       Display runtime version info    (default: FALSE)\n");
+    PR_fprintf(err, "\t-h       This message and nothing else\n");
+}  /* Help */
+
+static void DumpAddr(const PRNetAddr* address, const char *msg)
+{
+    PRUint32 *word = (PRUint32*)address;
+    PRUint32 addr_len = sizeof(PRNetAddr);
+    PR_fprintf(err, "%s[%d]\t", msg, NETADDR_SIZE(address));
+    while (addr_len > 0)
+    {
+        PR_fprintf(err, " %08x", *word++);
+        addr_len -= sizeof(PRUint32);
+    }
+    PR_fprintf(err, "\n");
+}  /* DumpAddr */
+
+static PRStatus PrintAddress(const PRNetAddr* address)
+{
+    PRNetAddr translation;
+    char buffer[ADDR_BUFFER];
+    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
+    if (PR_FAILURE == rv) PL_FPrintError(err, "PR_NetAddrToString");
+    else
+    {
+        PR_fprintf(err, "\t%s\n", buffer);
+        memset(&translation, 0, sizeof(translation));
+        rv = PR_StringToNetAddr(buffer, &translation);
+        if (PR_FAILURE == rv) PL_FPrintError(err, "PR_StringToNetAddr");
+        else
+        {
+            PRSize addr_len = NETADDR_SIZE(address);
+            if (0 != memcmp(address, &translation, addr_len))
+            {
+                PR_fprintf(err, "Address translations do not match\n");
+                DumpAddr(address, "original");
+                DumpAddr(&translation, "translate");
+                rv = PR_FAILURE;
+            }
+        }
+    }
+    return rv;
+}  /* PrintAddress */
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+    PLOptStatus os;
+    PRHostEnt host;
+    PRProtoEnt proto;
+    const char *name = NULL;
+    PRBool failed = PR_FALSE, version = PR_FALSE;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "Vh");
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:  /* Name of host to lookup */
+            name = opt->value;
+            break;
+         case 'V':  /* Do version discovery */
+            version = PR_TRUE;
+            break;
+        case 'h':  /* user wants some guidance */
+         default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (version)
+    {
+#if defined(WINNT)
+#define NSPR_LIB "libnspr4"
+#else
+#define NSPR_LIB "nspr4"
+#endif
+        const PRVersionDescription *version_info;
+        char *nspr_path = PR_GetEnv("LD_LIBRARY_PATH");
+        char *nspr_name = PR_GetLibraryName(nspr_path, NSPR_LIB);
+        PRLibrary *runtime = PR_LoadLibrary(nspr_name);
+        if (NULL == runtime)
+            PL_FPrintError(err, "PR_LoadLibrary");
+        else
+        {
+            versionEntryPointType versionPoint = (versionEntryPointType)
+                PR_FindSymbol(runtime, "libVersionPoint");
+            if (NULL == versionPoint)
+                PL_FPrintError(err, "PR_FindSymbol");
+            else
+            {
+                char buffer[100];
+                PRExplodedTime exploded;
+                version_info = versionPoint();
+                (void)PR_fprintf(err, "Runtime library version information\n");
+                PR_ExplodeTime(
+                    version_info->buildTime, PR_GMTParameters, &exploded);
+                (void)PR_FormatTime(
+                    buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded);
+                (void)PR_fprintf(err, "  Build time: %s GMT\n", buffer);
+                (void)PR_fprintf(
+                    err, "  Build time: %s\n", version_info->buildTimeString);
+                (void)PR_fprintf(
+                    err, "  %s V%u.%u.%u (%s%s%s)\n",
+                    version_info->description,
+                    version_info->vMajor,
+                    version_info->vMinor,
+                    version_info->vPatch,
+                    (version_info->beta ? " beta " : ""),
+                    (version_info->debug ? " debug " : ""),
+                    (version_info->special ? " special" : ""));
+                (void)PR_fprintf(err, "  filename: %s\n", version_info->filename);
+                (void)PR_fprintf(err, "  security: %s\n", version_info->security);
+                (void)PR_fprintf(err, "  copyright: %s\n", version_info->copyright);
+                (void)PR_fprintf(err, "  comment: %s\n", version_info->comment);
+            }
+        }
+        if (NULL != nspr_name) PR_FreeLibraryName(nspr_name);
+    }
+
+    {
+        if (NULL == name)
+        {
+            char *me = (char*)PR_MALLOC(DNS_BUFFER);
+            rv = PR_GetSystemInfo(PR_SI_HOSTNAME, me, DNS_BUFFER);
+            if (PR_FAILURE == rv)
+            {
+                failed = PR_TRUE;
+                PL_FPrintError(err, "PR_GetSystemInfo");
+                return 2;
+            }
+            name = me;  /* just leak the storage */
+        }
+    }
+
+    {
+        char buffer[HOST_BUFFER];
+        PR_fprintf(err, "Translating the name %s ...", name);
+
+        rv = PR_GetHostByName(name, buffer, sizeof(buffer), &host);
+        if (PR_FAILURE == rv)
+        {
+            failed = PR_TRUE;
+            PL_FPrintError(err, "PR_GetHostByName");
+        }
+        else
+        {
+            PRIntn index = 0;
+            PRNetAddr address;
+            memset(&address, 0, sizeof(PRNetAddr));
+            PR_fprintf(err, "success .. enumerating results\n");
+            do
+            {
+                index = PR_EnumerateHostEnt(index, &host, 0, &address);
+                if (index > 0) PrintAddress(&address);
+                else if (-1 == index)
+                {
+                    failed = PR_TRUE;
+                    PL_FPrintError(err, "PR_EnumerateHostEnt");
+                }
+            } while (index > 0);
+        }
+    }
+
+
+    {
+        char buffer[PROTO_BUFFER];
+        /*
+        ** Get Proto by name/number
+        */
+        rv = PR_GetProtoByName("tcp", &buffer[1], sizeof(buffer) - 1, &proto);
+        rv = PR_GetProtoByNumber(6, &buffer[3], sizeof(buffer) - 3, &proto);
+    }
+
+    return (failed) ? 1 : 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/join.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/join.c
new file mode 100644
index 0000000..0875aeb
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/join.c
@@ -0,0 +1,252 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: dbmalloc1.c
+**
+** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions.
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**		    AGarcia- Converted the test to accomodate the debug_mode flag.
+**          The debug mode will print all of the printfs associated with this test.
+**		    The regress mode will be the default mode. Since the regress tool limits
+**          the output to a one line status:PASS or FAIL,all of the printf statements
+**		    have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include "prttools.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**		        status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static void Test_Result (int result)
+{
+    if (result == PASS)
+        printf ("PASS\n");
+    else
+        printf ("FAIL\n");
+    exit (1);
+}
+
+
+/*
+    Program to test joining of threads.  Two threads are created.  One
+    to be waited upon until it has started.  The other to join after it has
+    completed.
+*/
+
+
+static void PR_CALLBACK lowPriority(void *arg)
+{
+}
+
+static void PR_CALLBACK highPriority(void *arg)
+{
+}
+
+static void PR_CALLBACK unjoinable(void *arg)
+{
+    PR_Sleep(PR_INTERVAL_NO_TIMEOUT);
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *low,*high;
+
+    /* create the low and high priority threads */
+    
+    low = PR_CreateThread(PR_USER_THREAD,
+                     lowPriority, 0, 
+                     PR_PRIORITY_LOW,
+                     scope1,
+                     PR_JOINABLE_THREAD,
+                     0);
+    if (!low) {
+        if (debug_mode) printf("\tcannot create low priority thread\n");
+        else Test_Result(FAIL);
+        return;
+    }
+
+    high = PR_CreateThread(PR_USER_THREAD,
+                     highPriority, 0, 
+                     PR_PRIORITY_HIGH,
+                     scope2,
+                     PR_JOINABLE_THREAD,
+                     0);
+    if (!high) {
+        if (debug_mode) printf("\tcannot create high priority thread\n");
+        else Test_Result(FAIL);
+        return;
+    }
+
+    /* Do the joining for both threads */
+    if (PR_JoinThread(low) == PR_FAILURE) {
+        if (debug_mode) printf("\tcannot join low priority thread\n");
+        else Test_Result (FAIL);
+        return;
+    } else {
+        if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+    if (PR_JoinThread(high) == PR_FAILURE) {
+        if (debug_mode) printf("\tcannot join high priority thread\n");
+        else Test_Result(FAIL);
+        return;
+    } else {
+        if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+void joinWithUnjoinable(void)
+{
+    PRThread *thread;
+
+    /* create the unjoinable thread */
+    
+    thread = PR_CreateThread(PR_USER_THREAD,
+                     unjoinable, 0, 
+                     PR_PRIORITY_NORMAL,
+                     PR_GLOBAL_THREAD,
+                     PR_UNJOINABLE_THREAD,
+                     0);
+    if (!thread) {
+        if (debug_mode) printf("\tcannot create unjoinable thread\n");
+        else Test_Result(FAIL);
+        return;
+    }
+
+    if (PR_JoinThread(thread) == PR_SUCCESS) {
+        if (debug_mode) printf("\tsuccessfully joined with unjoinable thread?!\n");
+        else Test_Result(FAIL);
+        return;
+    } else {
+        if (debug_mode) printf("\tcannot join with unjoinable thread, as expected\n");
+        if (PR_GetError() != PR_INVALID_ARGUMENT_ERROR) {
+            if (debug_mode) printf("\tWrong error code\n");
+            else Test_Result(FAIL);
+            return;
+        }
+    }
+    if (PR_Interrupt(thread) == PR_FAILURE) {
+        if (debug_mode) printf("\tcannot interrupt unjoinable thread\n");
+        else Test_Result(FAIL);
+        return;
+    } else {
+        if (debug_mode) printf("\tinterrupted unjoinable thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain(int argc, char **argv)
+{
+    /* The command line argument: -d is used to determine if the test is being run
+    in debug mode. The regress tool requires only one line output:PASS or FAIL.
+    All of the printfs associated with this test has been handled with a if (debug_mode)
+    test.
+    Usage: test_name -d
+    */
+    
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+ /* main test */
+    printf("User-User test\n");
+    runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+    printf("User-Kernel test\n");
+    runTest(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+    printf("Kernel-User test\n");
+    runTest(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+    printf("Kernel-Kernel test\n");
+    runTest(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+    printf("Join with unjoinable thread\n");
+    joinWithUnjoinable();
+
+    printf("PASSED\n");
+
+    return 0;
+}
+
+
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinkk.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinkk.c
new file mode 100644
index 0000000..ac731d3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinkk.c
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: dbmalloc1.c
+**
+** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions.
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**			 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+/*
+	Program to test joining of threads.  Two threads are created.  One
+	to be waited upon until it has started.  The other to join after it has
+	completed.
+*/
+
+
+static void lowPriority(void *arg)
+{
+}
+
+static void highPriority(void *arg)
+{
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+	PRThread *low,*high;
+
+	/* create the low and high priority threads */
+	
+	low = PR_CreateThread(PR_USER_THREAD,
+				      lowPriority, 0, 
+				      PR_PRIORITY_LOW,
+				      scope1,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!low) {
+		if (debug_mode) printf("\tcannot create low priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	high = PR_CreateThread(PR_USER_THREAD,
+				      highPriority, 0, 
+				      PR_PRIORITY_HIGH,
+				      scope2,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!high) {
+		if (debug_mode) printf("\tcannot create high priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	/* Do the joining for both threads */
+	if (PR_JoinThread(low) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join low priority thread\n");
+		else  failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+	if (PR_JoinThread(high) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join high priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+
+    if (debug_mode) printf("Kernel-Kernel test\n");
+    runTest(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+
+	if(failed_already)	
+	{
+        printf("FAIL\n");
+		return 1;
+	}
+	else
+	{
+        printf("PASS\n");
+		return 0;
+	}
+
+}
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinku.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinku.c
new file mode 100644
index 0000000..89d1529
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinku.c
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: dbmalloc1.c
+**
+** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions.
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**			 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+/*
+	Program to test joining of threads.  Two threads are created.  One
+	to be waited upon until it has started.  The other to join after it has
+	completed.
+*/
+
+
+static void lowPriority(void *arg)
+{
+}
+
+static void highPriority(void *arg)
+{
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+	PRThread *low,*high;
+
+	/* create the low and high priority threads */
+	
+	low = PR_CreateThread(PR_USER_THREAD,
+				      lowPriority, 0, 
+				      PR_PRIORITY_LOW,
+				      scope1,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!low) {
+		if (debug_mode) printf("\tcannot create low priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	high = PR_CreateThread(PR_USER_THREAD,
+				      highPriority, 0, 
+				      PR_PRIORITY_HIGH,
+				      scope2,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!high) {
+		if (debug_mode) printf("\tcannot create high priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	/* Do the joining for both threads */
+	if (PR_JoinThread(low) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join low priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+	if (PR_JoinThread(high) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join high priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+ /* main test */
+
+    if (debug_mode) printf("Kernel-User test\n");
+    runTest(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+
+
+	if(failed_already)	
+    {
+		printf("FAIL\n");    
+		return 1;
+	}
+	else
+	{
+		printf("PASS\n");    
+		return 0;
+	}
+
+}
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinuk.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinuk.c
new file mode 100644
index 0000000..284a64e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinuk.c
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: joinuk.c
+**
+** Description: Join kernel - user
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**			 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+/*
+	Program to test joining of threads.  Two threads are created.  One
+	to be waited upon until it has started.  The other to join after it has
+	completed.
+*/
+
+
+static void lowPriority(void *arg)
+{
+}
+
+static void highPriority(void *arg)
+{
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+	PRThread *low,*high;
+
+	/* create the low and high priority threads */
+	
+	low = PR_CreateThread(PR_USER_THREAD,
+				      lowPriority, 0, 
+				      PR_PRIORITY_LOW,
+				      scope1,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!low) {
+		if (debug_mode) printf("\tcannot create low priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	high = PR_CreateThread(PR_USER_THREAD,
+				      highPriority, 0, 
+				      PR_PRIORITY_HIGH,
+				      scope2,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!high) {
+		if (debug_mode) printf("\tcannot create high priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	/* Do the joining for both threads */
+	if (PR_JoinThread(low) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join low priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+	if (PR_JoinThread(high) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join high priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+ /* main test */
+
+    if (debug_mode) printf("User-Kernel test\n");
+    runTest(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+
+
+	if(failed_already)	
+	{
+        printf("FAIL\n");
+		return 1;
+    } else 
+    {
+        printf("PASS\n");
+		return 0;
+    }
+}
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinuu.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinuu.c
new file mode 100644
index 0000000..d8958a3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/joinuu.c
@@ -0,0 +1,187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: dbmalloc1.c
+**
+** Description: Join tests user - user
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**			 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+/*
+	Program to test joining of threads.  Two threads are created.  One
+	to be waited upon until it has started.  The other to join after it has
+	completed.
+*/
+
+
+static void lowPriority(void *arg)
+{
+}
+
+static void highPriority(void *arg)
+{
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+	PRThread *low,*high;
+
+	/* create the low and high priority threads */
+	
+	low = PR_CreateThread(PR_USER_THREAD,
+				      lowPriority, 0, 
+				      PR_PRIORITY_LOW,
+				      scope1,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!low) {
+		if (debug_mode) printf("\tcannot create low priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	high = PR_CreateThread(PR_USER_THREAD,
+				      highPriority, 0, 
+				      PR_PRIORITY_HIGH,
+				      scope2,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!high) {
+		if (debug_mode) printf("\tcannot create high priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	/* Do the joining for both threads */
+	if (PR_JoinThread(low) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join low priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+	if (PR_JoinThread(high) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join high priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+ /* main test */
+    if (debug_mode) printf("User-User test\n");
+    runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+
+	if(failed_already)	
+	{
+        printf("FAIL\n");
+		return 1;
+    } else 
+    {
+        printf("PASS\n");
+		return 0;
+    }
+
+
+}
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/layer.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/layer.c
new file mode 100644
index 0000000..e0e09b5
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/layer.c
@@ -0,0 +1,466 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prnetdb.h"
+#include "prthread.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+#include "prwin16.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Testing layering of I/O
+**
+**      The layered server
+** A thread that acts as a server. It creates a TCP listener with a dummy
+** layer pushed on top. Then listens for incoming connections. Each connection
+** request for connection will be layered as well, accept one request, echo
+** it back and close.
+**
+**      The layered client
+** Pretty much what you'd expect.
+*/
+
+static PRFileDesc *logFile;
+static PRDescIdentity identity;
+static PRNetAddr server_address;
+
+static PRIOMethods myMethods;
+
+typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
+
+static PRIntn minor_iterations = 5;
+static PRIntn major_iterations = 1;
+static Verbosity verbosity = quiet;
+static PRUint16 default_port = 12273;
+
+static PRFileDesc *PushLayer(PRFileDesc *stack)
+{
+    PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods);
+    PRStatus rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return stack;
+}  /* PushLayer */
+
+static PRFileDesc *PushNewLayers(PRFileDesc *stack)
+{
+	PRDescIdentity tmp_identity;
+    PRFileDesc *layer;
+    PRStatus rv;
+
+	/* push a dummy layer */
+    tmp_identity = PR_GetUniqueIdentity("Dummy 1");
+    layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods());
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer,
+															stack);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+	/* push a data procesing layer */
+    layer = PR_CreateIOLayerStub(identity, &myMethods);
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer,
+													stack);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+	/* push another dummy layer */
+    tmp_identity = PR_GetUniqueIdentity("Dummy 2");
+    layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods());
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer,
+															stack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return stack;
+}  /* PushLayer */
+
+#if 0
+static PRFileDesc *PopLayer(PRFileDesc *stack)
+{
+    PRFileDesc *popped = PR_PopIOLayer(stack, identity);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack);
+    popped->dtor(popped);
+    
+    return stack;
+}  /* PopLayer */
+#endif
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRUint8 buffer[100];
+    PRIntn empty_flags = 0;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+
+    /* Initialize the buffer so that Purify won't complain */
+    memset(buffer, 0, sizeof(buffer));
+
+    rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
+    PR_ASSERT(PR_SUCCESS == rv);
+    while (minor_iterations-- > 0)
+    {
+        bytes_sent = PR_Send(
+            stack, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        PR_ASSERT(sizeof(buffer) == bytes_sent);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Client sending %d bytes\n", bytes_sent);
+        bytes_read = PR_Recv(
+            stack, buffer, bytes_sent, empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Client receiving %d bytes\n", bytes_read);
+        PR_ASSERT(bytes_read == bytes_sent);
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Client shutting down stack\n");
+    
+    rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+}  /* Client */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRUint8 buffer[100];
+    PRFileDesc *service;
+    PRUintn empty_flags = 0;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+    PRNetAddr client_address;
+
+    service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server accepting connection\n");
+
+    do
+    {
+        bytes_read = PR_Recv(
+            service, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        if (0 != bytes_read)
+        {
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server receiving %d bytes\n", bytes_read);
+            PR_ASSERT(bytes_read > 0);
+            bytes_sent = PR_Send(
+                service, buffer, bytes_read, empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server sending %d bytes\n", bytes_sent);
+            PR_ASSERT(bytes_read == bytes_sent);
+        }
+
+    } while (0 != bytes_read);
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server shutting down and closing stack\n");
+    rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+
+}  /* Server */
+
+static PRInt32 PR_CALLBACK MyRecv(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    char *b = (char*)buf;
+    PRFileDesc *lo = fd->lower;
+    PRInt32 rv, readin = 0, request = 0;
+    rv = lo->methods->recv(lo, &request, sizeof(request), flags, timeout);
+    if (verbosity > chatty) PR_fprintf(
+        logFile, "MyRecv sending permission for %d bytes\n", request);
+    if (0 < rv)
+    {
+        if (verbosity > chatty) PR_fprintf(
+            logFile, "MyRecv received permission request for %d bytes\n", request);
+        rv = lo->methods->send(
+            lo, &request, sizeof(request), flags, timeout);
+        if (0 < rv)
+        {
+            if (verbosity > chatty) PR_fprintf(
+                logFile, "MyRecv sending permission for %d bytes\n", request);
+            while (readin < request)
+            {
+                rv = lo->methods->recv(
+                    lo, b + readin, amount - readin, flags, timeout);
+                if (rv <= 0) break;
+                if (verbosity > chatty) PR_fprintf(
+                    logFile, "MyRecv received %d bytes\n", rv);
+                readin += rv;
+            }
+            rv = readin;
+        }
+    }
+    return rv;
+}  /* MyRecv */
+
+static PRInt32 PR_CALLBACK MySend(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    PRFileDesc *lo = fd->lower;
+    const char *b = (const char*)buf;
+    PRInt32 rv, wroteout = 0, request;
+    if (verbosity > chatty) PR_fprintf(
+        logFile, "MySend asking permission to send %d bytes\n", amount);
+    rv = lo->methods->send(lo, &amount, sizeof(amount), flags, timeout);
+    if (0 < rv)
+    {
+        rv = lo->methods->recv(
+            lo, &request, sizeof(request), flags, timeout);
+        if (0 < rv)
+        {
+            PR_ASSERT(request == amount);
+            if (verbosity > chatty) PR_fprintf(
+                logFile, "MySend got permission to send %d bytes\n", request);
+            while (wroteout < request)
+            {
+                rv = lo->methods->send(
+                    lo, b + wroteout, request - wroteout, flags, timeout);
+                if (rv <= 0) break;
+                if (verbosity > chatty) PR_fprintf(
+                    logFile, "MySend wrote %d bytes\n", rv);
+                wroteout += rv;
+            }
+            rv = amount;
+        }
+    }
+    return rv;
+}  /* MySend */
+
+static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
+{
+    PRIntn verbage = (PRIntn)verbosity + delta;
+    if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;
+    else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;
+    return (Verbosity)verbage;
+}  /* ChangeVerbosity */
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+    PRIntn mits;
+    PLOptStatus os;
+    PRFileDesc *client, *service;
+    PRFileDesc *client_stack, *service_stack;
+    PRNetAddr any_address;
+    const char *server_name = NULL;
+    const PRIOMethods *stubMethods;
+    PRThread *client_thread, *server_thread;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            server_name = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            if (verbosity < noisy)
+                verbosity = ChangeVerbosity(verbosity, 1);
+            break;
+        case 'q':  /* debug mode */
+            if (verbosity > silent)
+                verbosity = ChangeVerbosity(verbosity, -1);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'C':  /* number of threads waiting */
+            major_iterations = atoi(opt->value);
+            break;
+        case 'c':  /* number of client threads */
+            minor_iterations = atoi(opt->value);
+            break;
+        case 'p':  /* default port */
+            default_port = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+
+    logFile = PR_GetSpecialFD(PR_StandardError);
+
+    identity = PR_GetUniqueIdentity("Dummy");
+    stubMethods = PR_GetDefaultIOMethods();
+
+    /*
+    ** The protocol we're going to implement is one where in order to initiate
+    ** a send, the sender must first solicit permission. Therefore, every
+    ** send is really a send - receive - send sequence.
+    */
+    myMethods = *stubMethods;  /* first get the entire batch */
+    myMethods.recv = MyRecv;  /* then override the ones we care about */
+    myMethods.send = MySend;  /* then override the ones we care about */
+
+    if (NULL == server_name)
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, default_port, &server_address);
+    else
+    {
+        rv = PR_StringToNetAddr(server_name, &server_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrNull, default_port, &server_address);
+    }
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    /* one type w/o layering */
+
+    mits = minor_iterations;
+    while (major_iterations-- > 0)
+    {
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning non-layered test\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        minor_iterations = mits;
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending non-layered test\n");
+
+        /* with layering */
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning layered test\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        PushLayer(client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+        PushLayer(service);
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        minor_iterations = mits;
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+        /* with layering, using new style stack */
+        if (verbosity > silent)
+            PR_fprintf(logFile,
+							"Beginning layered test with new style stack\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+    	client_stack = PR_CreateIOLayer(client);
+        PushNewLayers(client_stack);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+    	service_stack = PR_CreateIOLayer(service);
+        PushNewLayers(service_stack);
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        minor_iterations = mits;
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service_stack,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client_stack,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending layered test\n");
+    }
+    return 0;
+}  /* main */
+
+/* layer.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/lazyinit.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/lazyinit.c
new file mode 100644
index 0000000..1b20692
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/lazyinit.c
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        lazyinit.c
+** Description: Testing lazy initialization
+**
+**      Since you only get to initialize once, you have to rerun the test
+**      for each test case. The test cases are numbered. If you want to
+**      add more tests, take the next number and add it to the switch
+**      statement.
+**
+**      This test is problematic on systems that don't support the notion
+**      of console output. The workarounds to emulate that feature include
+**      initializations themselves, which defeats the purpose here.
+*/
+
+#include "prcvar.h"
+#include "prenv.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void PR_CALLBACK lazyEntry(void *arg)
+{
+    PR_ASSERT(NULL == arg);
+}  /* lazyEntry */
+
+
+int main(int argc, char **argv)
+{
+    PRUintn pdkey;
+    PRStatus status;
+    char *path = NULL;
+    PRDir *dir = NULL;
+    PRLock *ml = NULL;
+    PRCondVar *cv = NULL;
+    PRThread *thread = NULL;
+    PRIntervalTime interval = 0;
+    PRFileDesc *file, *udp, *tcp, *pair[2];
+    PRIntn test;
+
+    if ( argc < 2)
+    {
+        test = 0;
+    }
+    else
+        test = atoi(argv[1]);
+        
+    switch (test)
+    {
+        case 0: ml = PR_NewLock(); 
+            break;
+            
+        case 1: interval = PR_SecondsToInterval(1);
+            break;
+            
+        case 2: thread = PR_CreateThread(
+            PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); 
+            break;
+            
+        case 3: file = PR_Open("/usr/tmp/", PR_RDONLY, 0); 
+            break;
+            
+        case 4: udp = PR_NewUDPSocket(); 
+            break;
+            
+        case 5: tcp = PR_NewTCPSocket(); 
+            break;
+            
+        case 6: dir = PR_OpenDir("/usr/tmp/"); 
+            break;
+            
+        case 7: (void)PR_NewThreadPrivateIndex(&pdkey, NULL);
+            break;
+        
+        case 8: path = PR_GetEnv("PATH");
+            break;
+            
+        case 9: status = PR_NewTCPSocketPair(pair);
+            break;
+            
+        case 10: PR_SetConcurrency(2);
+            break;
+            
+        default: 
+            printf(
+                "lazyinit: unrecognized command line argument: %s\n", 
+                argv[1] );
+            printf( "FAIL\n" );
+            exit( 1 );
+            break;
+    } /* switch() */
+    return 0;
+}  /* Lazy */
+
+/* lazyinit.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/libfilename.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/libfilename.c
new file mode 100644
index 0000000..d454f5f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/libfilename.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: libfilename.c
+**
+** Description: test PR_GetLibraryFilePathname.
+**
+***********************************************************************/
+
+#include "nspr.h"
+#include "pprio.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRBool debug_mode = PR_FALSE;
+
+static PRStatus RunTest(const char *name, PRFuncPtr addr)
+{
+    char *pathname;
+    PRFileDesc *fd;
+
+    pathname = PR_GetLibraryFilePathname(name, addr);
+    if (pathname == NULL) {
+        fprintf(stderr, "PR_GetLibraryFilePathname failed\n");
+        /* we let this test pass if this function is not implemented */
+        if (PR_GetError() == PR_NOT_IMPLEMENTED_ERROR) {
+            return PR_SUCCESS;
+        }
+        return PR_FAILURE;
+    }
+
+    if (debug_mode) printf("Pathname is %s\n", pathname);
+    fd = PR_OpenFile(pathname, PR_RDONLY, 0);
+    if (fd == NULL) {
+        fprintf(stderr, "PR_Open failed: %d\n", (int)PR_GetError());
+        return PR_FAILURE;
+    }
+    if (PR_Close(fd) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed: %d\n", (int)PR_GetError());
+        return PR_FAILURE;
+    }
+    PR_Free(pathname);
+    return PR_SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+    char *name;
+    PRFuncPtr addr;
+    PRLibrary *lib;
+    PRBool failed = PR_FALSE;
+
+    if (argc >= 2 && strcmp(argv[1], "-d") == 0) {
+        debug_mode = PR_TRUE;
+    }
+
+    /* First test a library that is implicitly linked. */
+#ifdef WINNT
+    name = PR_Malloc(strlen("libnspr4.dll")+1);
+    strcpy(name, "libnspr4.dll");
+#else
+    name = PR_GetLibraryName(NULL, "nspr4");
+#endif
+    addr = (PRFuncPtr)PR_GetTCPMethods()->close;
+    if (RunTest(name, addr) == PR_FAILURE) {
+        failed = PR_TRUE;
+    }
+    PR_FreeLibraryName(name);
+
+    /* Next test a library that is dynamically loaded. */
+    name = PR_GetLibraryName("dll", "my");
+    if (debug_mode) printf("Loading library %s\n", name);
+    lib = PR_LoadLibrary(name);
+    if (!lib) {
+        fprintf(stderr, "PR_LoadLibrary failed\n");
+        exit(1);
+    }
+    PR_FreeLibraryName(name);
+    name = PR_GetLibraryName(NULL, "my");
+    addr = PR_FindFunctionSymbol(lib, "My_GetValue");
+    if (RunTest(name, addr) == PR_FAILURE) {
+        failed = PR_TRUE;
+    }
+    PR_FreeLibraryName(name);
+    PR_UnloadLibrary(lib);
+    if (failed) {
+        printf("FAIL\n");
+        return 1;
+    }
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/lltest.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/lltest.c
new file mode 100644
index 0000000..4679a2c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/lltest.c
@@ -0,0 +1,859 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ 
+/*
+** testll.c -- test suite for 64bit integer (longlong) operations
+**
+** Summary: testll [-d] | [-h]
+**
+** Where:
+** -d       set debug mode on; displays individual test failures
+** -v       verbose mode; displays progress in test, plus -d
+** -h       gives usage message.
+**
+** Description:
+** lltest.c tests the functions defined in NSPR 2.0's prlong.h.
+** 
+** Successive tests begin to depend on other LL functions working
+** correctly. So, ... Do not change the order of the tests as run
+** from main().
+** 
+** Caveats:
+** Do not even begin to think that this is an exhaustive test!
+**
+** These tests try a little of everything, but not all boundary
+** conditions and limits are tested.
+** You want better coverage? ... Add it.
+**
+** ---
+** Author: Lawrence Hardiman <larryh@netscape.com>.
+** ---
+** Revision History:
+** 01-Oct-1997. Original implementation.
+**
+*/
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+/* --- Local Definitions --- */
+#define ReportProgress(m) if (verboseMode) PR_fprintf(output, (m));
+
+
+/* --- Global variables --- */
+static PRIntn  failedAlready = 0;
+static PRFileDesc* output = NULL;
+static PRBool  debugMode = PR_FALSE;
+static PRBool  verboseMode = PR_FALSE;
+
+/*
+** Constants used in tests.
+*/
+const PRInt64 bigZero        = LL_INIT( 0, 0 );
+const PRInt64 bigOne         = LL_INIT( 0, 1 );
+const PRInt64 bigTwo         = LL_INIT( 0, 2 );
+const PRInt64 bigSixTeen     = LL_INIT( 0, 16 );        
+const PRInt64 bigThirtyTwo   = LL_INIT( 0, 32 );        
+const PRInt64 bigMinusOne    = LL_INIT( 0xffffffff, 0xffffffff );
+const PRInt64 bigMinusTwo    = LL_INIT( 0xffffffff, 0xfffffffe );
+const PRInt64 bigNumber      = LL_INIT( 0x7fffffff, 0xffffffff );
+const PRInt64 bigMinusNumber = LL_INIT( 0x80000000, 0x00000001 );
+const PRInt64 bigMaxInt32    = LL_INIT( 0x00000000, 0x7fffffff );
+const PRInt64 big2To31       = LL_INIT( 0x00000000, 0x80000000 );
+const PRUint64 bigZeroFox    = LL_INIT( 0x00000000, 0xffffffff );
+const PRUint64 bigFoxFox     = LL_INIT( 0xffffffff, 0xffffffff );
+const PRUint64 bigFoxZero    = LL_INIT( 0xffffffff, 0x00000000 );
+const PRUint64 bigEightZero  = LL_INIT( 0x80000000, 0x00000000 );
+const PRUint64 big64K        = LL_INIT( 0x00000000, 0x00010000 );
+const PRInt64 bigInt0        = LL_INIT( 0x01a00000, 0x00001000 );
+const PRInt64 bigInt1        = LL_INIT( 0x01a00000, 0x00001100 );
+const PRInt64 bigInt2        = LL_INIT( 0x01a00000, 0x00000100 );
+const PRInt64 bigInt3        = LL_INIT( 0x01a00001, 0x00001000 );
+const PRInt64 bigInt4        = LL_INIT( 0x01a00001, 0x00001100 );
+const PRInt64 bigInt5        = LL_INIT( 0x01a00001, 0x00000100 );
+const PRInt64 bigInt6        = LL_INIT( 0xb1a00000, 0x00001000 );
+const PRInt64 bigInt7        = LL_INIT( 0xb1a00000, 0x00001100 );
+const PRInt64 bigInt8        = LL_INIT( 0xb1a00000, 0x00000100 );
+const PRInt64 bigInt9        = LL_INIT( 0xb1a00001, 0x00001000 );
+const PRInt64 bigInt10       = LL_INIT( 0xb1a00001, 0x00001100 );
+const PRInt64 bigInt11       = LL_INIT( 0xb1a00001, 0x00000100 );
+const PRInt32 one = 1l;
+const PRInt32 minusOne = -1l;
+const PRInt32 sixteen  = 16l;
+const PRInt32 thirtyTwo = 32l;
+const PRInt32   sixtyThree = 63l;
+
+/*
+** SetFailed() -- Report individual test failure
+**
+*/
+static void
+SetFailed( char *what, char *how )
+{
+    failedAlready = 1;
+    if ( debugMode )
+        PR_fprintf(output, "%s: failed: %s\n", what, how );
+    return;
+}
+
+static void
+ResultFailed( char *what, char *how, PRInt64 expected, PRInt64 got)
+{
+    if ( debugMode)
+    {
+        SetFailed( what, how );
+        PR_fprintf(output, "Expected: 0x%llx   Got: 0x%llx\n", expected, got );
+    }
+    return;
+}    
+
+
+/*
+** TestAssignment() -- Test the assignment
+*/
+static void TestAssignment( void )
+{
+    PRInt64 zero = LL_Zero();
+    PRInt64 min = LL_MinInt();
+    PRInt64 max = LL_MaxInt();
+    if (!LL_EQ(zero, bigZero))
+        SetFailed("LL_EQ(zero, bigZero)", "!=");
+    if (!LL_CMP(max, >, min))
+        SetFailed("LL_CMP(max, >, min)", "!>");
+}
+
+/*
+** TestComparisons() -- Test the longlong comparison operations
+*/
+static void    
+TestComparisons( void )
+{
+    ReportProgress("Testing Comparisons Operations\n");
+         
+    /* test for zero */   
+    if ( !LL_IS_ZERO( bigZero ))
+        SetFailed( "LL_IS_ZERO", "Zero is not zero" );
+        
+    if ( LL_IS_ZERO( bigOne ))
+        SetFailed( "LL_IS_ZERO", "One tests as zero" );
+    
+    if ( LL_IS_ZERO( bigMinusOne ))
+        SetFailed( "LL_IS_ZERO", "Minus One tests as zero" );
+        
+    /* test equal */
+    if ( !LL_EQ( bigZero, bigZero ))
+        SetFailed( "LL_EQ", "zero EQ zero");
+        
+    if ( !LL_EQ( bigOne, bigOne ))
+        SetFailed( "LL_EQ", "one EQ one" );
+        
+    if ( !LL_EQ( bigNumber, bigNumber ))
+        SetFailed( "LL_EQ", "bigNumber EQ bigNumber" );
+        
+    if ( !LL_EQ( bigMinusOne, bigMinusOne ))
+        SetFailed( "LL_EQ", "minus one EQ minus one");
+    
+    if ( LL_EQ( bigZero, bigOne ))
+        SetFailed( "LL_EQ", "zero EQ one");
+        
+    if ( LL_EQ( bigOne, bigZero ))
+        SetFailed( "LL_EQ", "one EQ zero" );
+        
+    if ( LL_EQ( bigMinusOne, bigOne ))
+        SetFailed( "LL_EQ", "minus one EQ one");
+        
+    if ( LL_EQ( bigNumber, bigOne ))
+        SetFailed( "LL_EQ", "bigNumber EQ one");
+    
+    /* test not equal */
+    if ( LL_NE( bigZero, bigZero ))
+        SetFailed( "LL_NE", "0 NE 0");
+    
+    if ( LL_NE( bigOne, bigOne ))
+        SetFailed( "LL_NE", "1 NE 1");
+    
+    if ( LL_NE( bigMinusOne, bigMinusOne ))
+        SetFailed( "LL_NE", "-1 NE -1");
+    
+    if ( LL_NE( bigNumber, bigNumber ))
+        SetFailed( "LL_NE", "n NE n");
+    
+    if ( LL_NE( bigMinusNumber, bigMinusNumber ))
+        SetFailed( "LL_NE", "-n NE -n");
+        
+    if ( !LL_NE( bigZero, bigOne))
+        SetFailed( "LL_NE", "0 NE 1");
+    
+    if ( !LL_NE( bigOne, bigMinusNumber))
+        SetFailed( "LL_NE", "1 NE -n");
+        
+    /* Greater than or equal to zero */
+    if ( !LL_GE_ZERO( bigZero ))
+        SetFailed( "LL_GE_ZERO", "0");
+    
+    if ( !LL_GE_ZERO( bigOne ))
+        SetFailed( "LL_GE_ZERO", "1");
+    
+    if ( !LL_GE_ZERO( bigNumber ))
+        SetFailed( "LL_GE_ZERO", "n");
+    
+    if ( LL_GE_ZERO( bigMinusOne ))
+        SetFailed( "LL_GE_ZERO", "-1");
+        
+    if ( LL_GE_ZERO( bigMinusNumber ))
+        SetFailed( "LL_GE_ZERO", "-n");
+        
+    /* Algebraic Compare two values */
+    if ( !LL_CMP( bigZero, ==, bigZero ))
+        SetFailed( "LL_CMP", "0 == 0");
+    
+    if ( LL_CMP( bigZero, >, bigZero ))
+        SetFailed( "LL_CMP", "0 > 0");
+        
+    if ( LL_CMP( bigZero, <, bigZero ))
+        SetFailed( "LL_CMP", "0 < 0");
+        
+    if ( LL_CMP( bigNumber, <, bigOne ))
+        SetFailed( "LL_CMP", "n < 1");
+        
+    if ( !LL_CMP( bigNumber, >, bigOne ))
+        SetFailed( "LL_CMP", "n <= 1");
+        
+    if ( LL_CMP( bigOne, >, bigNumber ))
+        SetFailed( "LL_CMP", "1 > n");
+        
+    if ( LL_CMP( bigMinusNumber, >, bigNumber ))
+        SetFailed( "LL_CMP", "-n > n");
+        
+    if ( LL_CMP( bigNumber, !=, bigNumber))
+        SetFailed( "LL_CMP", "n != n");
+
+    if ( !LL_CMP( bigMinusOne, >, bigMinusTwo ))
+        SetFailed( "LL_CMP", "-1 <= -2");
+
+    if ( !LL_CMP( bigMaxInt32, <, big2To31 ))
+        SetFailed( "LL_CMP", "Max 32-bit signed int >= 2^31");
+
+    /* Two positive numbers */
+    if ( !LL_CMP( bigInt0, <=, bigInt0 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt0, <=, bigInt1 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( LL_CMP( bigInt0, <=, bigInt2 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt0, <=, bigInt3 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt0, <=, bigInt4 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt0, <=, bigInt5 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    /* Two negative numbers */
+    if ( !LL_CMP( bigInt6, <=, bigInt6 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt6, <=, bigInt7 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( LL_CMP( bigInt6, <=, bigInt8 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt6, <=, bigInt9 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt6, <=, bigInt10 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt6, <=, bigInt11 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    /* One positive, one negative */
+    if ( LL_CMP( bigInt0, <=, bigInt6 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( LL_CMP( bigInt0, <=, bigInt7 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( LL_CMP( bigInt0, <=, bigInt8 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    /* Bitwise Compare two numbers */
+    if ( !LL_UCMP( bigZero, ==, bigZero ))
+        SetFailed( "LL_UCMP", "0 == 0");
+    
+    if ( LL_UCMP( bigZero, >, bigZero ))
+        SetFailed( "LL_UCMP", "0 > 0");
+        
+    if ( LL_UCMP( bigZero, <, bigZero ))
+        SetFailed( "LL_UCMP", "0 < 0");
+        
+    if ( LL_UCMP( bigNumber, <, bigOne ))
+        SetFailed( "LL_UCMP", "n < 1");
+        
+    if ( !LL_UCMP( bigNumber, >, bigOne ))
+        SetFailed( "LL_UCMP", "n < 1");
+        
+    if ( LL_UCMP( bigOne, >, bigNumber ))
+        SetFailed( "LL_UCMP", "1 > n");
+        
+    if ( LL_UCMP( bigMinusNumber, <, bigNumber ))
+        SetFailed( "LL_UCMP", "-n < n");
+
+    /* Two positive numbers */
+    if ( !LL_UCMP( bigInt0, <=, bigInt0 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt1 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( LL_UCMP( bigInt0, <=, bigInt2 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt3 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt4 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt5 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    /* Two negative numbers */
+    if ( !LL_UCMP( bigInt6, <=, bigInt6 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt6, <=, bigInt7 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( LL_UCMP( bigInt6, <=, bigInt8 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt6, <=, bigInt9 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt6, <=, bigInt10 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt6, <=, bigInt11 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    /* One positive, one negative */
+    if ( !LL_UCMP( bigInt0, <=, bigInt6 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt7 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt8 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    return;
+}
+
+/*
+**  TestLogicalOperations() -- Tests for AND, OR, ...
+**
+*/
+static void
+TestLogicalOperations( void )
+{
+    PRUint64    result, result2;
+    
+    ReportProgress("Testing Logical Operations\n");
+    
+    /* Test AND */
+    LL_AND( result, bigZero, bigZero );
+    if ( !LL_IS_ZERO( result ))
+        ResultFailed( "LL_AND", "0 & 0", bigZero, result );
+    
+    LL_AND( result, bigOne, bigOne );
+    if ( LL_IS_ZERO( result ))
+        ResultFailed( "LL_AND", "1 & 1", bigOne, result );
+
+    LL_AND( result, bigZero, bigOne );
+    if ( !LL_IS_ZERO( result ))
+        ResultFailed( "LL_AND", "1 & 1", bigZero, result );
+
+    LL_AND( result, bigMinusOne, bigMinusOne );
+    if ( !LL_UCMP( result, ==, bigMinusOne ))
+        ResultFailed( "LL_AND", "-1 & -1", bigMinusOne, result );
+        
+    /* test OR */
+    LL_OR( result, bigZero, bigZero );
+    if ( !LL_IS_ZERO( result ))
+        ResultFailed( "LL_OR", "0 | 1", bigZero, result);
+    
+    LL_OR( result, bigZero, bigOne );
+    if ( LL_IS_ZERO( result ))
+        ResultFailed( "LL_OR", "0 | 1", bigOne, result );
+    
+    LL_OR( result, bigZero, bigMinusNumber );
+    if ( !LL_UCMP( result, ==, bigMinusNumber ))
+        ResultFailed( "LL_OR", "0 | -n", bigMinusNumber, result);
+    
+    LL_OR( result, bigMinusNumber, bigZero );
+    if ( !LL_UCMP( result, ==, bigMinusNumber ))
+        ResultFailed( "LL_OR", "-n | 0", bigMinusNumber, result );
+    
+    /* test XOR */
+    LL_XOR( result, bigZero, bigZero );
+    if ( LL_UCMP( result, !=, bigZero ))
+        ResultFailed( "LL_XOR", "0 ^ 0", bigZero, result);
+    
+    LL_XOR( result, bigOne, bigZero );
+    if ( LL_UCMP( result, !=, bigOne ))
+        ResultFailed( "LL_XOR", "1 ^ 0", bigZero, result );
+        
+    LL_XOR( result, bigMinusNumber, bigZero );
+    if ( LL_UCMP( result, !=, bigMinusNumber ))
+        ResultFailed( "LL_XOR", "-n ^ 0", bigMinusNumber, result );
+    
+    LL_XOR( result, bigMinusNumber, bigMinusNumber );
+    if ( LL_UCMP( result, !=, bigZero ))
+        ResultFailed( "LL_XOR", "-n ^ -n", bigMinusNumber, result);
+        
+    /* test OR2.  */
+    result = bigZero;
+    LL_OR2( result, bigOne );
+    if ( LL_UCMP( result, !=, bigOne ))
+        ResultFailed( "LL_OR2", "(r=0) |= 1", bigOne, result);
+        
+    result = bigOne;
+    LL_OR2( result, bigNumber );
+    if ( LL_UCMP( result, !=, bigNumber ))
+        ResultFailed( "LL_OR2", "(r=1) |= n", bigNumber, result);
+
+    result = bigMinusNumber;
+    LL_OR2( result, bigMinusNumber );
+    if ( LL_UCMP( result, !=, bigMinusNumber ))
+        ResultFailed( "LL_OR2", "(r=-n) |= -n", bigMinusNumber, result);
+
+    /* test NOT */
+    LL_NOT( result, bigMinusNumber);
+    LL_NOT( result2, result);
+    if ( LL_UCMP( result2, !=, bigMinusNumber ))
+        ResultFailed( "LL_NOT", "r != ~(~-n)", bigMinusNumber, result);
+            
+    /* test Negation */
+    LL_NEG( result, bigMinusNumber );
+    LL_NEG( result2, result );
+    if ( LL_CMP( result2, !=, bigMinusNumber ))
+        ResultFailed( "LL_NEG", "r != -(-(-n))", bigMinusNumber, result);
+
+    return;
+}
+
+
+
+/*
+**  TestConversion() -- Test Conversion Operations
+**
+*/
+static void
+TestConversion( void )
+{
+    PRInt64     result;
+    PRInt64     resultU;
+    PRInt32     result32;
+    PRUint32    resultU32;
+    float       resultF;
+    PRFloat64   resultD;
+    
+    ReportProgress("Testing Conversion Operations\n");
+    
+    /* LL_L2I  -- Convert to signed 32bit */
+    LL_L2I(result32, bigOne );
+    if ( result32 != one )  
+        SetFailed( "LL_L2I", "r != 1");
+    
+    LL_L2I(result32, bigMinusOne );
+    if ( result32 != minusOne )  
+        SetFailed( "LL_L2I", "r != -1");
+    
+    /* LL_L2UI -- Convert 64bit to unsigned 32bit */
+    LL_L2UI( resultU32, bigMinusOne );
+    if ( resultU32 != (PRUint32) minusOne )
+        SetFailed( "LL_L2UI", "r != -1");
+    
+    LL_L2UI( resultU32, bigOne );
+    if ( resultU32 != (PRUint32) one )
+        SetFailed( "LL_L2UI", "r != 1");
+        
+    /* LL_L2F  -- Convert to 32bit floating point */
+    LL_L2F( resultF, bigOne );
+    if ( resultF != 1.0 )
+        SetFailed( "LL_L2F", "r != 1.0");
+        
+    LL_L2F( resultF, bigMinusOne );
+    if ( resultF != -1.0 )
+        SetFailed( "LL_L2F", "r != 1.0");
+    
+    /* LL_L2D  -- Convert to 64bit floating point */
+    LL_L2D( resultD, bigOne );
+    if ( resultD != 1.0L )
+        SetFailed( "LL_L2D", "r != 1.0");
+        
+    LL_L2D( resultD, bigMinusOne );
+    if ( resultD != -1.0L )
+        SetFailed( "LL_L2D", "r != -1.0");
+        
+    /* LL_I2L  -- Convert 32bit signed to 64bit signed */
+    LL_I2L( result, one );
+    if ( LL_CMP(result, !=, bigOne ))
+        SetFailed( "LL_I2L", "r != 1");
+        
+    LL_I2L( result, minusOne );
+    if ( LL_CMP(result, !=, bigMinusOne ))
+        SetFailed( "LL_I2L", "r != -1");
+        
+    /* LL_UI2L -- Convert 32bit unsigned to 64bit unsigned */
+    LL_UI2L( resultU, (PRUint32) one );
+    if ( LL_CMP(resultU, !=, bigOne ))
+        SetFailed( "LL_UI2L", "r != 1");
+        
+    /* [lth.] This did not behave as expected, but it is correct 
+    */
+    LL_UI2L( resultU, (PRUint32) minusOne );
+    if ( LL_CMP(resultU, !=, bigZeroFox ))
+        ResultFailed( "LL_UI2L", "r != -1", bigZeroFox, resultU);
+        
+    /* LL_F2L  -- Convert 32bit float to 64bit signed */
+    LL_F2L( result, 1.0 );
+    if ( LL_CMP(result, !=, bigOne ))
+        SetFailed( "LL_F2L", "r != 1");
+        
+    LL_F2L( result, -1.0 );
+    if ( LL_CMP(result, !=, bigMinusOne ))
+        SetFailed( "LL_F2L", "r != -1");
+    
+    /* LL_D2L  -- Convert 64bit Float to 64bit signed */
+    LL_D2L( result, 1.0L );
+    if ( LL_CMP(result, !=, bigOne ))
+        SetFailed( "LL_D2L", "r != 1");
+        
+    LL_D2L( result, -1.0L );
+    if ( LL_CMP(result, !=, bigMinusOne ))
+        SetFailed( "LL_D2L", "r != -1");
+
+    return;
+}
+
+static void ShiftCompileOnly()
+{
+    /*
+    ** This function is only compiled, never called.
+    ** The real test is to see if it compiles w/o
+    ** warnings. This is no small feat, by the way.
+    */
+    PRInt64 ia, ib;
+    PRUint64 ua, ub;
+    LL_SHR(ia, ib, 32);
+    LL_SHL(ia, ib, 32);
+
+    LL_USHR(ua, ub, 32);
+    LL_ISHL(ia, 49, 32);
+
+}  /* ShiftCompileOnly */
+   
+
+/*
+**  TestShift() -- Test Shifting Operations
+**
+*/
+static void
+TestShift( void )
+{
+    static const PRInt64 largeTwoZero = LL_INIT( 0x00000002, 0x00000000 );
+    PRInt64     result;
+    PRUint64    resultU;
+
+    ReportProgress("Testing Shifting Operations\n");
+    
+    /* LL_SHL  -- Shift left algebraic */
+    LL_SHL( result, bigOne, one );
+    if ( LL_CMP( result, !=, bigTwo ))
+        ResultFailed( "LL_SHL", "r != 2", bigOne, result );
+    
+    LL_SHL( result, bigTwo, thirtyTwo );
+    if ( LL_CMP( result, !=, largeTwoZero ))
+        ResultFailed( "LL_SHL", "r != twoZero", largeTwoZero, result);
+    
+    /* LL_SHR  -- Shift right algebraic */
+    LL_SHR( result, bigFoxZero, thirtyTwo );
+    if ( LL_CMP( result, !=, bigMinusOne ))
+        ResultFailed( "LL_SHR", "r != -1", bigMinusOne, result);
+    
+    LL_SHR( result, bigTwo, one );
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_SHR", "r != 1", bigOne, result);
+
+    LL_SHR( result, bigFoxFox, thirtyTwo );
+    if ( LL_CMP( result, !=, bigMinusOne ))
+        ResultFailed( "LL_SHR", "r != -1 (was ff,ff)", bigMinusOne, result);
+    
+    /* LL_USHR -- Logical shift right */
+    LL_USHR( resultU, bigZeroFox, thirtyTwo );
+    if ( LL_UCMP( resultU, !=, bigZero ))
+        ResultFailed( "LL_USHR", "r != 0 ", bigZero, result);
+    
+    LL_USHR( resultU, bigFoxFox, thirtyTwo );
+    if ( LL_UCMP( resultU, !=, bigZeroFox ))
+        ResultFailed( "LL_USHR", "r != 0 ", bigZeroFox, result);
+    
+    /* LL_ISHL -- Shift a 32bit integer into a 64bit result */
+    LL_ISHL( resultU, minusOne, thirtyTwo );
+    if ( LL_UCMP( resultU, !=, bigFoxZero ))
+        ResultFailed( "LL_ISHL", "r != ff,00 ", bigFoxZero, result);
+    
+    LL_ISHL( resultU, one, sixtyThree );
+    if ( LL_UCMP( resultU, !=, bigEightZero ))
+        ResultFailed( "LL_ISHL", "r != 80,00 ", bigEightZero, result);
+    
+    LL_ISHL( resultU, one, sixteen );
+    if ( LL_UCMP( resultU, !=, big64K ))
+        ResultFailed( "LL_ISHL", "r != 64K ", big64K, resultU);
+    
+    return;
+}    
+
+
+/*
+**  TestArithmetic() -- Test arithmetic operations.
+**
+*/
+static void
+TestArithmetic( void )
+{
+    PRInt64 largeVal          = LL_INIT( 0x00000001, 0xffffffff );
+    PRInt64 largeValPlusOne   = LL_INIT( 0x00000002, 0x00000000 );
+    PRInt64 largeValTimesTwo  = LL_INIT( 0x00000003, 0xfffffffe );
+    PRInt64 largeMultCand     = LL_INIT( 0x00000000, 0x7fffffff );
+    PRInt64 largeMinusMultCand = LL_INIT( 0xffffffff, 0x10000001 );
+    PRInt64 largeMultCandx64K = LL_INIT( 0x00007fff, 0xffff0000 );
+    PRInt64 largeNumSHL5      = LL_INIT( 0x0000001f, 0xffffffe0 );        
+    PRInt64 result, result2;
+
+    /* Addition */    
+    LL_ADD( result, bigOne, bigOne );
+    if ( LL_CMP( result, !=, bigTwo ))
+        ResultFailed( "LL_ADD", "r != 1 + 1", bigTwo, result);
+
+    LL_ADD( result, bigMinusOne, bigOne );
+    if ( LL_CMP( result, !=, bigZero ))
+        ResultFailed( "LL_ADD", "r != -1 + 1", bigOne, result);
+
+    LL_ADD( result, largeVal, bigOne );
+    if ( LL_CMP( result, !=, largeValPlusOne ))
+        ResultFailed( "LL_ADD", "lVP1 != lV + 1", largeValPlusOne, result);
+            
+    /* Subtraction */
+    LL_SUB( result, bigOne, bigOne );
+    if ( LL_CMP( result, !=, bigZero ))
+        ResultFailed( "LL_SUB", "r != 1 - 1", bigZero, result);
+            
+    LL_SUB( result, bigTwo, bigOne );
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_SUB", "r != 2 - 1", bigOne, result);
+            
+    LL_SUB( result, largeValPlusOne, bigOne );
+    if ( LL_CMP( result, !=, largeVal ))
+        ResultFailed( "LL_SUB", "r != lVP1 - 1", largeVal, result);
+            
+    
+    /* Multiply */
+    LL_MUL( result, largeVal, bigTwo );
+    if ( LL_CMP( result, !=, largeValTimesTwo ))
+        ResultFailed( "LL_MUL", "r != lV*2", largeValTimesTwo, result);
+    
+    LL_MUL( result, largeMultCand, big64K );
+    if ( LL_CMP( result, !=, largeMultCandx64K ))
+        ResultFailed( "LL_MUL", "r != lV*64K", largeMultCandx64K, result);
+        
+    LL_NEG( result2, largeMultCand );
+    LL_MUL( result, largeMultCand, bigMinusOne );
+    if ( LL_CMP( result, !=, result2  ))
+        ResultFailed( "LL_MUL", "r != -lMC", result2, result);
+
+    LL_SHL( result2, bigZeroFox, 5);
+    LL_MUL( result, bigZeroFox, bigThirtyTwo );
+    if ( LL_CMP( result, !=, largeNumSHL5  ))
+        ResultFailed( "LL_MUL", "r != 0f<<5", largeNumSHL5, result );
+
+    
+
+    /* LL_DIV() Division */
+    LL_DIV( result, bigOne, bigOne);
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_DIV", "1 != 1", bigOne, result);
+    
+    LL_DIV( result, bigNumber, bigOne );
+    if ( LL_CMP( result, !=, bigNumber  ))
+        ResultFailed( "LL_DIV", "r != n / 1", bigNumber, result);
+
+    LL_DIV( result, bigNumber, bigMinusOne );
+    if ( LL_CMP( result, !=, bigMinusNumber  ))
+        ResultFailed( "LL_DIV", "r != n / -1", bigMinusNumber, result);
+
+    LL_DIV( result, bigMinusNumber, bigMinusOne );
+    if ( LL_CMP( result, !=, bigNumber  ))
+        ResultFailed( "LL_DIV", "r != -n / -1", bigNumber, result);
+        
+    LL_SHL( result2, bigZeroFox, 5 );
+    LL_DIV( result, result2, bigOne );
+    if ( LL_CMP( result, !=, result2  ))
+        ResultFailed( "LL_DIV", "0f<<5 != 0f<<5", result2, result);
+    
+    LL_SHL( result2, bigZeroFox, 5 );
+    LL_NEG( result2, result2 );
+    LL_DIV( result, result2, bigOne );
+    if ( LL_CMP( result, !=, result2  ))
+        ResultFailed( "LL_DIV", "-0f<<5 != -0f<<5", result2, result);
+    
+    LL_SHL( result2, bigZeroFox, 17 );
+    LL_DIV( result, result2, bigMinusOne );
+    LL_NEG( result2, result2 );
+    if ( LL_CMP( result, !=, result2  ))
+        ResultFailed( "LL_DIV", "-0f<<17 != -0f<<17", result2, result);
+    
+    
+    /* LL_MOD() Modulo Division */
+    LL_ADD( result2, bigThirtyTwo, bigOne );
+    LL_MOD( result, result2, bigSixTeen );
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_MOD", "r != 1", bigSixTeen, result);
+    
+    
+    LL_MUL( result2, bigZeroFox, bigThirtyTwo );
+    LL_ADD( result2, result2, bigSixTeen);
+    LL_MOD( result, result2, bigThirtyTwo );
+    if ( LL_CMP( result, !=, bigSixTeen ))
+        ResultFailed( "LL_MOD", "r != 16", bigSixTeen, result);
+
+    /* LL_UDIVMOD */
+    LL_DIV( result, bigOne, bigOne);
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_DIV", "r != 16", bigSixTeen, result);
+    
+
+    return;
+} 
+
+static void TestWellknowns(void)
+{
+    PRInt64 max = LL_MAXINT, min = LL_MININT, zero = LL_ZERO;
+    PRInt64 mmax = LL_MaxInt(), mmin = LL_MinInt(), mzero = LL_Zero();
+    if (LL_NE(max, mmax))
+        ResultFailed( "max, mmax", "max != mmax", max, mmax);
+    if (LL_NE(min, mmin))
+        ResultFailed( "min, mmin", "min != mmin", max, mmin);
+    if (LL_NE(zero, mzero))
+        ResultFailed( "zero, mzero", "zero != mzero", zero, mzero);
+}  /* TestWellknowns */ 
+
+/*
+** Initialize() -- Initialize the test case
+**
+** Parse command line options
+**
+*/
+static PRIntn
+Initialize( PRIntn argc, char **argv )
+{
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dvh");
+    PLOptStatus os;
+
+    /*
+    ** Parse command line options
+    */    
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* set debug mode */
+            debugMode = PR_TRUE;
+            break;
+            
+        case 'v':  /* set verbose mode */
+            verboseMode = PR_TRUE;
+            debugMode = PR_TRUE;
+            break;
+            
+        case 'h':  /* user wants some guidance */
+        default:
+            PR_fprintf(output, "You get help.\n");
+            return(1);
+        }
+    }
+    PL_DestroyOptState(opt);
+    return(0);
+}    
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+    output = PR_GetSpecialFD(PR_StandardError);
+
+    if ( Initialize( argc, argv ))
+        return(1);
+
+    TestAssignment();
+    TestComparisons();
+    TestLogicalOperations();
+    TestConversion();
+    TestShift();
+    TestArithmetic();
+    TestWellknowns();
+    
+    /*
+    ** That's all folks!
+    */
+    if ( failedAlready )
+    {
+        PR_fprintf(output, "FAIL\n");\
+    } 
+    else
+    {
+        PR_fprintf(output, "PASS\n");\
+    }
+    return failedAlready;
+} /* end main() */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/lock.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/lock.c
new file mode 100644
index 0000000..4b0db4a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/lock.c
@@ -0,0 +1,551 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        lock.c
+** Purpose:     test basic locking functions
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+**
+** 11-Aug-97 LarryH. Win16 port of NSPR.
+**           - Added "PASS", "FAIL" messages on completion.
+**           - Change stack variables to static scope variables
+**             because of shadow-stack use by Win16
+**           - Added PR_CALLBACK attribute to functions called by NSPR
+**           - Added command line arguments:
+**             - l <num> to control the number of loops
+**             - c <num> to control the number of CPUs.
+**             (was positional argv).
+** 
+**
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prio.h"
+#include "prcmon.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prprf.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmon.h"
+#include "prmem.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#include "plstr.h"
+
+#include <stdlib.h>
+
+#if defined(XP_UNIX)
+#include <string.h>
+#endif
+
+static PRIntn failed_already=0;
+static PRFileDesc *std_err = NULL;
+static PRBool verbosity = PR_FALSE;
+static PRBool debug_mode = PR_FALSE;
+
+const static PRIntervalTime contention_interval = 50;
+
+typedef struct LockContentious_s {
+    PRLock *ml;
+    PRInt32 loops;
+    PRUint32 contender;
+    PRUint32 contentious;
+    PRIntervalTime overhead;
+    PRIntervalTime interval;
+} LockContentious_t;
+
+typedef struct MonitorContentious_s {
+    PRMonitor *ml;
+    PRInt32 loops;
+    PRUint32 contender;
+    PRUint32 contentious;
+    PRIntervalTime overhead;
+    PRIntervalTime interval;
+} MonitorContentious_t;
+
+
+static PRIntervalTime Sleeper(PRUint32 loops)
+{
+    PRIntervalTime predicted = 0;
+    while (loops-- > 0)
+    {
+        predicted += contention_interval;
+        (void)PR_Sleep(contention_interval);
+    }
+    return predicted;
+}  /* Sleeper */
+
+/*
+** BASIC LOCKS
+*/
+static PRIntervalTime MakeLock(PRUint32 loops)
+{
+    PRLock *ml = NULL;
+    while (loops-- > 0)
+    {
+        ml = PR_NewLock();
+        PR_DestroyLock(ml);
+        ml = NULL;
+    }
+    return 0;
+}  /* MakeLock */
+
+static PRIntervalTime NonContentiousLock(PRUint32 loops)
+{
+    PRLock *ml = NULL;
+    ml = PR_NewLock();
+    while (loops-- > 0)
+    {
+        PR_Lock(ml);
+        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(ml);
+        PR_Unlock(ml);
+    }
+    PR_DestroyLock(ml);
+    return 0;
+}  /* NonContentiousLock */
+
+static void PR_CALLBACK LockContender(void *arg)
+{
+    LockContentious_t *contention = (LockContentious_t*)arg;
+    while (contention->loops-- > 0)
+    {
+        PR_Lock(contention->ml);
+        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
+        contention->contender+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
+        PR_Unlock(contention->ml);
+    }
+}  /* LockContender */
+
+static PRIntervalTime ContentiousLock(PRUint32 loops)
+{
+    PRStatus status;
+    PRThread *thread = NULL;
+    LockContentious_t * contention;
+    PRIntervalTime rv, overhead, timein = PR_IntervalNow();
+
+    contention = PR_NEWZAP(LockContentious_t);
+    contention->loops = loops;
+    contention->overhead = 0;
+    contention->ml = PR_NewLock();
+    contention->interval = contention_interval;
+    thread = PR_CreateThread(
+        PR_USER_THREAD, LockContender, contention,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+
+    overhead = PR_IntervalNow() - timein;
+
+    while (contention->loops-- > 0)
+    {
+        PR_Lock(contention->ml);
+        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
+        contention->contentious+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
+        PR_Unlock(contention->ml);
+    }
+
+    timein = PR_IntervalNow();
+    status = PR_JoinThread(thread);
+    PR_DestroyLock(contention->ml);
+    overhead += (PR_IntervalNow() - timein);
+    rv = overhead + contention->overhead;
+    if (verbosity)
+        PR_fprintf(
+            std_err, "Access ratio: %u to %u\n",
+            contention->contentious, contention->contender);
+    PR_Free(contention);
+    return rv;
+}  /* ContentiousLock */
+
+/*
+** MONITORS
+*/
+static PRIntervalTime MakeMonitor(PRUint32 loops)
+{
+    PRMonitor *ml = NULL;
+    while (loops-- > 0)
+    {
+        ml = PR_NewMonitor();
+        PR_DestroyMonitor(ml);
+        ml = NULL;
+    }
+    return 0;
+}  /* MakeMonitor */
+
+static PRIntervalTime NonContentiousMonitor(PRUint32 loops)
+{
+    PRMonitor *ml = NULL;
+    ml = PR_NewMonitor();
+    while (loops-- > 0)
+    {
+        PR_EnterMonitor(ml);
+        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
+        PR_ExitMonitor(ml);
+    }
+    PR_DestroyMonitor(ml);
+    return 0;
+}  /* NonContentiousMonitor */
+
+static void PR_CALLBACK TryEntry(void *arg)
+{
+    PRMonitor *ml = (PRMonitor*)arg;
+    if (debug_mode) PR_fprintf(std_err, "Reentrant thread created\n");
+    PR_EnterMonitor(ml);
+    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
+    if (debug_mode) PR_fprintf(std_err, "Reentrant thread acquired monitor\n");
+    PR_ExitMonitor(ml);
+    if (debug_mode) PR_fprintf(std_err, "Reentrant thread released monitor\n");
+}  /* TryEntry */
+
+static PRIntervalTime ReentrantMonitor(PRUint32 loops)
+{
+    PRStatus status;
+    PRThread *thread;
+    PRMonitor *ml = PR_NewMonitor();
+    if (debug_mode) PR_fprintf(std_err, "\nMonitor created for reentrant test\n");
+
+    PR_EnterMonitor(ml);
+    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
+    PR_EnterMonitor(ml);
+    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
+    if (debug_mode) PR_fprintf(std_err, "Monitor acquired twice\n");
+
+    thread = PR_CreateThread(
+        PR_USER_THREAD, TryEntry, ml,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+    PR_Sleep(PR_SecondsToInterval(1));
+    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
+
+    PR_ExitMonitor(ml);
+    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
+    if (debug_mode) PR_fprintf(std_err, "Monitor released first time\n");
+
+    PR_ExitMonitor(ml);
+    if (debug_mode) PR_fprintf(std_err, "Monitor released second time\n");
+
+    status = PR_JoinThread(thread);
+    if (debug_mode) PR_fprintf(std_err, 
+        "Reentrant thread joined %s\n",
+        (status == PR_SUCCESS) ? "successfully" : "in error");
+
+    PR_DestroyMonitor(ml);
+    return 0;
+}  /* ReentrantMonitor */
+
+static void PR_CALLBACK MonitorContender(void *arg)
+{
+    MonitorContentious_t *contention = (MonitorContentious_t*)arg;
+    while (contention->loops-- > 0)
+    {
+        PR_EnterMonitor(contention->ml);
+        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
+        contention->contender+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
+        PR_ExitMonitor(contention->ml);
+    }
+}  /* MonitorContender */
+
+static PRUint32 ContentiousMonitor(PRUint32 loops)
+{
+    PRStatus status;
+    PRThread *thread = NULL;
+    MonitorContentious_t * contention;
+    PRIntervalTime rv, overhead, timein = PR_IntervalNow();
+
+    contention = PR_NEWZAP(MonitorContentious_t);
+    contention->loops = loops;
+    contention->overhead = 0;
+    contention->ml = PR_NewMonitor();
+    contention->interval = contention_interval;
+    thread = PR_CreateThread(
+        PR_USER_THREAD, MonitorContender, contention,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+
+    overhead = PR_IntervalNow() - timein;
+
+    while (contention->loops-- > 0)
+    {
+        PR_EnterMonitor(contention->ml);
+        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
+        contention->contentious+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
+        PR_ExitMonitor(contention->ml);
+    }
+
+    timein = PR_IntervalNow();
+    status = PR_JoinThread(thread);
+    PR_DestroyMonitor(contention->ml);
+    overhead += (PR_IntervalNow() - timein);
+    rv = overhead + contention->overhead;
+    if (verbosity)
+        PR_fprintf(
+            std_err, "Access ratio: %u to %u\n",
+            contention->contentious, contention->contender);
+    PR_Free(contention);
+    return rv;
+}  /* ContentiousMonitor */
+
+/*
+** CACHED MONITORS
+*/
+static PRIntervalTime NonContentiousCMonitor(PRUint32 loops)
+{
+    MonitorContentious_t contention;
+    while (loops-- > 0)
+    {
+        PR_CEnterMonitor(&contention);
+        PR_CExitMonitor(&contention);
+    }
+    return 0;
+}  /* NonContentiousCMonitor */
+
+static void PR_CALLBACK Contender(void *arg)
+{
+    MonitorContentious_t *contention = (MonitorContentious_t*)arg;
+    while (contention->loops-- > 0)
+    {
+        PR_CEnterMonitor(contention);
+        contention->contender+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_CExitMonitor(contention);
+    }
+}  /* Contender */
+
+static PRIntervalTime ContentiousCMonitor(PRUint32 loops)
+{
+    PRStatus status;
+    PRThread *thread = NULL;
+    MonitorContentious_t * contention;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+
+    contention = PR_NEWZAP(MonitorContentious_t);
+    contention->ml = NULL;
+    contention->loops = loops;
+    contention->interval = contention_interval;
+    thread = PR_CreateThread(
+        PR_USER_THREAD, Contender, contention,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+
+    overhead = PR_IntervalNow() - timein;
+
+    while (contention->loops-- > 0)
+    {
+        PR_CEnterMonitor(contention);
+        contention->contentious+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_CExitMonitor(contention);
+    }
+
+    timein = PR_IntervalNow();
+    status = PR_JoinThread(thread);
+    overhead += (PR_IntervalNow() - timein);
+    overhead += overhead + contention->overhead;
+    if (verbosity)
+        PR_fprintf(
+            std_err, "Access ratio: %u to %u\n",
+            contention->contentious, contention->contender);
+    PR_Free(contention);
+    return overhead;
+}  /* ContentiousCMonitor */
+
+static PRIntervalTime Test(
+    const char* msg, PRUint32 (*test)(PRUint32 loops),
+    PRUint32 loops, PRIntervalTime overhead)
+{ 
+    /*
+     * overhead - overhead not measured by the test.
+     * duration - wall clock time it took to perform test.
+     * predicted - extra time test says should not be counted 
+     *
+     * Time accountable to the test is duration - overhead - predicted
+     * All times are Intervals and accumulated for all iterations.
+     */
+    PRFloat64 elapsed;
+    PRIntervalTime accountable, duration;    
+    PRUintn spaces = PL_strlen(msg);
+    PRIntervalTime timeout, timein = PR_IntervalNow();
+    PRIntervalTime predicted = test(loops);
+    timeout = PR_IntervalNow();
+    duration = timeout - timein;
+
+    if (debug_mode)
+    {
+        accountable = duration - predicted;
+        accountable -= overhead;
+        elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable);
+        PR_fprintf(PR_STDOUT, "%s:", msg);
+        while (spaces++ < 50) PR_fprintf(PR_STDOUT, " ");
+        if ((PRInt32)accountable < 0)
+            PR_fprintf(PR_STDOUT, "*****.** usecs/iteration\n");
+        else
+            PR_fprintf(PR_STDOUT, "%8.2f usecs/iteration\n", elapsed/loops);
+    }
+    return duration;
+}  /* Test */
+
+int main(int argc,  char **argv)
+{
+    PRBool rv = PR_TRUE;
+    PRIntervalTime duration;
+    PRUint32 cpu, cpus = 2, loops = 100;
+
+	
+    PR_STDIO_INIT();
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    {
+    	/* The command line argument: -d is used to determine if the test is being run
+    	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+    	All of the printfs associated with this test has been handled with a if (debug_mode)
+    	test.
+        Command line argument -l <num> sets the number of loops.
+        Command line argument -c <num> sets the number of cpus.
+        Usage: lock [-d] [-l <num>] [-c <num>]
+    	*/
+    	PLOptStatus os;
+    	PLOptState *opt = PL_CreateOptState(argc, argv, "dvl:c:");
+    	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+    		if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug mode */
+    			debug_mode = PR_TRUE;
+                break;
+            case 'v':  /* debug mode */
+    			verbosity = PR_TRUE;
+                break;
+            case 'l':  /* number of loops */
+                loops = atoi(opt->value);
+                break;
+            case 'c':  /* number of cpus */
+                cpus = atoi(opt->value);
+                break;
+             default:
+                break;
+            }
+        }
+    	PL_DestroyOptState(opt);
+    }
+
+ /* main test */
+    PR_SetConcurrency(8);
+
+    if (loops == 0) loops = 100;
+    if (debug_mode)
+    {
+        std_err = PR_STDERR;
+        PR_fprintf(std_err, "Lock: Using %d loops\n", loops);
+    }
+
+    if (cpus == 0) cpus = 2;
+    if (debug_mode) PR_fprintf(std_err, "Lock: Using %d cpu(s)\n", cpus);
+
+    (void)Sleeper(10);  /* try filling in the caches */
+
+    for (cpu = 1; cpu <= cpus; ++cpu)
+    {
+        if (debug_mode) PR_fprintf(std_err, "\nLock: Using %d CPU(s)\n", cpu);
+        PR_SetConcurrency(cpu);
+
+        duration = Test("Overhead of PR_Sleep", Sleeper, loops, 0);
+        duration = 0;
+
+        (void)Test("Lock creation/deletion", MakeLock, loops, 0);
+        (void)Test("Lock non-contentious locking/unlocking", NonContentiousLock, loops, 0);
+        (void)Test("Lock contentious locking/unlocking", ContentiousLock, loops, duration);
+        (void)Test("Monitor creation/deletion", MakeMonitor, loops, 0);
+        (void)Test("Monitor non-contentious locking/unlocking", NonContentiousMonitor, loops, 0);
+        (void)Test("Monitor contentious locking/unlocking", ContentiousMonitor, loops, duration);
+
+        (void)Test("Cached monitor non-contentious locking/unlocking", NonContentiousCMonitor, loops, 0);
+        (void)Test("Cached monitor contentious locking/unlocking", ContentiousCMonitor, loops, duration);
+
+        (void)ReentrantMonitor(loops);
+    }
+
+    if (debug_mode)
+        PR_fprintf(
+            std_err, "%s: test %s\n", "Lock(mutex) test",
+            ((rv) ? "passed" : "failed"));
+	else {
+		 if (!rv)
+			 failed_already=1;
+	}
+
+	if(failed_already)	
+	{
+	    PR_fprintf(PR_STDOUT, "FAIL\n"); 
+		return 1;
+    } 
+	else
+    {
+	    PR_fprintf(PR_STDOUT, "PASS\n"); 
+		return 0;
+    }
+
+}  /* main */
+
+/* testlock.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/lockfile.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/lockfile.c
new file mode 100644
index 0000000..c737f00
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/lockfile.c
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        lockfile.c
+** Purpose:     test basic locking functions
+**              Just because this times stuff, don't think its a perforamnce
+**              test!!!
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prcmon.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmon.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#include "private/pprio.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+const static PRIntervalTime contention_interval = 50;
+
+typedef struct LockContentious_s {
+    PRLock *ml;
+    PRInt32 loops;
+    PRIntervalTime overhead;
+    PRIntervalTime interval;
+} LockContentious_t;
+
+#define LOCKFILE "prlock.fil"
+
+
+
+static PRIntervalTime NonContentiousLock(PRInt32 loops)
+{
+    PRFileDesc *_lockfile;
+    while (loops-- > 0)
+    {
+        _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666);
+        if (!_lockfile) {
+            if (debug_mode) printf(
+                "could not create lockfile: %d [%d]\n",
+                PR_GetError(), PR_GetOSError());
+            return PR_INTERVAL_NO_TIMEOUT;
+        }
+        PR_LockFile(_lockfile);
+        PR_UnlockFile(_lockfile);
+        PR_Close(_lockfile);
+    }
+    return 0;
+}  /* NonContentiousLock */
+
+static void PR_CALLBACK LockContender(void *arg)
+{
+    LockContentious_t *contention = (LockContentious_t*)arg;
+    PRFileDesc *_lockfile;
+    while (contention->loops-- > 0)
+    {
+        _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666);
+        if (!_lockfile) {
+            if (debug_mode) printf(
+                "could not create lockfile: %d [%d]\n",
+                PR_GetError(), PR_GetOSError());
+            break;
+        }
+        PR_LockFile(_lockfile);
+        PR_Sleep(contention->interval);
+        PR_UnlockFile(_lockfile);
+        PR_Close(_lockfile);
+    }
+
+}  /* LockContender */
+
+/*
+** Win16 requires things passed to Threads not be on the stack
+*/
+static LockContentious_t contention;
+
+static PRIntervalTime ContentiousLock(PRInt32 loops)
+{
+    PRStatus status;
+    PRThread *thread = NULL;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+
+    contention.loops = loops;
+    contention.overhead = 0;
+    contention.ml = PR_NewLock();
+    contention.interval = contention_interval;
+    thread = PR_CreateThread(
+        PR_USER_THREAD, LockContender, &contention,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+
+    overhead = PR_IntervalNow() - timein;
+
+    while (contention.loops > 0)
+    {
+        PR_Lock(contention.ml);
+        contention.overhead += contention.interval;
+        PR_Sleep(contention.interval);
+        PR_Unlock(contention.ml);
+    }
+
+    timein = PR_IntervalNow();
+    status = PR_JoinThread(thread);
+    PR_DestroyLock(contention.ml);
+    overhead += (PR_IntervalNow() - timein);
+    return overhead + contention.overhead;
+}  /* ContentiousLock */
+
+static PRIntervalTime Test(
+    const char* msg, PRIntervalTime (*test)(PRInt32 loops),
+    PRInt32 loops, PRIntervalTime overhead)
+{ 
+    /*
+     * overhead - overhead not measured by the test.
+     * duration - wall clock time it took to perform test.
+     * predicted - extra time test says should not be counted 
+     *
+     * Time accountable to the test is duration - overhead - predicted
+     * All times are Intervals and accumulated for all iterations.
+     */
+    PRFloat64 elapsed;
+    PRIntervalTime accountable, duration;    
+    PRUintn spaces = strlen(msg);
+    PRIntervalTime timeout, timein = PR_IntervalNow();
+    PRIntervalTime predicted = test(loops);
+    timeout = PR_IntervalNow();
+    duration = timeout - timein;
+    accountable = duration - predicted;
+    accountable -= overhead;
+    elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable);
+    if (debug_mode) printf("%s:", msg);
+    while (spaces++ < 50) if (debug_mode) printf(" ");
+    if ((PRInt32)accountable < 0) {
+        if (debug_mode) printf("*****.** usecs/iteration\n");
+    } else {
+        if (debug_mode) printf("%8.2f usecs/iteration\n", elapsed/loops);
+    }
+    return duration;
+}  /* Test */
+
+int main(int argc,  char **argv)
+{
+    PRIntervalTime duration;
+    PRUint32 cpu, cpus = 2;
+    PRInt32 loops = 100;
+
+	
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 1) loops = atoi(argv[1]);
+    if (loops == 0) loops = 100;
+    if (debug_mode) printf("Lock: Using %d loops\n", loops);
+
+    cpus = (argc < 3) ? 2 : atoi(argv[2]);
+    if (cpus == 0) cpus = 2;
+    if (debug_mode) printf("Lock: Using %d cpu(s)\n", cpus);
+
+
+    for (cpu = 1; cpu <= cpus; ++cpu)
+    {
+        if (debug_mode) printf("\nLockFile: Using %d CPU(s)\n", cpu);
+        PR_SetConcurrency(cpu);
+        
+        duration = Test("LockFile non-contentious locking/unlocking", NonContentiousLock, loops, 0);
+        (void)Test("LockFile contentious locking/unlocking", ContentiousLock, loops, duration);
+    }
+
+    PR_Delete(LOCKFILE);  /* try to get rid of evidence */
+
+    if (debug_mode) printf("%s: test %s\n", "Lock(mutex) test", ((failed_already) ? "failed" : "passed"));
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}  /* main */
+
+/* testlock.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/logfile.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/logfile.c
new file mode 100644
index 0000000..3589efb
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/logfile.c
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Google Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * A regression test for bug 491441.  NSPR should not crash on startup in
+ * PR_SetLogFile when the NSPR_LOG_MODULES and NSPR_LOG_FILE environment
+ * variables are set.
+ *
+ * This test could be extended to be a full-blown test for NSPR_LOG_FILE.
+ */
+
+#include "prinit.h"
+#include "prlog.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main()
+{
+    PRLogModuleInfo *test_lm;
+
+    if (putenv("NSPR_LOG_MODULES=all:5") != 0) {
+        fprintf(stderr, "putenv failed\n");
+        exit(1);
+    }
+    if (putenv("NSPR_LOG_FILE=logfile.log") != 0) {
+        fprintf(stderr, "putenv failed\n");
+        exit(1);
+    }
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    test_lm = PR_NewLogModule("test");
+    PR_LOG(test_lm, PR_LOG_MIN, ("logfile: test log message"));
+    PR_Cleanup();
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/logger.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/logger.c
new file mode 100644
index 0000000..1280c26
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/logger.c
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:        logger.c
+ * Description: test program for logging's basic functions
+ */
+
+#include "prinit.h"
+#include "prlog.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "prthread.h"
+#include "prinrval.h"
+
+#include <stdio.h>
+
+/* lth. re-define PR_LOG() */
+#if 0
+#undef PR_LOG_TEST
+#undef PR_LOG
+#define PR_LOG_TEST(_module,_level) ((_module)->level <= (_level))
+#define PR_LOG(_module,_level,_args)    \
+  {                                     \
+    if (PR_LOG_TEST(_module,_level))    \
+       PR_LogPrint _args   ;             \
+  }
+#endif
+
+
+static void Error(const char* msg)
+{
+    printf("\t%s\n", msg);
+}  /* Error */
+
+static void PR_CALLBACK forked(void *arg)
+{
+    PRIntn i;
+	PRLock *ml;
+	PRCondVar *cv;
+	
+    PR_LogPrint("%s logging creating mutex\n", (const char*)arg);
+    ml = PR_NewLock();
+    PR_LogPrint("%s logging creating condition variable\n", (const char*)arg);
+    cv = PR_NewCondVar(ml);
+
+    PR_LogPrint("%s waiting on condition timeout 10 times\n", (const char*)arg);
+    for (i = 0; i < 10; ++i)
+    {
+        PR_Lock(ml);
+        PR_WaitCondVar(cv, PR_SecondsToInterval(1));
+        PR_Unlock(ml);
+    }
+    
+    PR_LogPrint("%s logging destroying condition variable\n", (const char*)arg);
+    PR_DestroyCondVar(cv);
+    PR_LogPrint("%s logging destroying mutex\n", (const char*)arg);
+    PR_DestroyLock(ml);
+    PR_LogPrint("%s forked thread exiting\n", (const char*)arg);
+}
+
+static void UserLogStuff( void )
+{
+    PRLogModuleInfo *myLM;
+    PRIntn i;
+
+    myLM = PR_NewLogModule( "userStuff" );
+    if (! myLM )
+      {
+        printf("UserLogStuff(): can't create new log module\n" );
+        return;
+      }
+
+    PR_LOG( myLM, PR_LOG_NOTICE, ("Log a Notice %d\n", 1 ));
+
+    for (i = 0; i < 10 ; i++ )
+      {
+        PR_LOG( myLM, PR_LOG_DEBUG, ("Log Debug number: %d\n", i));
+        PR_Sleep( 300 );
+      }
+
+} /* end UserLogStuff() */
+
+int main(int argc, char **argv)
+{
+    PRThread *thread;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 1)
+    {
+        if (!PR_SetLogFile(argv[1]))
+        {
+            Error("Access: Cannot create log file");
+            goto exit;
+        }
+    }
+
+    /* Start logging something here */
+    PR_LogPrint("%s logging into %s\n", argv[0], argv[1]);
+
+    PR_LogPrint("%s creating new thread\n", argv[0]);
+
+    /*
+    ** Now change buffering.
+    */
+    PR_SetLogBuffering( 65500 );    
+	thread = PR_CreateThread(
+	    PR_USER_THREAD, forked, (void*)argv[0], PR_PRIORITY_NORMAL,
+	    PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_LogPrint("%s joining thread\n", argv[0]);
+
+    UserLogStuff();
+
+    PR_JoinThread(thread);
+
+    PR_LogFlush();
+    return 0;
+
+exit:
+    return -1;
+}
+
+/* logger.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/makedir.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/makedir.c
new file mode 100644
index 0000000..5bb3dfd
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/makedir.c
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This test calls PR_MakeDir to create a bunch of directories
+ * with various mode bits.
+ */
+
+#include "prio.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+    if (PR_MakeDir("tdir0400", 0400) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0200", 0200) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0100", 0100) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0500", 0500) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0600", 0600) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0300", 0300) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0700", 0700) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0640", 0640) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0660", 0660) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0644", 0644) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0664", 0664) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0666", 0666) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/many_cv.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/many_cv.c
new file mode 100644
index 0000000..d3002ec
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/many_cv.c
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prprf.h"
+#include "prthread.h"
+#include "prcvar.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmem.h"
+
+#include "primpl.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+static PRInt32 RandomNum(void)
+{
+    PRInt32 ran = rand() >> 16;
+    return ran;
+}  /* RandomNum */
+
+static void Help(void)
+{
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PR_fprintf(err, "many_cv usage: [-c n] [-l n] [-h]\n");
+    PR_fprintf(err, "\t-c n Number of conditions per lock       (default: 10)\n");
+    PR_fprintf(err, "\t-l n Number of times to loop the test    (default:  1)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+    PLOptStatus os;
+    PRIntn index, nl;
+    PRLock *ml = NULL;
+    PRCondVar **cv = NULL;
+    PRBool stats = PR_FALSE;
+    PRIntn nc, loops = 1, cvs = 10;
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hsc:l:");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 's':  /* number of CVs to association with lock */
+            stats = PR_TRUE;
+            break;
+        case 'c':  /* number of CVs to association with lock */
+            cvs = atoi(opt->value);
+            break;
+        case 'l':  /* number of times to run the tests */
+            loops = atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+         default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_fprintf(err, "Settings\n");
+    PR_fprintf(err, "\tConditions / lock: %d\n", cvs);
+    PR_fprintf(err, "\tLoops to run test: %d\n", loops);
+
+    ml = PR_NewLock();
+    PR_ASSERT(NULL != ml);
+
+    cv = (PRCondVar**)PR_CALLOC(sizeof(PRCondVar*) * cvs);
+    PR_ASSERT(NULL != cv);
+
+    for (index = 0; index < cvs; ++index)
+    {
+        cv[index] = PR_NewCondVar(ml);
+        PR_ASSERT(NULL != cv[index]);
+    }
+
+    for (index = 0; index < loops; ++index)
+    {
+        PR_Lock(ml);
+        for (nl = 0; nl < cvs; ++nl)
+        {
+            PRInt32 ran = RandomNum() % 8;
+            if (0 == ran) PR_NotifyAllCondVar(cv[nl]);
+            else for (nc = 0; nc < ran; ++nc)
+                PR_NotifyCondVar(cv[nl]);
+        }
+        PR_Unlock(ml);
+    }
+
+    for (index = 0; index < cvs; ++index)
+        PR_DestroyCondVar(cv[index]);
+
+    PR_DELETE(cv);
+
+    PR_DestroyLock(ml);
+    
+    printf("PASS\n");
+
+    PT_FPrintStats(err, "\nPThread Statistics\n");
+    return 0;
+}
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/mbcs.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/mbcs.c
new file mode 100644
index 0000000..bb2cf78
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/mbcs.c
@@ -0,0 +1,187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: mbcs.c
+**
+** Synopsis: mbcs {dirName}
+**
+** where dirName is the directory to be traversed. dirName is required.
+**
+** Description: 
+** mbcs.c tests use of multi-byte characters, as would be passed to
+** NSPR funtions by internationalized applications. 
+**
+** mbcs.c, when run on any single-byte platform, should run correctly.
+** In truth, running the mbcs test on a single-byte platform is
+** really meaningless. mbcs.c, nor any NSPR library or test is not
+** intended for use with any wide character set, including Unicode.
+** mbcs.c should not be included in runtests.ksh because it requires
+** extensive user intervention to set-up and run.
+**
+** mbcs.c should be run on a platform using some form of multi-byte
+** characters. The initial platform for this test is a Japanese
+** language Windows NT 4.0 machine. ... Thank you Noriko Hoshi.
+**
+** To run mbcs.c, the tester should create a directory tree containing
+** some files in the same directory from which the test is run; i.e.
+** the current working directory. The directory and files should be
+** named such that when represented in the local multi-byte character
+** set, one or more characters of the name is longer than a single
+** byte.
+** 
+*/
+
+#include <plgetopt.h> 
+#include <nspr.h> 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn  debug = 0;
+PRUint32  failed_already = 0;
+/* end Test harness infrastructure */
+
+char *dirName =  NULL;  /* directory name to traverse */
+
+/*
+** Traverse directory
+*/
+static void TraverseDirectory( unsigned char *dir )
+{
+    PRDir *cwd;
+    PRDirEntry *dirEntry;
+    PRFileInfo info;
+    PRStatus rc;
+    PRInt32 err;
+    PRFileDesc *fd;
+    char    nextDir[256];
+    char    file[256];
+
+    printf("Directory: %s\n", dir );
+    cwd = PR_OpenDir( dir );
+    if ( NULL == cwd )  {
+        printf("PR_OpenDir() failed on directory: %s, with error: %d, %d\n", 
+            dir, PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    while( NULL != (dirEntry = PR_ReadDir( cwd, PR_SKIP_BOTH | PR_SKIP_HIDDEN )))  {
+        sprintf( file, "%s/%s", dir, dirEntry->name );
+        rc = PR_GetFileInfo( file, &info );
+        if ( PR_FAILURE == rc ) {
+            printf("PR_GetFileInfo() failed on file: %s, with error: %d, %d\n", 
+                dirEntry->name, PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        if ( PR_FILE_FILE == info.type )  {
+            printf("File: %s \tsize: %ld\n", dirEntry->name, info.size );
+            fd = PR_Open( file, PR_RDONLY, 0 );
+            if ( NULL == fd )  {
+                printf("PR_Open() failed. Error: %ld, OSError: %ld\n", 
+                    PR_GetError(), PR_GetOSError());
+            }
+            rc = PR_Close( fd );
+            if ( PR_FAILURE == rc )  {
+                printf("PR_Close() failed. Error: %ld, OSError: %ld\n", 
+                    PR_GetError(), PR_GetOSError());
+            }
+        } else if ( PR_FILE_DIRECTORY == info.type ) {
+            sprintf( nextDir, "%s/%s", dir, dirEntry->name );
+            TraverseDirectory(nextDir);
+        } else {
+            printf("type is not interesting for file: %s\n", dirEntry->name );
+            /* keep going */
+        }
+    }
+    /* assume end-of-file, actually could be error */
+
+    rc = PR_CloseDir( cwd );
+    if ( PR_FAILURE == rc ) {
+        printf("PR_CloseDir() failed on directory: %s, with error: %d, %d\n", 
+            dir, PR_GetError(), PR_GetOSError());
+    }
+
+} /* end TraverseDirectory() */
+
+int main(int argc, char **argv)
+{
+    { /* get command line options */
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "dv");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_ERROR;
+                break;
+            case 'v':  /* verbose mode */
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+             default:
+                dirName = strdup(opt->value); 
+                break; 
+            }
+        }
+	    PL_DestroyOptState(opt);
+    } /* end get command line options */
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+
+    
+    if ( dirName == NULL )  {
+        printf("you gotta specify a directory as an operand!\n");
+        exit(1);
+    }
+
+    TraverseDirectory( dirName );
+
+    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end template.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/multiacc.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/multiacc.c
new file mode 100644
index 0000000..ccae270
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/multiacc.c
@@ -0,0 +1,252 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: multiacc.c
+ *
+ * Description:
+ * This test creates multiple threads that accept on the
+ * same listening socket.
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NUM_SERVER_THREADS 10
+
+static int num_server_threads = NUM_SERVER_THREADS;
+static PRThreadScope thread_scope = PR_GLOBAL_THREAD;
+static PRBool exit_flag = PR_FALSE;
+
+static void ServerThreadFunc(void *arg)
+{
+    PRFileDesc *listenSock = (PRFileDesc *) arg;
+    PRFileDesc *acceptSock;
+    PRErrorCode err;
+    PRStatus status;
+
+    while (!exit_flag) {
+        acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+        if (NULL == acceptSock) {
+            err = PR_GetError();
+            if (PR_PENDING_INTERRUPT_ERROR == err) {
+                printf("server thread is interrupted\n");
+                fflush(stdout);
+                continue;
+            }
+            fprintf(stderr, "PR_Accept failed: %d\n", err);
+            exit(1);
+        }
+        status = PR_Close(acceptSock);
+        if (PR_FAILURE == status) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        }
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *dummySock;
+    PRFileDesc *listenSock;
+    PRFileDesc *clientSock;
+    PRThread *dummyThread;
+    PRThread **serverThreads;
+    PRStatus status;
+    PRUint16 port;
+    int idx;
+    PRInt32 nbytes;
+    char buf[1024];
+
+    serverThreads = (PRThread **)
+            PR_Malloc(num_server_threads * sizeof(PRThread *));
+    if (NULL == serverThreads) {
+        fprintf(stderr, "PR_Malloc failed\n");
+        exit(1);
+    }
+
+    /*
+     * Create a dummy listening socket and have the first
+     * (dummy) thread listen on it.  This is to ensure that
+     * the first thread becomes the I/O continuation thread
+     * in the pthreads implementation (see ptio.c) and remains
+     * so throughout the test, so that we never have to
+     * recycle the I/O continuation thread.
+     */
+    dummySock = PR_NewTCPSocket();
+    if (NULL == dummySock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&serverAddr, 0, sizeof(serverAddr));
+    status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    status = PR_Bind(dummySock, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    status = PR_Listen(dummySock, 5);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    listenSock = PR_NewTCPSocket();
+    if (NULL == listenSock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&serverAddr, 0, sizeof(serverAddr));
+    status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    status = PR_Bind(listenSock, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    status = PR_GetSockName(listenSock, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_GetSockName failed\n");
+        exit(1);
+    }
+    port = PR_ntohs(serverAddr.inet.port);
+    status = PR_Listen(listenSock, 5);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    printf("creating dummy thread\n");
+    fflush(stdout);
+    dummyThread = PR_CreateThread(PR_USER_THREAD,
+            ServerThreadFunc, dummySock, PR_PRIORITY_NORMAL,
+            thread_scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == dummyThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    printf("sleeping one second before creating server threads\n");
+    fflush(stdout);
+    PR_Sleep(PR_SecondsToInterval(1));
+    for (idx = 0; idx < num_server_threads; idx++) {
+        serverThreads[idx] = PR_CreateThread(PR_USER_THREAD,
+                ServerThreadFunc, listenSock, PR_PRIORITY_NORMAL,
+                thread_scope, PR_JOINABLE_THREAD, 0);
+        if (NULL == serverThreads[idx]) {
+            fprintf(stderr, "PR_CreateThread failed\n");
+            exit(1);
+        }
+    }
+
+    memset(&serverAddr, 0, sizeof(serverAddr));
+    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &serverAddr);
+    clientSock = PR_NewTCPSocket();
+    if (NULL == clientSock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    printf("sleeping one second before connecting\n");
+    fflush(stdout);
+    PR_Sleep(PR_SecondsToInterval(1));
+    status = PR_Connect(clientSock, &serverAddr, PR_INTERVAL_NO_TIMEOUT);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Connect failed\n");
+        exit(1);
+    }
+    nbytes = PR_Read(clientSock, buf, sizeof(buf));
+    if (nbytes != 0) {
+        fprintf(stderr, "expected 0 bytes but got %d bytes\n", nbytes);
+        exit(1);
+    }
+    status = PR_Close(clientSock);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    printf("sleeping one second before shutting down server threads\n");
+    fflush(stdout);
+    PR_Sleep(PR_SecondsToInterval(1));
+
+    exit_flag = PR_TRUE;
+    status = PR_Interrupt(dummyThread);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Interrupt failed\n");
+        exit(1);
+    }
+    status = PR_JoinThread(dummyThread);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    for (idx = 0; idx < num_server_threads; idx++) {
+        status = PR_Interrupt(serverThreads[idx]);
+        if (PR_FAILURE == status) {
+            fprintf(stderr, "PR_Interrupt failed\n");
+            exit(1);
+        }
+        status = PR_JoinThread(serverThreads[idx]);
+        if (PR_FAILURE == status) {
+            fprintf(stderr, "PR_JoinThread failed\n");
+            exit(1);
+        }
+    }
+    PR_Free(serverThreads);
+    status = PR_Close(dummySock);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(listenSock);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/multiwait.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/multiwait.c
new file mode 100644
index 0000000..8454eb4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/multiwait.c
@@ -0,0 +1,725 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prmem.h"
+#include "pratom.h"
+#include "prlock.h"
+#include "prmwait.h"
+#include "prclist.h"
+#include "prerror.h"
+#include "prinrval.h"
+#include "prnetdb.h"
+#include "prthread.h"
+
+#include "plstr.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <string.h>
+
+typedef struct Shared
+{
+    const char *title;
+    PRLock *list_lock;
+    PRWaitGroup *group;
+    PRIntervalTime timeout;
+} Shared;
+
+typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
+
+static PRFileDesc *debug = NULL;
+static PRInt32 desc_allocated = 0;
+static PRUint16 default_port = 12273;
+static enum Verbosity verbosity = quiet;
+static PRInt32 ops_required = 1000, ops_done = 0;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+static PRIntn client_threads = 20, worker_threads = 2, wait_objects = 50;
+
+#if defined(DEBUG)
+#define MW_ASSERT(_expr) \
+    ((_expr)?((void)0):_MW_Assert(# _expr,__FILE__,__LINE__))
+static void _MW_Assert(const char *s, const char *file, PRIntn ln)
+{
+    if (NULL != debug) PL_FPrintError(debug, NULL);
+    PR_Assert(s, file, ln);
+}  /* _MW_Assert */
+#else
+#define MW_ASSERT(_expr)
+#endif
+
+static void PrintRecvDesc(PRRecvWait *desc, const char *msg)
+{
+    const char *tag[] = {
+        "PR_MW_INTERRUPT", "PR_MW_TIMEOUT",
+        "PR_MW_FAILURE", "PR_MW_SUCCESS", "PR_MW_PENDING"};
+    PR_fprintf(
+        debug, "%s: PRRecvWait(@0x%x): {fd: 0x%x, outcome: %s, tmo: %u}\n",
+        msg, desc, desc->fd, tag[desc->outcome + 3], desc->timeout);
+}  /* PrintRecvDesc */
+
+static Shared *MakeShared(const char *title)
+{
+    Shared *shared = PR_NEWZAP(Shared);
+    shared->group = PR_CreateWaitGroup(1);
+    shared->timeout = PR_SecondsToInterval(1);
+    shared->list_lock = PR_NewLock();
+    shared->title = title;
+    return shared;
+}  /* MakeShared */
+
+static void DestroyShared(Shared *shared)
+{
+    PRStatus rv;
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: destroying group\n", shared->title);
+    rv = PR_DestroyWaitGroup(shared->group);
+    MW_ASSERT(PR_SUCCESS == rv);
+    PR_DestroyLock(shared->list_lock);
+    PR_DELETE(shared);
+}  /* DestroyShared */
+
+static PRRecvWait *CreateRecvWait(PRFileDesc *fd, PRIntervalTime timeout)
+{
+    PRRecvWait *desc_out = PR_NEWZAP(PRRecvWait);
+    MW_ASSERT(NULL != desc_out);
+
+    MW_ASSERT(NULL != fd);
+    desc_out->fd = fd;
+    desc_out->timeout = timeout;
+    desc_out->buffer.length = 120;
+    desc_out->buffer.start = PR_CALLOC(120);
+
+    PR_AtomicIncrement(&desc_allocated);
+
+    if (verbosity > chatty)
+        PrintRecvDesc(desc_out, "Allocated");
+    return desc_out;
+}  /* CreateRecvWait */
+
+static void DestroyRecvWait(PRRecvWait *desc_out)
+{
+    if (verbosity > chatty)
+        PrintRecvDesc(desc_out, "Destroying");
+    PR_Close(desc_out->fd);
+    if (NULL != desc_out->buffer.start)
+        PR_DELETE(desc_out->buffer.start);
+    PR_Free(desc_out);
+    (void)PR_AtomicDecrement(&desc_allocated);
+}  /* DestroyRecvWait */
+
+static void CancelGroup(Shared *shared)
+{
+    PRRecvWait *desc_out;
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s Reclaiming wait descriptors\n", shared->title);
+
+    do
+    {
+        desc_out = PR_CancelWaitGroup(shared->group);
+        if (NULL != desc_out) DestroyRecvWait(desc_out);
+    } while (NULL != desc_out);
+
+    MW_ASSERT(0 == desc_allocated);
+    MW_ASSERT(PR_GROUP_EMPTY_ERROR == PR_GetError());
+}  /* CancelGroup */
+
+static void PR_CALLBACK ClientThread(void* arg)
+{
+    PRStatus rv;
+    PRInt32 bytes;
+    PRIntn empty_flags = 0;
+    PRNetAddr server_address;
+    unsigned char buffer[100];
+    Shared *shared = (Shared*)arg;
+    PRFileDesc *server = PR_NewTCPSocket();
+    if ((NULL == server)
+    && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) return;
+    MW_ASSERT(NULL != server);
+
+    if (verbosity > chatty)
+        PR_fprintf(debug, "%s: Server socket @0x%x\n", shared->title, server);
+
+    /* Initialize the buffer so that Purify won't complain */
+    memset(buffer, 0, sizeof(buffer));
+
+    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, default_port, &server_address);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: Client opening connection\n", shared->title);
+    rv = PR_Connect(server, &server_address, PR_INTERVAL_NO_TIMEOUT);
+
+    if (PR_FAILURE == rv)
+    {
+        if (verbosity > silent) PL_FPrintError(debug, "Client connect failed");
+        return;
+    }
+
+    while (ops_done < ops_required)
+    {
+        bytes = PR_Send(
+            server, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
+        MW_ASSERT(sizeof(buffer) == bytes);
+        if (verbosity > chatty)
+            PR_fprintf(
+                debug, "%s: Client sent %d bytes\n",
+                shared->title, sizeof(buffer));
+        bytes = PR_Recv(
+            server, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        if (verbosity > chatty)
+            PR_fprintf(
+                debug, "%s: Client received %d bytes\n",
+                shared->title, sizeof(buffer));
+        if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
+        MW_ASSERT(sizeof(buffer) == bytes);
+        PR_Sleep(shared->timeout);
+    }
+    rv = PR_Close(server);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+}  /* ClientThread */
+
+static void OneInThenCancelled(Shared *shared)
+{
+    PRStatus rv;
+    PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait);
+
+    shared->timeout = PR_INTERVAL_NO_TIMEOUT;
+
+    desc_in->fd = PR_NewTCPSocket();
+    desc_in->timeout = shared->timeout;
+
+    if (verbosity > chatty) PrintRecvDesc(desc_in, "Adding desc");
+
+    rv = PR_AddWaitFileDesc(shared->group, desc_in);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    if (verbosity > chatty) PrintRecvDesc(desc_in, "Cancelling");
+    rv = PR_CancelWaitFileDesc(shared->group, desc_in);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    desc_out = PR_WaitRecvReady(shared->group);
+    MW_ASSERT(desc_out == desc_in);
+    MW_ASSERT(PR_MW_INTERRUPT == desc_out->outcome);
+    MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+    if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready");
+
+    rv = PR_Close(desc_in->fd);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: destroying group\n", shared->title);
+
+    PR_DELETE(desc_in);
+}  /* OneInThenCancelled */
+
+static void OneOpOneThread(Shared *shared)
+{
+    PRStatus rv;
+    PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait);
+
+    desc_in->fd = PR_NewTCPSocket();
+    desc_in->timeout = shared->timeout;
+
+    if (verbosity > chatty) PrintRecvDesc(desc_in, "Adding desc");
+
+    rv = PR_AddWaitFileDesc(shared->group, desc_in);
+    MW_ASSERT(PR_SUCCESS == rv);
+    desc_out = PR_WaitRecvReady(shared->group);
+    MW_ASSERT(desc_out == desc_in);
+    MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
+    MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
+    if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready");
+
+    rv = PR_Close(desc_in->fd);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    PR_DELETE(desc_in);
+}  /* OneOpOneThread */
+
+static void ManyOpOneThread(Shared *shared)
+{
+    PRStatus rv;
+    PRIntn index;
+    PRRecvWait *desc_in;
+    PRRecvWait *desc_out;
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: adding %d descs\n", shared->title, wait_objects);
+
+    for (index = 0; index < wait_objects; ++index)
+    {
+        desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout);
+
+        rv = PR_AddWaitFileDesc(shared->group, desc_in);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+
+    while (ops_done < ops_required)
+    {
+        desc_out = PR_WaitRecvReady(shared->group);
+        MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
+        MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
+        if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready/readding");
+        rv = PR_AddWaitFileDesc(shared->group, desc_out);
+        MW_ASSERT(PR_SUCCESS == rv);
+        (void)PR_AtomicIncrement(&ops_done);
+    }
+
+    CancelGroup(shared);
+}  /* ManyOpOneThread */
+
+static void PR_CALLBACK SomeOpsThread(void *arg)
+{
+    PRRecvWait *desc_out;
+    PRStatus rv = PR_SUCCESS;
+    Shared *shared = (Shared*)arg;
+    do  /* until interrupted */
+    {
+        desc_out = PR_WaitRecvReady(shared->group);
+        if (NULL == desc_out)
+        {
+            MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+            if (verbosity > quiet) PR_fprintf(debug, "Aborted\n");
+            break;
+        }
+        MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
+        MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
+        if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready");
+
+        if (verbosity > chatty) PrintRecvDesc(desc_out, "Re-Adding");
+        desc_out->timeout = shared->timeout;
+        rv = PR_AddWaitFileDesc(shared->group, desc_out);
+        PR_AtomicIncrement(&ops_done);
+        if (ops_done > ops_required) break;
+    } while (PR_SUCCESS == rv);
+    MW_ASSERT(PR_SUCCESS == rv);
+}  /* SomeOpsThread */
+
+static void SomeOpsSomeThreads(Shared *shared)
+{
+    PRStatus rv;
+    PRThread **thread;
+    PRIntn index;
+    PRRecvWait *desc_in;
+
+    thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads);
+
+    /* Create some threads */
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating threads\n", shared->title);
+    for (index = 0; index < worker_threads; ++index)
+    {
+        thread[index] = PR_CreateThread(
+            PR_USER_THREAD, SomeOpsThread, shared,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+    }
+
+    /* then create some operations */
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating desc\n", shared->title);
+    for (index = 0; index < wait_objects; ++index)
+    {
+        desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout);
+        rv = PR_AddWaitFileDesc(shared->group, desc_in);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: sleeping\n", shared->title);
+    while (ops_done < ops_required) PR_Sleep(shared->timeout);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: interrupting/joining threads\n", shared->title);
+    for (index = 0; index < worker_threads; ++index)
+    {
+        rv = PR_Interrupt(thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+    PR_DELETE(thread);
+
+    CancelGroup(shared);
+}  /* SomeOpsSomeThreads */
+
+static PRStatus ServiceRequest(Shared *shared, PRRecvWait *desc)
+{
+    PRInt32 bytes_out;
+
+    if (verbosity > chatty)
+        PR_fprintf(
+            debug, "%s: Service received %d bytes\n",
+            shared->title, desc->bytesRecv);
+
+    if (0 == desc->bytesRecv) goto quitting;
+    if ((-1 == desc->bytesRecv)
+    && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) goto aborted;
+
+    bytes_out = PR_Send(
+        desc->fd, desc->buffer.start, desc->bytesRecv, 0, shared->timeout);
+    if (verbosity > chatty)
+        PR_fprintf(
+            debug, "%s: Service sent %d bytes\n",
+            shared->title, bytes_out);
+
+    if ((-1 == bytes_out)
+    && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) goto aborted;
+    MW_ASSERT(bytes_out == desc->bytesRecv);
+
+    return PR_SUCCESS;
+
+aborted:
+quitting:
+    return PR_FAILURE;
+}  /* ServiceRequest */
+
+static void PR_CALLBACK ServiceThread(void *arg)
+{
+    PRStatus rv = PR_SUCCESS;
+    PRRecvWait *desc_out = NULL;
+    Shared *shared = (Shared*)arg;
+    do  /* until interrupted */
+    {
+        if (NULL != desc_out)
+        {
+            desc_out->timeout = PR_INTERVAL_NO_TIMEOUT;
+            if (verbosity > chatty)
+                PrintRecvDesc(desc_out, "Service re-adding");
+            rv = PR_AddWaitFileDesc(shared->group, desc_out);
+            MW_ASSERT(PR_SUCCESS == rv);
+        }
+
+        desc_out = PR_WaitRecvReady(shared->group);
+        if (NULL == desc_out)
+        {
+            MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+            break;
+        }
+
+        switch (desc_out->outcome)
+        {
+            case PR_MW_SUCCESS:
+            {
+                PR_AtomicIncrement(&ops_done);
+                if (verbosity > chatty)
+                    PrintRecvDesc(desc_out, "Service ready");
+                rv = ServiceRequest(shared, desc_out);
+                break;
+            }
+            case PR_MW_INTERRUPT:
+                MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+                rv = PR_FAILURE;  /* if interrupted, then exit */
+                break;
+            case PR_MW_TIMEOUT:
+                MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
+            case PR_MW_FAILURE:
+                if (verbosity > silent)
+                    PL_FPrintError(debug, "RecvReady failure");
+                break;
+            default:
+                break;
+        }
+    } while (PR_SUCCESS == rv);
+
+    if (NULL != desc_out) DestroyRecvWait(desc_out);
+
+}  /* ServiceThread */
+
+static void PR_CALLBACK EnumerationThread(void *arg)
+{
+    PRStatus rv;
+    PRIntn count;
+    PRRecvWait *desc;
+    Shared *shared = (Shared*)arg;
+    PRIntervalTime five_seconds = PR_SecondsToInterval(5);
+    PRMWaitEnumerator *enumerator = PR_CreateMWaitEnumerator(shared->group);
+    MW_ASSERT(NULL != enumerator);
+
+    while (PR_SUCCESS == PR_Sleep(five_seconds))
+    {
+        count = 0;
+        desc = NULL;
+        while (NULL != (desc = PR_EnumerateWaitGroup(enumerator, desc)))
+        {
+            if (verbosity > chatty) PrintRecvDesc(desc, shared->title);
+            count += 1;
+        }
+        if (verbosity > silent)
+            PR_fprintf(debug,
+                "%s Enumerated %d objects\n", shared->title, count);
+    }
+
+    MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+
+
+    rv = PR_DestroyMWaitEnumerator(enumerator);
+    MW_ASSERT(PR_SUCCESS == rv);
+}  /* EnumerationThread */
+
+static void PR_CALLBACK ServerThread(void *arg)
+{
+    PRStatus rv;
+    PRIntn index;
+    PRRecvWait *desc_in;
+    PRThread **worker_thread;
+    Shared *shared = (Shared*)arg;
+    PRFileDesc *listener, *service;
+    PRNetAddr server_address, client_address;
+
+    worker_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads);
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: Server creating worker_threads\n", shared->title);
+    for (index = 0; index < worker_threads; ++index)
+    {
+        worker_thread[index] = PR_CreateThread(
+            PR_USER_THREAD, ServiceThread, shared,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+    }
+
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &server_address);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    listener = PR_NewTCPSocket(); MW_ASSERT(NULL != listener);
+    if (verbosity > chatty)
+        PR_fprintf(
+            debug, "%s: Server listener socket @0x%x\n",
+            shared->title, listener);
+    rv = PR_Bind(listener, &server_address); MW_ASSERT(PR_SUCCESS == rv);
+    rv = PR_Listen(listener, 10); MW_ASSERT(PR_SUCCESS == rv);
+    while (ops_done < ops_required)
+    {
+        if (verbosity > quiet)
+            PR_fprintf(debug, "%s: Server accepting connection\n", shared->title);
+        service = PR_Accept(listener, &client_address, PR_INTERVAL_NO_TIMEOUT);
+        if (NULL == service)
+        {
+            if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) break;
+            PL_PrintError("Accept failed");
+            MW_ASSERT(!"Accept failed");
+        }
+        else
+        {
+            desc_in = CreateRecvWait(service, shared->timeout);
+            desc_in->timeout = PR_INTERVAL_NO_TIMEOUT;
+            if (verbosity > chatty)
+                PrintRecvDesc(desc_in, "Service adding");
+            rv = PR_AddWaitFileDesc(shared->group, desc_in);
+            MW_ASSERT(PR_SUCCESS == rv);
+        }
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: Server interrupting worker_threads\n", shared->title);
+    for (index = 0; index < worker_threads; ++index)
+    {
+        rv = PR_Interrupt(worker_thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(worker_thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+    PR_DELETE(worker_thread);
+
+    PR_Close(listener);
+
+    CancelGroup(shared);
+
+}  /* ServerThread */
+
+static void RealOneGroupIO(Shared *shared)
+{
+    /*
+    ** Create a server that listens for connections and then services
+    ** requests that come in over those connections. The server never
+    ** deletes a connection and assumes a basic RPC model of operation.
+    **
+    ** Use worker_threads threads to service how every many open ports
+    ** there might be.
+    **
+    ** Oh, ya. Almost forget. Create (some) clients as well.
+    */
+    PRStatus rv;
+    PRIntn index;
+    PRThread *server_thread, *enumeration_thread, **client_thread;
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating server_thread\n", shared->title);
+
+    server_thread = PR_CreateThread(
+        PR_USER_THREAD, ServerThread, shared,
+        PR_PRIORITY_HIGH, thread_scope,
+        PR_JOINABLE_THREAD, 16 * 1024);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating enumeration_thread\n", shared->title);
+
+    enumeration_thread = PR_CreateThread(
+        PR_USER_THREAD, EnumerationThread, shared,
+        PR_PRIORITY_HIGH, thread_scope,
+        PR_JOINABLE_THREAD, 16 * 1024);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: snoozing before creating clients\n", shared->title);
+    PR_Sleep(5 * shared->timeout);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating client_threads\n", shared->title);
+    client_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * client_threads);
+    for (index = 0; index < client_threads; ++index)
+    {
+        client_thread[index] = PR_CreateThread(
+            PR_USER_THREAD, ClientThread, shared,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+    }
+
+    while (ops_done < ops_required) PR_Sleep(shared->timeout);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: interrupting/joining client_threads\n", shared->title);
+    for (index = 0; index < client_threads; ++index)
+    {
+        rv = PR_Interrupt(client_thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(client_thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+    PR_DELETE(client_thread);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: interrupting/joining enumeration_thread\n", shared->title);
+    rv = PR_Interrupt(enumeration_thread);
+    MW_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(enumeration_thread);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: interrupting/joining server_thread\n", shared->title);
+    rv = PR_Interrupt(server_thread);
+    MW_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(server_thread);
+    MW_ASSERT(PR_SUCCESS == rv);
+}  /* RealOneGroupIO */
+
+static void RunThisOne(
+    void (*func)(Shared*), const char *name, const char *test_name)
+{
+    Shared *shared;
+    if ((NULL == test_name) || (0 == PL_strcmp(name, test_name)))
+    {
+        if (verbosity > silent)
+            PR_fprintf(debug, "%s()\n", name);
+        shared = MakeShared(name);
+        ops_done = 0;
+        func(shared);  /* run the test */
+        MW_ASSERT(0 == desc_allocated);
+        DestroyShared(shared);
+    }
+}  /* RunThisOne */
+
+static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
+{
+    PRIntn verbage = (PRIntn)verbosity;
+    return (Verbosity)(verbage += delta);
+}  /* ChangeVerbosity */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    const char *test_name = NULL;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGc:o:p:t:w:");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            test_name = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            if (verbosity < noisy)
+                verbosity = ChangeVerbosity(verbosity, 1);
+            break;
+        case 'q':  /* debug mode */
+            if (verbosity > silent)
+                verbosity = ChangeVerbosity(verbosity, -1);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'c':  /* number of client threads */
+            client_threads = atoi(opt->value);
+            break;
+        case 'o':  /* operations to compelete */
+            ops_required = atoi(opt->value);
+            break;
+        case 'p':  /* default port */
+            default_port = atoi(opt->value);
+            break;
+        case 't':  /* number of threads waiting */
+            worker_threads = atoi(opt->value);
+            break;
+        case 'w':  /* number of wait objects */
+            wait_objects = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (verbosity > 0)
+        debug = PR_GetSpecialFD(PR_StandardError);
+
+    RunThisOne(OneInThenCancelled, "OneInThenCancelled", test_name);
+    RunThisOne(OneOpOneThread, "OneOpOneThread", test_name);
+    RunThisOne(ManyOpOneThread, "ManyOpOneThread", test_name);
+    RunThisOne(SomeOpsSomeThreads, "SomeOpsSomeThreads", test_name);
+    RunThisOne(RealOneGroupIO, "RealOneGroupIO", test_name);
+    return 0;
+}  /* main */
+
+/* multwait.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/nameshm1.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/nameshm1.c
new file mode 100644
index 0000000..6cc8f56
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/nameshm1.c
@@ -0,0 +1,608 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: nameshm1.c -- Test Named Shared Memory
+**
+** Description: 
+** nameshm1 tests Named Shared Memory. nameshm1 performs two tests of
+** named shared memory. 
+** 
+** The first test is a basic test. The basic test operates as a single
+** process. The process exercises all the API elements of the facility.
+** This test also attempts to write to all locations in the shared
+** memory.
+**
+** The second test is a client-server test. The client-server test
+** creates a new instance of nameshm1, passing the -C argument to the
+** new process; this creates the client-side process. The server-side
+** (the instance of nameshm1 created from the command line) and the
+** client-side interact via inter-process semaphores to verify that the
+** shared memory segment can be read and written by both sides in a
+** synchronized maner.
+**
+** Note: Because this test runs in two processes, the log files created
+** by the test are not in chronological sequence; makes it hard to read.
+** As a temporary circumvention, I changed the definition(s) of the
+** _PUT_LOG() macro in prlog.c to force a flushall(), or equivalent.
+** This causes the log entries to be emitted in true chronological
+** order.
+**
+** Synopsis: nameshm1 [options] [name]
+** 
+** Options:
+** -d       Enables debug trace via PR_LOG()
+** -v       Enables verbose mode debug trace via PR_LOG()
+** -w       Causes the basic test to attempt to write to the segment
+**          mapped as read-only. When this option is specified, the
+**          test should crash with a seg-fault; this is a destructive
+**          test and is considered successful when it seg-faults.
+** 
+** -C       Causes nameshm1 to start as the client-side of a
+**          client-server pair of processes. Only the instance
+**          of nameshm1 operating as the server-side process should
+**          specify the -C option when creating the client-side process;
+**          the -C option should not be specified at the command line.
+**          The client-side uses the shared memory segment created by
+**          the server-side to communicate with the server-side
+**          process.
+**          
+** -p <n>   Specify the number of iterations the client-server tests
+**          should perform. Default: 1000.
+**
+** -s <n>   Size, in KBytes (1024), of the shared memory segment.
+**          Default: (10 * 1024)
+**
+** -i <n>   Number of client-side iterations. Default: 3
+**
+** name     specifies the name of the shared memory segment to be used.
+**          Default: /tmp/xxxNSPRshm
+**
+**
+** See also: prshm.h
+**
+** /lth. Aug-1999.
+*/
+
+#include <plgetopt.h> 
+#include <nspr.h>
+#include <stdlib.h>
+#include <string.h>
+#include <private/primpl.h>
+
+#ifdef SYMBIAN
+#define SEM_NAME1 "c:\\data\\nameshmSEM1"
+#define SEM_NAME2 "c:\\data\\nameshmSEM2"
+#define OPT_NAME "c:\\data\\xxxNSPRshm"
+#define EXE_NAME "nspr_tests_nameshm1.exe"
+#else
+#define SEM_NAME1 "/tmp/nameshmSEM1"
+#define SEM_NAME2 "/tmp/nameshmSEM2"
+#define OPT_NAME "/tmp/xxxNSPRshm"
+#define EXE_NAME "nameshm1"
+#endif
+#define SEM_MODE  0666
+#define SHM_MODE  0666
+
+#define NameSize (1024)
+
+PRIntn  debug = 0;
+PRIntn  failed_already = 0;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRLogModuleInfo *lm;
+
+/* command line options */
+PRIntn      optDebug = 0;
+PRIntn      optVerbose = 0;
+PRUint32    optWriteRO = 0;     /* test write to read-only memory. should crash  */
+PRUint32    optClient = 0;
+PRUint32    optCreate = 1;
+PRUint32    optAttachRW = 1;
+PRUint32    optAttachRO = 1;
+PRUint32    optClose = 1;
+PRUint32    optDelete = 1;
+PRInt32     optPing = 1000;
+PRUint32    optSize = (10 * 1024 );
+PRInt32     optClientIterations = 3;
+char        optName[NameSize] = OPT_NAME;
+
+char buf[1024] = "";
+
+
+static void BasicTest( void ) 
+{
+    PRSharedMemory  *shm;
+    char *addr; /* address of shared memory segment */
+    PRUint32  i;
+    PRInt32 rc;
+
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Begin BasicTest" ));
+
+    if ( PR_FAILURE == PR_DeleteSharedMemory( optName )) {
+        PR_LOG( lm, msgLevel,
+            ("nameshm1: Initial PR_DeleteSharedMemory() failed. No problem"));
+    } else
+        PR_LOG( lm, msgLevel,
+            ("nameshm1: Initial PR_DeleteSharedMemory() success"));
+
+
+    shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE );
+    if ( NULL == shm )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Create: success: %p", shm ));
+
+    addr = PR_AttachSharedMemory( shm , 0 );
+    if ( NULL == addr ) 
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Attach: success: %p", addr ));
+
+    /* fill memory with i */
+    for ( i = 0; i < optSize ;  i++ )
+    {
+         *(addr + i) = i;
+    }
+
+    rc = PR_DetachSharedMemory( shm, addr );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Detach: success: " ));
+
+    rc = PR_CloseSharedMemory( shm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Close: success: " ));
+
+    rc = PR_DeleteSharedMemory( optName );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Delete: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Delete: success: " ));
+
+    PR_LOG( lm, msgLevel,
+            ("nameshm1: BasicTest(): Passed"));
+
+    return;
+} /* end BasicTest() */
+
+static void ReadOnlyTest( void )
+{
+    PRSharedMemory  *shm;
+    char *roAddr; /* read-only address of shared memory segment */
+    PRInt32 rc;
+
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Begin ReadOnlyTest" ));
+
+    shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE);
+    if ( NULL == shm )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Create: success: %p", shm ));
+
+
+    roAddr = PR_AttachSharedMemory( shm , PR_SHM_READONLY );
+    if ( NULL == roAddr ) 
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Attach: success: %p", roAddr ));
+
+    if ( optWriteRO )
+    {
+        *roAddr = 0x00; /* write to read-only memory */
+        failed_already = 1;
+        PR_LOG( lm, msgLevel, ("nameshm1: Wrote to read-only memory segment!"));
+        return;
+    }
+
+    rc = PR_DetachSharedMemory( shm, roAddr );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Detach: success: " ));
+
+    rc = PR_CloseSharedMemory( shm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Close: success: " ));
+
+    rc = PR_DeleteSharedMemory( optName );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Destroy: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Destroy: success: " ));
+
+    PR_LOG( lm, msgLevel,
+        ("nameshm1: ReadOnlyTest(): Passed"));
+
+    return;
+} /* end ReadOnlyTest() */
+
+static void DoClient( void )
+{
+    PRStatus rc;
+    PRSem *sem1, *sem2;
+    PRSharedMemory  *shm;
+    PRUint32 *addr; 
+    PRInt32 i;
+
+    PR_LOG( lm, msgLevel,
+            ("nameshm1: DoClient(): Starting"));
+
+    sem1 = PR_OpenSemaphore( SEM_NAME1, 0, 0, 0 );
+    PR_ASSERT( sem1 );
+
+    sem2 = PR_OpenSemaphore( SEM_NAME2, 0, 0, 0 );
+    PR_ASSERT( sem1 );
+
+    shm = PR_OpenSharedMemory( optName, optSize, 0, SHM_MODE );
+    if ( NULL == shm )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: DoClient(): Create: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: DoClient(): Create: success: %p", shm ));
+
+    addr = PR_AttachSharedMemory( shm , 0 );
+    if ( NULL == addr ) 
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: DoClient(): Attach: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: DoClient(): Attach: success: %p", addr ));
+
+    PR_LOG( lm, msgLevel,
+        ( "Client found: %s", addr));
+
+    PR_Sleep(PR_SecondsToInterval(4));
+    for ( i = 0 ; i < optPing ; i++ )
+    {
+        rc = PR_WaitSemaphore( sem2 );
+        PR_ASSERT( PR_FAILURE != rc );
+        
+        (*addr)++;
+        PR_ASSERT( (*addr % 2) == 0 );        
+        if ( optVerbose )
+            PR_LOG( lm, msgLevel,
+                 ( "nameshm1: Client ping: %d, i: %d", *addr, i));
+
+        rc = PR_PostSemaphore( sem1 );
+        PR_ASSERT( PR_FAILURE != rc );
+    }
+
+    rc = PR_CloseSemaphore( sem1 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_CloseSemaphore( sem2 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_DetachSharedMemory( shm, addr );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: DoClient(): Detach: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: DoClient(): Detach: success: " ));
+
+    rc = PR_CloseSharedMemory( shm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: DoClient(): Close: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: DoClient(): Close: success: " ));
+
+    return;
+}    /* end DoClient() */
+
+static void ClientServerTest( void )
+{
+    PRStatus rc;
+    PRSem *sem1, *sem2;
+    PRProcess *proc;
+    PRInt32 exit_status;
+    PRSharedMemory  *shm;
+    PRUint32 *addr; 
+    PRInt32 i;
+    char *child_argv[8];
+    char buf[24];
+
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Begin ClientServerTest" ));
+
+    rc = PR_DeleteSharedMemory( optName );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Destroy: failed. No problem"));
+    } else
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Destroy: success" ));
+
+
+    shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE);
+    if ( NULL == shm )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: Server: Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Server: Create: success: %p", shm ));
+
+    addr = PR_AttachSharedMemory( shm , 0 );
+    if ( NULL == addr ) 
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: Server: Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Server: Attach: success: %p", addr ));
+
+    sem1 = PR_OpenSemaphore( SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0 );
+    PR_ASSERT( sem1 );
+
+    sem2 = PR_OpenSemaphore( SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 1 );
+    PR_ASSERT( sem1 );
+
+    strcpy( (char*)addr, "FooBar" );
+
+    child_argv[0] = EXE_NAME;
+    child_argv[1] = "-C";
+    child_argv[2] = "-p";
+    sprintf( buf, "%d", optPing );
+    child_argv[3] = buf;
+    child_argv[4] = optName;
+    child_argv[5] = NULL;
+
+    proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
+    PR_ASSERT( proc );
+
+    PR_Sleep( PR_SecondsToInterval(4));
+
+    *addr = 1;
+    for ( i = 0 ; i < optPing ; i++ )
+    { 
+        rc = PR_WaitSemaphore( sem1 );
+        PR_ASSERT( PR_FAILURE != rc );
+
+        (*addr)++;
+        PR_ASSERT( (*addr % 2) == 1 );
+        if ( optVerbose )
+            PR_LOG( lm, msgLevel,
+                 ( "nameshm1: Server pong: %d, i: %d", *addr, i));
+
+    
+        rc = PR_PostSemaphore( sem2 );
+        PR_ASSERT( PR_FAILURE != rc );
+    }
+
+    rc = PR_WaitProcess( proc, &exit_status );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_CloseSemaphore( sem1 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_CloseSemaphore( sem2 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_DeleteSemaphore( SEM_NAME1 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_DeleteSemaphore( SEM_NAME2 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_DetachSharedMemory( shm, addr );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Detach: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Server: Detach: success: " ));
+
+    rc = PR_CloseSharedMemory( shm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Close: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+        ( "nameshm1: Server: Close: success: " ));
+
+    rc = PR_DeleteSharedMemory( optName );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Destroy: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+        ( "nameshm1: Server: Destroy: success" ));
+
+    return;
+} /* end ClientServerTest() */
+
+int main(int argc, char **argv)
+{
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "Cdvw:s:p:i:");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'v':  /* debug mode */
+                optVerbose = 1;
+                /* no break! fall into debug option */
+            case 'd':  /* debug mode */
+                debug = 1;
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+            case 'w':  /* try writing to memory mapped read-only */
+                optWriteRO = 1;
+                break;
+            case 'C':
+                optClient = 1;
+                break;
+            case 's':
+                optSize = atol(opt->value) * 1024;
+                break;
+            case 'p':
+                optPing = atol(opt->value);
+                break;
+            case 'i':
+                optClientIterations = atol(opt->value);
+                break;
+            default:
+                strcpy( optName, opt->value );
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+    
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Starting" ));
+
+    if ( optClient )
+    {
+        DoClient();
+    } else {
+        BasicTest();
+        if ( failed_already != 0 )
+            goto Finished;
+        ReadOnlyTest();
+        if ( failed_already != 0 )
+            goto Finished;
+        ClientServerTest();
+    }
+
+Finished:
+    if ( debug ) printf("%s\n", (failed_already)? "FAIL" : "PASS" );
+    return( (failed_already)? 1 : 0 );
+}  /* main() */
+/* end instrumt.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/nbconn.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/nbconn.c
new file mode 100644
index 0000000..27e0e69
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/nbconn.c
@@ -0,0 +1,552 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * A test for nonblocking connect.  Functions tested include PR_Connect,
+ * PR_Poll, and PR_GetConnectStatus.
+ *
+ * The test should be invoked with a host name, for example:
+ *     nbconn www.netscape.com
+ * It will do a nonblocking connect to port 80 (HTTP) on that host,
+ * and when connected, issue the "GET /" HTTP command.
+ *
+ * You should run this test in three ways:
+ * 1. To a known web site, such as www.netscape.com.  The HTML of the
+ *    top-level page at the web site should be printed.
+ * 2. To a machine not running a web server at port 80.  This test should
+ *    fail.  Ideally the error code should be PR_CONNECT_REFUSED_ERROR.
+ *    But it is possible to return PR_UNKNOWN_ERROR on certain platforms.
+ * 3. To an unreachable machine, for example, a machine that is off line.
+ *    The test should fail after the connect times out.  Ideally the
+ *    error code should be PR_IO_TIMEOUT_ERROR, but it is possible to
+ *    return PR_UNKNOWN_ERROR on certain platforms.
+ */
+
+#include "nspr.h"
+#include "plgetopt.h"
+#include <stdio.h>
+#include <string.h>
+
+#define SERVER_MAX_BIND_COUNT        100
+#define DATA_BUF_SIZE        		 256
+#define TCP_SERVER_PORT            10000
+#define TCP_UNUSED_PORT            211
+
+typedef struct Server_Param {
+    PRFileDesc *sp_fd;		/* server port */
+} Server_Param;
+static void PR_CALLBACK TCP_Server(void *arg);
+
+int _debug_on;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+static PRIntn connection_success_test();
+static PRIntn connection_failure_test();
+
+int main(int argc, char **argv)
+{
+    PRHostEnt he;
+    char buf[1024];
+    PRNetAddr addr;
+    PRPollDesc pd;
+    PRStatus rv;
+    PRSocketOptionData optData;
+	const char *hostname = NULL;
+    PRIntn default_case, n, bytes_read, bytes_sent;
+	PRInt32 failed_already = 0;
+
+    /*
+     * -d           debug mode
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:  /* debug mode */
+            hostname = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_STDIO_INIT();
+    if (hostname)
+		default_case = 0;
+	else
+		default_case = 1;
+
+	if (default_case) {
+
+		/*
+		 * In the default case the following tests are executed:
+		 *	1. successful connection: a server thread accepts a connection
+		 *	   from the main thread
+		 *	2. unsuccessful connection: the main thread tries to connect to a
+		 *	   nonexistent port and expects to get an error
+		 */
+		rv = connection_success_test();
+		if (rv == 0)
+			rv = connection_failure_test();
+		return rv;
+	} else {
+    	PRFileDesc *sock;
+
+		if (PR_GetHostByName(argv[1], buf, sizeof(buf), &he) == PR_FAILURE) {
+			printf( "Unknown host: %s\n", argv[1]);
+			exit(1);
+		} else {
+			printf( "host: %s\n", buf);
+		}
+		PR_EnumerateHostEnt(0, &he, 80, &addr);
+
+		sock = PR_NewTCPSocket();
+		optData.option = PR_SockOpt_Nonblocking;
+		optData.value.non_blocking = PR_TRUE;
+		PR_SetSocketOption(sock, &optData);
+		rv = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+		if (rv == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
+			printf( "Connect in progress\n");
+		}
+
+		pd.fd = sock;
+		pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+		n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+		if (n == -1) {
+			printf( "PR_Poll failed\n");
+			exit(1);
+		}
+		printf( "PR_Poll returns %d\n", n);
+		if (pd.out_flags & PR_POLL_READ) {
+			printf( "PR_POLL_READ\n");
+		}
+		if (pd.out_flags & PR_POLL_WRITE) {
+			printf( "PR_POLL_WRITE\n");
+		}
+		if (pd.out_flags & PR_POLL_EXCEPT) {
+			printf( "PR_POLL_EXCEPT\n");
+		}
+		if (pd.out_flags & PR_POLL_ERR) {
+			printf( "PR_POLL_ERR\n");
+		}
+		if (pd.out_flags & PR_POLL_NVAL) {
+			printf( "PR_POLL_NVAL\n");
+		}
+
+		if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
+			printf("PR_GetConnectStatus: connect succeeded\n");
+			PR_Write(sock, "GET /\r\n\r\n", 9);
+			PR_Shutdown(sock, PR_SHUTDOWN_SEND);
+			pd.in_flags = PR_POLL_READ;
+			while (1) {
+				n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+				printf( "poll returns %d\n", n);
+				n = PR_Read(sock, buf, sizeof(buf));
+				printf( "read returns %d\n", n);
+				if (n <= 0) {
+					break;
+				}
+				PR_Write(PR_STDOUT, buf, n);
+			}
+		} else {
+			if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
+				printf( "PR_GetConnectStatus: connect still in progress\n");
+				exit(1);
+			}
+			printf( "PR_GetConnectStatus: connect failed: (%ld, %ld)\n",
+					PR_GetError(), PR_GetOSError());
+		}
+		PR_Close(sock);
+    	printf( "PASS\n");
+    	return 0;
+
+	}
+}
+
+
+/*
+ * TCP Server
+ *    Server Thread
+ *    Accept a connection from the client and write some data
+ */
+static void PR_CALLBACK
+TCP_Server(void *arg)
+{
+    Server_Param *sp = (Server_Param *) arg;
+    PRFileDesc *sockfd, *newsockfd;
+	char data_buf[DATA_BUF_SIZE];
+    PRIntn rv, bytes_read;
+
+	sockfd = sp->sp_fd;
+	if ((newsockfd = PR_Accept(sockfd, NULL,
+		PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+		fprintf(stderr,"ERROR - PR_Accept failed: (%d,%d)\n",
+										PR_GetError(), PR_GetOSError());
+		return;
+	}
+	bytes_read = 0;
+	while (bytes_read != DATA_BUF_SIZE) {
+		rv = PR_Read(newsockfd, data_buf + bytes_read ,
+									DATA_BUF_SIZE - bytes_read);
+		if (rv < 0) {
+			fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n",
+							PR_GetError(), PR_GetOSError());
+			PR_Close(newsockfd);
+			return;
+		}
+		PR_ASSERT(rv != 0);
+		bytes_read += rv;
+	}
+	DPRINTF(("Bytes read from client - %d\n",bytes_read));
+	rv = PR_Write(newsockfd, data_buf,DATA_BUF_SIZE);
+	if (rv < 0) {
+		fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n",
+						PR_GetError(), PR_GetOSError());
+		PR_Close(newsockfd);
+		return;
+	}
+	PR_ASSERT(rv == DATA_BUF_SIZE);
+	DPRINTF(("Bytes written to client - %d\n",rv));
+	PR_Close(newsockfd);
+}
+
+
+/*
+ * test for successful connection using a non-blocking socket
+ */
+static PRIntn
+connection_success_test()
+{
+	PRFileDesc *sockfd = NULL, *conn_fd = NULL;
+	PRNetAddr netaddr;
+	PRInt32 i, rv;
+    PRPollDesc pd;
+    PRSocketOptionData optData;
+	PRThread *thr = NULL;
+	Server_Param sp;
+	char send_buf[DATA_BUF_SIZE], recv_buf[DATA_BUF_SIZE];
+    PRIntn default_case, n, bytes_read, bytes_sent;
+    PRIntn failed_already = 0;
+
+	/*
+	 * Create a tcp socket
+	 */
+	if ((sockfd = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	memset(&netaddr, 0 , sizeof(netaddr));
+	netaddr.inet.family = PR_AF_INET;
+	netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
+	netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+	/*
+	 * try a few times to bind server's address, if addresses are in
+	 * use
+	 */
+	i = 0;
+	while (PR_Bind(sockfd, &netaddr) < 0) {
+		if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+			netaddr.inet.port += 2;
+			if (i++ < SERVER_MAX_BIND_COUNT)
+				continue;
+		}
+		fprintf(stderr,"ERROR - PR_Bind failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+
+	if (PR_Listen(sockfd, 32) < 0) {
+		fprintf(stderr,"ERROR - PR_Listen failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+
+	if (PR_GetSockName(sockfd, &netaddr) < 0) {
+		fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+	if ((conn_fd = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	optData.option = PR_SockOpt_Nonblocking;
+	optData.value.non_blocking = PR_TRUE;
+	PR_SetSocketOption(conn_fd, &optData);
+	rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT);
+	if (rv == PR_FAILURE) {
+		if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
+			DPRINTF(("Connect in progress\n"));
+		} else  {
+			fprintf(stderr,"Error - PR_Connect failed: (%d, %d)\n",
+									PR_GetError(), PR_GetOSError());
+			failed_already=1;
+			goto def_exit;
+		}
+	}
+	/*
+	 * Now create a thread to accept a connection
+	 */
+	sp.sp_fd = sockfd;
+	thr = PR_CreateThread(PR_USER_THREAD, TCP_Server, (void *)&sp, 
+			PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+	if (thr == NULL) {
+		fprintf(stderr,"Error - PR_CreateThread failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+	DPRINTF(("Created TCP_Server thread [0x%x]\n",thr));
+	pd.fd = conn_fd;
+	pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+	if (n == -1) {
+		fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+	if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
+		PRInt32 rv;
+
+		DPRINTF(("Connection successful\n"));
+
+		/*
+		 * Write some data, read it back and check data integrity to
+		 * make sure the connection is good
+		 */
+		pd.in_flags = PR_POLL_WRITE;
+		bytes_sent = 0;
+		memset(send_buf, 'a', DATA_BUF_SIZE);
+		while (bytes_sent != DATA_BUF_SIZE) {
+			rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+			if (rv < 0) {
+				fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
+								PR_GetError(), PR_GetOSError());
+				failed_already=1;
+				goto def_exit;
+			}
+			PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_WRITE));
+			rv = PR_Write(conn_fd, send_buf + bytes_sent,
+										DATA_BUF_SIZE - bytes_sent);
+			if (rv < 0) {
+				fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n",
+								PR_GetError(), PR_GetOSError());
+				failed_already=1;
+				goto def_exit;
+			}
+			PR_ASSERT(rv > 0);
+			bytes_sent += rv;
+		}
+		DPRINTF(("Bytes written to server - %d\n",bytes_sent));
+		PR_Shutdown(conn_fd, PR_SHUTDOWN_SEND);
+		pd.in_flags = PR_POLL_READ;
+		bytes_read = 0;
+		memset(recv_buf, 0, DATA_BUF_SIZE);
+		while (bytes_read != DATA_BUF_SIZE) {
+			rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+			if (rv < 0) {
+				fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
+								PR_GetError(), PR_GetOSError());
+				failed_already=1;
+				goto def_exit;
+			}
+			PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_READ));
+			rv = PR_Read(conn_fd, recv_buf + bytes_read ,
+										DATA_BUF_SIZE - bytes_read);
+			if (rv < 0) {
+				fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n",
+								PR_GetError(), PR_GetOSError());
+				failed_already=1;
+				goto def_exit;
+			}
+			PR_ASSERT(rv != 0);
+			bytes_read += rv;
+		}
+		DPRINTF(("Bytes read from server - %d\n",bytes_read));
+		/*
+		 * verify the data read
+		 */
+		if (memcmp(send_buf, recv_buf, DATA_BUF_SIZE) != 0) {
+			fprintf(stderr,"ERROR - data corruption\n");
+			failed_already=1;
+			goto def_exit;
+		}
+		DPRINTF(("Data integrity verified\n"));
+	} else {
+		fprintf(stderr,"PR_GetConnectStatus: connect failed: (%ld, %ld)\n",
+				PR_GetError(), PR_GetOSError());
+		failed_already = 1;
+		goto def_exit;
+	}
+def_exit:
+	if (thr) {
+		PR_JoinThread(thr);
+		thr = NULL;
+	}
+	if (sockfd) {
+		PR_Close(sockfd);
+		sockfd = NULL;
+	}
+	if (conn_fd) {
+		PR_Close(conn_fd);
+		conn_fd = NULL;
+	}
+	if (failed_already)
+		return 1;
+	else
+		return 0;
+
+}
+
+/*
+ * test for connection to a nonexistent port using a non-blocking socket
+ */
+static PRIntn
+connection_failure_test()
+{
+	PRFileDesc *sockfd = NULL, *conn_fd = NULL;
+	PRNetAddr netaddr;
+	PRInt32 i, rv;
+    PRPollDesc pd;
+    PRSocketOptionData optData;
+    PRIntn n, failed_already = 0;
+
+	/*
+	 * Create a tcp socket
+	 */
+	if ((sockfd = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	memset(&netaddr, 0 , sizeof(netaddr));
+	netaddr.inet.family = PR_AF_INET;
+	netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
+	netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+	/*
+	 * try a few times to bind server's address, if addresses are in
+	 * use
+	 */
+	i = 0;
+	while (PR_Bind(sockfd, &netaddr) < 0) {
+		if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+			netaddr.inet.port += 2;
+			if (i++ < SERVER_MAX_BIND_COUNT)
+				continue;
+		}
+		fprintf(stderr,"ERROR - PR_Bind failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+
+	if (PR_GetSockName(sockfd, &netaddr) < 0) {
+		fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+#ifdef AIX
+	/*
+	 * On AIX, set to unused/reserved port
+	 */
+	netaddr.inet.port = PR_htons(TCP_UNUSED_PORT);
+#endif
+	if ((conn_fd = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	optData.option = PR_SockOpt_Nonblocking;
+	optData.value.non_blocking = PR_TRUE;
+	PR_SetSocketOption(conn_fd, &optData);
+	rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT);
+	if (rv == PR_FAILURE) {
+		DPRINTF(("PR_Connect to a non-listen port failed: (%d, %d)\n",
+									PR_GetError(), PR_GetOSError()));
+	} else {
+		PR_ASSERT(rv == PR_SUCCESS);
+		fprintf(stderr,"Error - PR_Connect succeeded, expected to fail\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	pd.fd = conn_fd;
+	pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+	if (n == -1) {
+		fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+	if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
+		PRInt32 rv;
+		fprintf(stderr,"PR_GetConnectStatus succeeded, expected to fail\n");
+		failed_already = 1;
+		goto def_exit;
+	}
+	rv = PR_GetError();
+	DPRINTF(("Connection failed, successfully with PR_Error %d\n",rv));
+def_exit:
+	if (sockfd) {
+		PR_Close(sockfd);
+		sockfd = NULL;
+	}
+	if (conn_fd) {
+		PR_Close(conn_fd);
+		conn_fd = NULL;
+	}
+	if (failed_already)
+		return 1;
+	else
+		return 0;
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/nblayer.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/nblayer.c
new file mode 100644
index 0000000..19df5cf
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/nblayer.c
@@ -0,0 +1,707 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prerror.h"
+#include "prnetdb.h"
+#include "prthread.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+#include "prwin16.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Testing layering of I/O
+**
+**      The layered server
+** A thread that acts as a server. It creates a TCP listener with a dummy
+** layer pushed on top. Then listens for incoming connections. Each connection
+** request for connection will be layered as well, accept one request, echo
+** it back and close.
+**
+**      The layered client
+** Pretty much what you'd expect.
+*/
+
+static PRFileDesc *logFile;
+static PRDescIdentity identity;
+static PRNetAddr server_address;
+
+static PRIOMethods myMethods;
+
+typedef enum {rcv_get_debit, rcv_send_credit, rcv_data} RcvState;
+typedef enum {xmt_send_debit, xmt_recv_credit, xmt_data} XmtState;
+
+struct PRFilePrivate
+{
+    RcvState rcvstate;
+    XmtState xmtstate;
+    PRInt32 rcvreq, rcvinprogress;
+    PRInt32 xmtreq, xmtinprogress;
+};
+
+typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
+
+static PRIntn minor_iterations = 5;
+static PRIntn major_iterations = 1;
+static Verbosity verbosity = quiet;
+static PRUint16 default_port = 12273;
+
+static PRFileDesc *PushLayer(PRFileDesc *stack)
+{
+    PRStatus rv;
+    PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods);
+    layer->secret = PR_NEWZAP(PRFilePrivate);
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);
+    return stack;
+}  /* PushLayer */
+
+static PRFileDesc *PopLayer(PRFileDesc *stack)
+{
+    PRFileDesc *popped = PR_PopIOLayer(stack, identity);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack);
+    PR_DELETE(popped->secret);
+    popped->dtor(popped);
+    return stack;
+}  /* PopLayer */
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRIntn mits;
+    PRInt32 ready;
+    PRUint8 buffer[100];
+    PRPollDesc polldesc;
+    PRIntn empty_flags = 0;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+
+    /* Initialize the buffer so that Purify won't complain */
+    memset(buffer, 0, sizeof(buffer));
+
+    rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
+    if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError()))
+    {
+        if (verbosity > quiet)
+            PR_fprintf(logFile, "Client connect 'in progress'\n");
+        do
+        {
+            polldesc.fd = stack;
+            polldesc.out_flags = 0;
+            polldesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+            ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+            if ((1 != ready)  /* if not 1, then we're dead */
+            || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                { PR_ASSERT(!"Whoa!"); break; }
+            if (verbosity > quiet)
+                PR_fprintf(
+                    logFile, "Client connect 'in progress' [0x%x]\n",
+                    polldesc.out_flags);
+            rv = PR_GetConnectStatus(&polldesc);
+            if ((PR_FAILURE == rv)
+            && (PR_IN_PROGRESS_ERROR != PR_GetError())) break;
+        } while (PR_FAILURE == rv);
+    }
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (verbosity > chatty)
+        PR_fprintf(logFile, "Client created connection\n");
+
+    for (mits = 0; mits < minor_iterations; ++mits)
+    {
+        bytes_sent = 0;
+        if (verbosity > quiet)
+            PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer));
+        do
+        {
+            if (verbosity > chatty)
+                PR_fprintf(
+                    logFile, "Client sending %d bytes\n",
+                    sizeof(buffer) - bytes_sent);
+            ready = PR_Send(
+                stack, buffer + bytes_sent, sizeof(buffer) - bytes_sent,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Client send status [%d]\n", ready);
+            if (0 < ready) bytes_sent += ready;
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = stack;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_WRITE;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if ((1 != ready)  /* if not 1, then we're dead */
+                || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                    { PR_ASSERT(!"Whoa!"); break; }
+            }
+            else break;
+        } while (bytes_sent < sizeof(buffer));
+        PR_ASSERT(sizeof(buffer) == bytes_sent);
+
+        bytes_read = 0;
+        do
+        {
+            if (verbosity > chatty)
+                PR_fprintf(
+                    logFile, "Client receiving %d bytes\n",
+                    bytes_sent - bytes_read);
+            ready = PR_Recv(
+                stack, buffer + bytes_read, bytes_sent - bytes_read,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (verbosity > chatty)
+                PR_fprintf(
+                    logFile, "Client receive status [%d]\n", ready);
+            if (0 < ready) bytes_read += ready;
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = stack;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_READ;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if ((1 != ready)  /* if not 1, then we're dead */
+                || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                    { PR_ASSERT(!"Whoa!"); break; }
+            }
+            else break;
+        } while (bytes_read < bytes_sent);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Client received %d bytes\n", bytes_read);
+        PR_ASSERT(bytes_read == bytes_sent);
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Client shutting down stack\n");
+    
+    rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+}  /* Client */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRInt32 ready;
+    PRUint8 buffer[100];
+    PRFileDesc *service;
+    PRUintn empty_flags = 0;
+    struct PRPollDesc polldesc;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+    PRNetAddr client_address;
+
+    do
+    {
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Server accepting connection\n");
+        service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Server accept status [0x%p]\n", service);
+        if ((NULL == service) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+        {
+            polldesc.fd = stack;
+            polldesc.out_flags = 0;
+            polldesc.in_flags = PR_POLL_READ | PR_POLL_EXCEPT;
+            ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+            if ((1 != ready)  /* if not 1, then we're dead */
+            || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                { PR_ASSERT(!"Whoa!"); break; }
+        }
+    } while (NULL == service);
+    PR_ASSERT(NULL != service);
+        
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server accepting connection\n");
+
+    do
+    {
+        bytes_read = 0;
+        do
+        {
+            if (verbosity > chatty)
+                PR_fprintf(
+                    logFile, "Server receiving %d bytes\n",
+                    sizeof(buffer) - bytes_read);
+            ready = PR_Recv(
+                service, buffer + bytes_read, sizeof(buffer) - bytes_read,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server receive status [%d]\n", ready);
+            if (0 < ready) bytes_read += ready;
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = service;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_READ;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if ((1 != ready)  /* if not 1, then we're dead */
+                || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                    { PR_ASSERT(!"Whoa!"); break; }
+            }
+            else break;
+        } while (bytes_read < sizeof(buffer));
+
+        if (0 != bytes_read)
+        {
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server received %d bytes\n", bytes_read);
+            PR_ASSERT(bytes_read > 0);
+
+            bytes_sent = 0;
+            do
+            {
+                ready = PR_Send(
+                    service, buffer + bytes_sent, bytes_read - bytes_sent,
+                    empty_flags, PR_INTERVAL_NO_TIMEOUT);
+                if (0 < ready)
+                {
+                    bytes_sent += ready;
+                }
+                else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+                {
+                    polldesc.fd = service;
+                    polldesc.out_flags = 0;
+                    polldesc.in_flags = PR_POLL_WRITE;
+                    ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                    if ((1 != ready)  /* if not 1, then we're dead */
+                    || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                        { PR_ASSERT(!"Whoa!"); break; }
+                }
+                else break;
+            } while (bytes_sent < bytes_read);
+            PR_ASSERT(bytes_read == bytes_sent);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server sent %d bytes\n", bytes_sent);
+        }
+    } while (0 != bytes_read);
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server shutting down stack\n");
+    rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+
+}  /* Server */
+
+static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd)
+{
+    PR_DELETE(fd->secret);  /* manage my secret file object */
+    return (PR_GetDefaultIOMethods())->close(fd);  /* let him do all the work */
+}  /* MyClose */
+
+static PRInt16 PR_CALLBACK MyPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    PRInt16 my_flags, new_flags;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+    if (0 != (PR_POLL_READ & in_flags))
+    {
+        /* client thinks he's reading */
+        switch (mine->rcvstate)
+        {
+            case rcv_send_credit:
+                my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE;
+                break;
+            case rcv_data:
+            case rcv_get_debit:
+                my_flags = in_flags;
+            default: break;
+        }
+    }
+    else if (0 != (PR_POLL_WRITE & in_flags))
+    {
+        /* client thinks he's writing */
+        switch (mine->xmtstate)
+        {
+            case xmt_recv_credit:
+                my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ;
+                break;
+            case xmt_send_debit:
+            case xmt_data:
+                my_flags = in_flags;
+            default: break;
+        }
+    }
+    else PR_ASSERT(!"How'd I get here?");
+    new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags);
+    if (verbosity > chatty)
+        PR_fprintf(
+            logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n",
+            in_flags, my_flags, *out_flags, new_flags);
+    return new_flags;
+}  /* MyPoll */
+
+static PRFileDesc * PR_CALLBACK MyAccept(
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRFileDesc *newfd, *layer = fd;
+    PRFileDesc *newstack;
+    PRFilePrivate *newsecret;
+
+    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;
+    }
+    newsecret = PR_NEW(PRFilePrivate);
+    if (NULL == newsecret)
+    {
+        PR_DELETE(newstack);
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    *newstack = *fd;  /* make a copy of the accepting layer */
+    *newsecret = *fd->secret;
+    newstack->secret = newsecret;
+
+    newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
+    if (NULL == newfd)
+    {
+        PR_DELETE(newsecret);
+        PR_DELETE(newstack);
+        return NULL;
+    }
+
+    /* this PR_PushIOLayer call cannot fail */
+    rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return newfd;  /* that's it */
+}
+
+static PRInt32 PR_CALLBACK MyRecv(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    char *b;
+    PRInt32 rv;
+    PRFileDesc *lo = fd->lower;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+
+    do
+    {
+        switch (mine->rcvstate)
+        {
+        case rcv_get_debit:
+            b = (char*)&mine->rcvreq;
+            mine->rcvreq = amount;
+            rv = lo->methods->recv(
+                lo, b + mine->rcvinprogress,
+                sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);
+            if (0 == rv) goto closed;
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < sizeof(mine->rcvreq)) break;  /* loop */
+            mine->rcvstate = rcv_send_credit;
+            mine->rcvinprogress = 0;
+        case rcv_send_credit:
+            b = (char*)&mine->rcvreq;
+            rv = lo->methods->send(
+                lo, b + mine->rcvinprogress,
+                sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < sizeof(mine->rcvreq)) break;  /* loop */
+            mine->rcvstate = rcv_data;
+            mine->rcvinprogress = 0;
+        case rcv_data:
+            b = (char*)buf;
+            rv = lo->methods->recv(
+                lo, b + mine->rcvinprogress,
+                mine->rcvreq - mine->rcvinprogress, flags, timeout);
+            if (0 == rv) goto closed;
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < amount) break;  /* loop */
+            mine->rcvstate = rcv_get_debit;
+            mine->rcvinprogress = 0;
+            return mine->rcvreq;  /* << -- that's it! */
+        default:
+            break;
+        }
+    } while (-1 != rv);
+    return rv;
+closed:
+    mine->rcvinprogress = 0;
+    mine->rcvstate = rcv_get_debit;
+    return 0;
+}  /* MyRecv */
+
+static PRInt32 PR_CALLBACK MySend(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    char *b;
+    PRInt32 rv;
+    PRFileDesc *lo = fd->lower;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+
+    do
+    {
+        switch (mine->xmtstate)
+        {
+        case xmt_send_debit:
+            b = (char*)&mine->xmtreq;
+            mine->xmtreq = amount;
+            rv = lo->methods->send(
+                lo, b - mine->xmtinprogress,
+                sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;
+            mine->xmtstate = xmt_recv_credit;
+            mine->xmtinprogress = 0;
+        case xmt_recv_credit:
+             b = (char*)&mine->xmtreq;
+             rv = lo->methods->recv(
+                lo, b + mine->xmtinprogress,
+                sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;
+            mine->xmtstate = xmt_data;
+            mine->xmtinprogress = 0;
+        case xmt_data:
+            b = (char*)buf;
+            rv = lo->methods->send(
+                lo, b + mine->xmtinprogress,
+                mine->xmtreq - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < amount) break;
+            mine->xmtstate = xmt_send_debit;
+            mine->xmtinprogress = 0;
+            return mine->xmtreq;  /* <<-- That's the one! */
+        default:
+            break;
+        }
+    } while (-1 != rv);
+    return rv;
+}  /* MySend */
+
+static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
+{
+    PRIntn verbage = (PRIntn)verbosity + delta;
+    if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;
+    else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;
+    return (Verbosity)verbage;
+}  /* ChangeVerbosity */
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+    PLOptStatus os;
+    PRFileDesc *client, *service;
+    PRNetAddr any_address;
+    const char *server_name = NULL;
+    const PRIOMethods *stubMethods;
+    PRThread *client_thread, *server_thread;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRSocketOptionData socket_noblock, socket_nodelay;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            server_name = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            if (verbosity < noisy)
+                verbosity = ChangeVerbosity(verbosity, 1);
+            break;
+        case 'q':  /* debug mode */
+            if (verbosity > silent)
+                verbosity = ChangeVerbosity(verbosity, -1);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'C':  /* number of threads waiting */
+            major_iterations = atoi(opt->value);
+            break;
+        case 'c':  /* number of client threads */
+            minor_iterations = atoi(opt->value);
+            break;
+        case 'p':  /* default port */
+            default_port = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+
+    logFile = PR_GetSpecialFD(PR_StandardError);
+    identity = PR_GetUniqueIdentity("Dummy");
+    stubMethods = PR_GetDefaultIOMethods();
+
+    /*
+    ** The protocol we're going to implement is one where in order to initiate
+    ** a send, the sender must first solicit permission. Therefore, every
+    ** send is really a send - receive - send sequence.
+    */
+    myMethods = *stubMethods;  /* first get the entire batch */
+    myMethods.accept = MyAccept;  /* then override the ones we care about */
+    myMethods.recv = MyRecv;  /* then override the ones we care about */
+    myMethods.send = MySend;  /* then override the ones we care about */
+    myMethods.close = MyClose;  /* then override the ones we care about */
+    myMethods.poll = MyPoll;  /* then override the ones we care about */
+
+    if (NULL == server_name)
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, default_port, &server_address);
+    else
+    {
+        rv = PR_StringToNetAddr(server_name, &server_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrNull, default_port, &server_address);
+    }
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    socket_noblock.value.non_blocking = PR_TRUE;
+    socket_noblock.option = PR_SockOpt_Nonblocking;
+    socket_nodelay.value.no_delay = PR_TRUE;
+    socket_nodelay.option = PR_SockOpt_NoDelay;
+
+    /* one type w/o layering */
+
+    while (major_iterations-- > 0)
+    {
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning non-layered test\n");
+
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+
+        rv = PR_SetSocketOption(client, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(client, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending non-layered test\n");
+
+        /* with layering */
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning layered test\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+
+        rv = PR_SetSocketOption(client, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(client, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        PushLayer(client);
+        PushLayer(service);
+
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(PopLayer(client)); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(PopLayer(service)); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending layered test\n");
+    }
+    return 0;
+}  /* main */
+
+/* nblayer.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/nonblock.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/nonblock.c
new file mode 100644
index 0000000..bacb1ce
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/nonblock.c
@@ -0,0 +1,257 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "prio.h"
+#include "prerror.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+#include "plerror.h"
+#include "obsolete/probslet.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUMBER_ROUNDS 5
+
+#if defined(WIN16)
+/*
+** Make win16 unit_time interval 300 milliseconds, others get 100
+*/
+#define UNIT_TIME  200       /* unit time in milliseconds */
+#elif defined(SYMBIAN)
+#define UNIT_TIME  5000      /* unit time in milliseconds */
+#else
+#define UNIT_TIME  100       /* unit time in milliseconds */
+#endif
+#define CHUNK_SIZE 10
+#undef USE_PR_SELECT         /* If defined, we use PR_Select.
+                              * If not defined, use PR_Poll instead. */
+
+#if defined(USE_PR_SELECT)
+#include "pprio.h"
+#endif
+
+static void PR_CALLBACK
+clientThreadFunc(void *arg)
+{
+    PRUintn port = (PRUintn)arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[CHUNK_SIZE];
+    int i;
+    PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
+    PRSocketOptionData optval;
+    PRStatus retVal;
+    PRInt32 nBytes;
+
+    /* Initialize the buffer so that Purify won't complain */
+    memset(buf, 0, sizeof(buf));
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons((PRUint16)port);
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);
+
+    /* time 1 */
+    PR_Sleep(unitTime);
+    sock = PR_NewTCPSocket();
+    optval.option = PR_SockOpt_Nonblocking;
+    optval.value.non_blocking = PR_TRUE;
+    PR_SetSocketOption(sock, &optval);
+    retVal = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+    if (retVal == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
+#if !defined(USE_PR_SELECT)
+	PRPollDesc pd;
+	PRInt32 n;
+	fprintf(stderr, "connect: EWOULDBLOCK, good\n");
+	pd.fd = sock;
+	pd.in_flags = PR_POLL_WRITE;
+	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(n == 1);
+        PR_ASSERT(pd.out_flags == PR_POLL_WRITE);
+#else
+        PR_fd_set writeSet;
+        PRInt32 n;
+        fprintf(stderr, "connect: EWOULDBLOCK, good\n");
+        PR_FD_ZERO(&writeSet);
+        PR_FD_SET(sock, &writeSet);
+        n = PR_Select(0, NULL, &writeSet, NULL, PR_INTERVAL_NO_TIMEOUT);
+        PR_ASSERT(n == 1);
+        PR_ASSERT(PR_FD_ISSET(sock, &writeSet));
+#endif
+    }
+    printf("client connected\n");
+    fflush(stdout);
+
+    /* time 4, 7, 11, etc. */
+    for (i = 0; i < NUMBER_ROUNDS; i++) {
+        PR_Sleep(3 * unitTime);
+    	nBytes = PR_Write(sock, buf, sizeof(buf));
+	    if (nBytes == -1) {
+	    if (PR_GetError() == PR_WOULD_BLOCK_ERROR) {
+		fprintf(stderr, "write: EWOULDBLOCK\n");
+		exit(1);
+            } else {
+		fprintf(stderr, "write: failed\n");
+            }
+	}
+	printf("client sent %d bytes\n", nBytes);
+	fflush(stdout);
+    }
+
+    PR_Close(sock);
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+    PRFileDesc *listenSock, *sock;
+    PRUint16 listenPort;
+    PRNetAddr addr;
+    char buf[CHUNK_SIZE];
+    PRThread *clientThread;
+    PRInt32 retVal;
+    PRSocketOptionData optval;
+    PRIntn i;
+    PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
+
+    /* Create a listening socket */
+    if ((listenSock = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	exit(1);
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	exit(1);
+    }
+    listenPort = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	exit(1);
+    }
+
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on port %hu\n\n",
+	    listenPort);
+    printf("%s", buf);
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    printf("client thread created.\n");
+
+    optval.option = PR_SockOpt_Nonblocking;
+    optval.value.non_blocking = PR_TRUE;
+    PR_SetSocketOption(listenSock, &optval);
+    /* time 0 */
+    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (sock != NULL || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+        PL_PrintError("First Accept\n");
+        fprintf(stderr, "First PR_Accept() xxx\n" );
+		    exit(1);
+    }
+    printf("accept: EWOULDBLOCK, good\n");
+    fflush(stdout);
+    /* time 2 */
+    PR_Sleep(2 * unitTime);
+    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (sock == NULL) {
+        PL_PrintError("Second Accept\n");
+        fprintf(stderr, "Second PR_Accept() failed: (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+		    exit(1);
+    }
+    printf("accept: succeeded, good\n");
+    fflush(stdout);
+    PR_Close(listenSock);
+
+    PR_SetSocketOption(sock, &optval);
+
+    /* time 3, 5, 6, 8, etc. */
+    for (i = 0; i < NUMBER_ROUNDS; i++) {
+	PR_Sleep(unitTime);
+	retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+	if (retVal != -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+        PL_PrintError("First Receive:\n");
+	    fprintf(stderr, "First PR_Recv: retVal: %ld, Error: %ld\n",
+            retVal, PR_GetError());
+	    exit(1);
+        }
+	printf("read: EWOULDBLOCK, good\n");
+	fflush(stdout);
+	PR_Sleep(2 * unitTime);
+	retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+	if (retVal != CHUNK_SIZE) {
+        PL_PrintError("Second Receive:\n");
+	    fprintf(stderr, "Second PR_Recv: retVal: %ld, Error: %ld\n", 
+            retVal, PR_GetError());
+	    exit(1);
+        }
+	printf("read: %d bytes, good\n", retVal);
+	fflush(stdout);
+    }
+    PR_Close(sock);
+
+    printf("All tests finished\n");
+    printf("PASS\n");
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/ntioto.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ntioto.c
new file mode 100644
index 0000000..4fb175a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ntioto.c
@@ -0,0 +1,318 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: ntioto.c
+** Description: 
+** This test, ntioto.c, was designed to reproduce a bug reported by NES
+** on WindowsNT (fibers implementation). NSPR was asserting in ntio.c
+** after PR_AcceptRead() had timed out. I/O performed subsequent to the
+** call to PR_AcceptRead() could complete on a CPU other than the one
+** on which it was started. The assert in ntio.c detected this, then
+** asserted.
+**
+** Design:
+** This test will fail with an assert in ntio.c if the problem it was
+** designed to catch occurs. It returns 0 otherwise.
+** 
+** The main() thread initializes and tears things down. A file is
+** opened for writing; this file will be written to by AcceptThread()
+** and JitterThread().  Main() creates a socket for reading, listens
+** and binds the socket.
+** 
+** ConnectThread() connects to the socket created by main, then polls
+** the "state" variable. When state is AllDone, ConnectThread() exits.
+**
+** AcceptThread() calls PR_AcceptRead() on the socket. He fully expects
+** it to time out. After the timeout, AccpetThread() interacts with
+** JitterThread() via a common condition variable and the state
+** variable. The two threads ping-pong back and forth, each thread
+** writes the the file opened by main. This should provoke the
+** condition reported by NES (if we didn't fix it).
+**
+** The failure is not solid. It may fail within a few ping-pongs between
+** AcceptThread() and JitterThread() or may take a while. The default
+** iteration count, jitter, is set by DEFAULT_JITTER. This may be
+** modified at the command line with the -j option.
+** 
+*/
+
+#include <plgetopt.h> 
+#include <nspr.h> 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn  debug = 0;
+PRIntn  verbose = 0;
+PRUint32  failed_already = 0;
+/* end Test harness infrastructure */
+
+/* JITTER_DEFAULT: the number of times AcceptThread() and JitterThread() ping-pong */
+#define JITTER_DEFAULT  100000
+#define BASE_PORT 9867
+
+PRIntervalTime timeout;
+PRNetAddr   listenAddr;
+PRFileDesc  *listenSock;
+PRLock      *ml;
+PRCondVar   *cv;
+volatile enum  {
+    RunJitter,
+    RunAcceptRead,
+    AllDone
+} state = RunAcceptRead;
+PRFileDesc  *file1;
+PRIntn  iCounter = 0;
+PRIntn  jitter = JITTER_DEFAULT;
+PRBool  resume = PR_FALSE;
+
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+    printf("Template: Help(): display your help message(s) here");
+    exit(1);
+} /* end Help() */
+
+
+/*
+** static computation of PR_AcceptRead() buffer size.
+*/
+#define ACCEPT_READ_DATASIZE 10
+#define ACCEPT_READ_BUFSIZE (PR_ACCEPT_READ_BUF_OVERHEAD + ACCEPT_READ_DATASIZE)
+
+static void AcceptThread(void *arg)
+{
+    PRIntn bytesRead;
+    char dataBuf[ACCEPT_READ_BUFSIZE];
+    PRFileDesc  *arSock;
+    PRNetAddr   *arAddr;
+
+    bytesRead = PR_AcceptRead( listenSock, 
+        &arSock,
+        &arAddr,
+        dataBuf,
+        ACCEPT_READ_DATASIZE,
+        PR_SecondsToInterval(1));
+
+    if ( bytesRead == -1 && PR_GetError() == PR_IO_TIMEOUT_ERROR ) {
+        if ( debug ) printf("AcceptRead timed out\n");
+    } else {
+        if ( debug ) printf("Oops! read: %d, error: %d\n", bytesRead, PR_GetError());
+    }
+
+    while( state != AllDone )  {
+        PR_Lock( ml );
+        while( state != RunAcceptRead )
+            PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT );
+        if ( ++iCounter >= jitter )
+            state = AllDone;
+        else
+            state = RunJitter;
+        if ( verbose ) printf(".");
+        PR_NotifyCondVar( cv );
+        PR_Unlock( ml );
+        PR_Write( file1, ".", 1 );
+    }
+
+    return;
+} /* end AcceptThread() */
+
+static void JitterThread(void *arg)
+{
+    while( state != AllDone )  {
+        PR_Lock( ml );
+        while( state != RunJitter && state != AllDone )
+            PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT );
+        if ( state != AllDone)
+            state = RunAcceptRead;
+        if ( verbose ) printf("+");
+        PR_NotifyCondVar( cv );
+        PR_Unlock( ml );
+        PR_Write( file1, "+", 1 );
+    }
+    return;
+} /* end Goofy() */
+
+static void ConnectThread( void *arg )
+{
+    PRStatus    rv;
+    PRFileDesc  *clientSock;
+    PRNetAddr   serverAddress;
+    clientSock = PR_NewTCPSocket();
+
+    PR_ASSERT(clientSock);
+
+    if ( resume ) {
+        if ( debug ) printf("pausing 3 seconds before connect\n");
+        PR_Sleep( PR_SecondsToInterval(3));
+    }
+
+    memset(&serverAddress, 0, sizeof(serverAddress));
+    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddress);
+    PR_ASSERT( PR_SUCCESS == rv );
+    rv = PR_Connect( clientSock, 
+        &serverAddress, 
+        PR_SecondsToInterval(1));
+    PR_ASSERT( PR_SUCCESS == rv );
+
+    /* that's all we do. ... Wait for the acceptread() to timeout */
+    while( state != AllDone )
+        PR_Sleep( PR_SecondsToInterval(1));
+    return;
+} /* end ConnectThread() */
+
+
+int main(int argc, char **argv)
+{
+    PRThread *tJitter;
+    PRThread *tAccept;
+    PRThread *tConnect;
+    PRStatus rv;
+    /* This test if valid for WinNT only! */
+
+#if !defined(WINNT)
+    return 0;
+#endif
+
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "hdrvj:");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_ERROR;
+                break;
+            case 'v':  /* verbose mode */
+                verbose = 1;
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+            case 'j':
+                jitter = atoi(opt->value);
+                if ( jitter == 0)
+                    jitter = JITTER_DEFAULT;
+                break;
+            case 'r':
+                resume = PR_TRUE;
+                break;
+            case 'h':  /* help message */
+			    Help();
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+
+    /* set concurrency */
+    PR_SetConcurrency( 4 );
+
+    /* setup thread synchronization mechanics */
+    ml = PR_NewLock();
+    cv = PR_NewCondVar( ml );
+
+    /* setup a tcp socket */
+    memset(&listenAddr, 0, sizeof(listenAddr));
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr);
+    PR_ASSERT( PR_SUCCESS == rv );
+
+    listenSock = PR_NewTCPSocket();
+    PR_ASSERT( listenSock );
+
+    rv = PR_Bind( listenSock, &listenAddr);
+    PR_ASSERT( PR_SUCCESS == rv );
+
+    rv = PR_Listen( listenSock, 5 );
+    PR_ASSERT( PR_SUCCESS == rv );
+
+    /* open a file for writing, provoke bug */
+    file1 = PR_Open("xxxTestFile", PR_CREATE_FILE | PR_RDWR, 666);
+
+    /* create Connect thread */
+    tConnect = PR_CreateThread(
+        PR_USER_THREAD, ConnectThread, NULL,
+        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+        PR_JOINABLE_THREAD, 0 );
+    PR_ASSERT( tConnect );
+
+    /* create jitter off thread */
+    tJitter = PR_CreateThread(
+        PR_USER_THREAD, JitterThread, NULL,
+        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+        PR_JOINABLE_THREAD, 0 );
+    PR_ASSERT( tJitter );
+
+    /* create acceptread thread */
+    tAccept = PR_CreateThread(
+        PR_USER_THREAD, AcceptThread, NULL,
+        PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+        PR_JOINABLE_THREAD, 0 );
+    PR_ASSERT( tAccept );
+
+    /* wait for all threads to quit, then terminate gracefully */
+    PR_JoinThread( tConnect );
+    PR_JoinThread( tAccept );
+    PR_JoinThread( tJitter );
+    PR_Close( listenSock );
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    PR_Close( file1 );
+    PR_Delete( "xxxTestFile");
+
+    /* test return and exit */
+    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end ntioto.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/ntoh.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ntoh.c
new file mode 100644
index 0000000..d6eb095
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ntoh.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * A test program for PR_htons, PR_ntohs, PR_htonl, PR_ntohl,
+ * PR_htonll, and PR_ntohll.
+ */
+
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Byte sequence in network byte order */
+static unsigned char bytes_n[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+/* Integers in host byte order */
+static PRUint16 s_h = 0x0102;
+static PRUint32 l_h = 0x01020304;
+static PRUint64 ll_h = LL_INIT(0x01020304, 0x05060708);
+
+int main(int argc, char **argv)
+{
+    union {
+        PRUint16 s;
+        PRUint32 l;
+        PRUint64 ll;
+        unsigned char bytes[8];
+    } un;
+
+    un.s = s_h;
+    printf("%u %u\n",
+        un.bytes[0], un.bytes[1]);
+    un.s = PR_htons(un.s);
+    printf("%u %u\n",
+        un.bytes[0], un.bytes[1]);
+    if (memcmp(un.bytes, bytes_n, 2)) {
+        fprintf(stderr, "PR_htons failed\n");
+        exit(1);
+    }
+    un.s = PR_ntohs(un.s);
+    printf("%u %u\n",
+        un.bytes[0], un.bytes[1]);
+    if (un.s != s_h) {
+        fprintf(stderr, "PR_ntohs failed\n");
+        exit(1);
+    }
+
+    un.l = l_h;
+    printf("%u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
+    un.l = PR_htonl(un.l);
+    printf("%u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
+    if (memcmp(un.bytes, bytes_n, 4)) {
+        fprintf(stderr, "PR_htonl failed\n");
+        exit(1);
+    }
+    un.l = PR_ntohl(un.l);
+    printf("%u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
+    if (un.l != l_h) {
+        fprintf(stderr, "PR_ntohl failed\n");
+        exit(1);
+    }
+
+    un.ll = ll_h;
+    printf("%u %u %u %u %u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
+        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
+    un.ll = PR_htonll(un.ll);
+    printf("%u %u %u %u %u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
+        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
+    if (memcmp(un.bytes, bytes_n, 8)) {
+        fprintf(stderr, "PR_htonll failed\n");
+        exit(1);
+    }
+    un.ll = PR_ntohll(un.ll);
+    printf("%u %u %u %u %u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
+        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
+    if (LL_NE(un.ll, ll_h)) {
+        fprintf(stderr, "PR_ntohll failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/obsints.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/obsints.c
new file mode 100644
index 0000000..bbe60f8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/obsints.c
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Test: obsints.c 
+ *
+ * Description: make sure that protypes.h defines the obsolete integer
+ * types intn, uintn, uint, int8, uint8, int16, uint16, int32, uint32,
+ * int64, and uint64.
+ */
+
+#include <stdio.h>
+
+#ifdef NO_NSPR_10_SUPPORT
+
+/* nothing to do */
+int main(int argc, char **argv)
+{
+    printf("PASS\n");
+    return 0;
+}
+
+#else /* NO_NSPR_10_SUPPORT */
+
+#include "prtypes.h"  /* which includes protypes.h */
+
+int main(int argc, char **argv)
+{
+    /*
+     * Compilation fails if any of these integer types are not
+     * defined by protypes.h.
+     */
+    intn in;
+    uintn uin;
+    uint ui;
+    int8 i8;
+    uint8 ui8;
+    int16 i16;
+    uint16 ui16;
+    int32 i32;
+    uint32 ui32;
+    int64 i64;
+    uint64 ui64;
+
+    printf("PASS\n");
+    return 0;
+}
+
+#endif /* NO_NSPR_10_SUPPORT */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_2long.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_2long.c
new file mode 100644
index 0000000..deb55b7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_2long.c
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: op_2long.c
+**
+** Description: Test Program to verify the PR_NAME_TOO_LONG_ERROR
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+#include "plerror.h"
+#include "plgetopt.h"
+
+static PRFileDesc *t1;
+PRIntn error_code;
+
+/*
+ * should exceed any system's maximum file name length
+ * Note: was set at 4096. This is legal on some unix (Linux 2.1+) platforms.
+ * 
+ */
+#define TOO_LONG 5000
+
+int main(int argc, char **argv)
+{
+	char nameTooLong[TOO_LONG];
+	int i;
+
+	/* Generate a really long pathname */
+	for (i = 0; i < TOO_LONG - 1; i++) {
+		if (i % 10 == 0) {
+			nameTooLong[i] = '/';
+		} else {
+			nameTooLong[i] = 'a';
+		}
+	}
+	nameTooLong[TOO_LONG - 1] = 0;
+
+    PR_STDIO_INIT();
+	t1 = PR_Open(nameTooLong, PR_RDWR, 0666);
+	if (t1 == NULL) {
+		if (PR_GetError() == PR_NAME_TOO_LONG_ERROR) {
+            PL_PrintError("error code is");
+			printf ("PASS\n");
+			return 0;
+		}
+		else {
+            PL_PrintError("error code is");
+			printf ("FAIL\n");
+			return 1;
+		}
+	}
+	
+		else {
+			printf ("Test passed\n");
+			return 0;
+		}
+	
+
+
+}			
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_excl.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_excl.c
new file mode 100644
index 0000000..3040768
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_excl.c
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: op_excl.c
+**
+** Description: Test Program to verify function of PR_EXCL open flag
+**
+** Modification History:
+** 27-Oct-1999 lth. Initial version
+***********************************************************************/
+
+#include <plgetopt.h> 
+#include <nspr.h> 
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn  debug = 0;
+PRUint32  failed_already = 0;
+/* end Test harness infrastructure */
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+    printf("op_excl: Help");
+    printf("op_excl [-d]");
+    printf("-d enables debug messages");
+    exit(1);
+} /* end Help() */
+
+
+
+int main(int argc, char **argv)
+{
+    PRFileDesc  *fd;
+    PRStatus    rv;
+    PRInt32     written;
+    char        outBuf[] = "op_excl.c test file";
+#define OUT_SIZE sizeof(outBuf)
+#define NEW_FILENAME "xxxExclNewFile"
+
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "hd");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_ERROR;
+                break;
+            case 'h':  /* help message */
+			    Help();
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+
+    /*
+    ** First, open a file, PR_EXCL, we believe not to exist
+    */
+    fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 );
+    if ( NULL == fd )  {
+        if (debug) fprintf( stderr, "Open exclusive. Expected success, got failure\n");
+        failed_already = 1;
+        goto Finished;
+    }
+
+    written = PR_Write( fd, outBuf, OUT_SIZE );
+    if ( OUT_SIZE != written )  {
+        if (debug) fprintf( stderr, "Write after open exclusive failed\n");
+        failed_already = 1;
+        goto Finished;
+    }
+
+    rv = PR_Close(fd);
+    if ( PR_FAILURE == rv )  {
+        if (debug) fprintf( stderr, "Close after open exclusive failed\n");
+        failed_already = 1;
+        goto Finished;
+    }
+
+    /*
+    ** Second, open the same file, PR_EXCL, expect it to fail
+    */
+    fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 );
+    if ( NULL != fd )  {
+        if (debug) fprintf( stderr, "Open exclusive. Expected failure, got success\n");
+        failed_already = 1;
+        PR_Close(fd);
+    }
+
+    rv = PR_Delete( NEW_FILENAME );
+    if ( PR_FAILURE == rv ) {
+        if (debug) fprintf( stderr, "PR_Delete() failed\n");
+        failed_already = 1;
+    }
+
+Finished:
+    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end op_excl.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_filnf.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_filnf.c
new file mode 100644
index 0000000..c4cc48e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_filnf.c
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: op_filnf.c
+**
+** Description: Test Program to verify the PR_FILE_NOT_FOUND_ERROR
+**				This test program also uses the TRUNCATE option
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+#include "plgetopt.h"
+
+static PRFileDesc *t1;
+PRIntn error_code;
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+	t1 = PR_Open("/usr/tmp/ttools/err03.tmp", PR_TRUNCATE | PR_RDWR, 0666);
+	if (t1 == NULL) {
+		if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) {
+				printf ("error code is %d \n", PR_GetError());
+				printf ("PASS\n");
+				return 0;
+		}
+		else {
+				printf ("error code is %d \n", PR_GetError());
+				printf ("FAIL\n");
+			return 1;
+		}
+	}
+	PR_Close(t1);
+	printf ("opened a file that should not exist\n");
+	printf ("FAIL\n");
+	return 1;
+}			
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_filok.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_filok.c
new file mode 100644
index 0000000..3218c1f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_filok.c
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: op_filok.c
+**
+** Description: Test Program to verify the PR_Open finding an existing file.
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+
+/*
+ * The name of a file that is guaranteed to exist
+ * on every machine of a particular OS.
+ */
+#if defined(SYMBIAN)
+#define EXISTING_FILENAME "z:\\system\\install\\Series60v3.0.sis"
+#elif defined (XP_UNIX)
+#define EXISTING_FILENAME "/bin/sh"
+#elif defined(WINCE)
+#define EXISTING_FILENAME "/Windows/services.exe"
+#elif defined(WIN32)
+#define EXISTING_FILENAME "c:/autoexec.bat"
+#elif defined(OS2)
+#define EXISTING_FILENAME "c:/config.sys"
+#elif defined(BEOS)
+#define EXISTING_FILENAME "/boot/beos/bin/sh"
+#else
+#error "Unknown OS"
+#endif
+
+static PRFileDesc *t1;
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+
+	t1 = PR_Open(EXISTING_FILENAME, PR_RDONLY, 0666);
+
+	if (t1 == NULL) {
+		printf ("error code is %d \n", PR_GetError());
+		printf ("File %s should be found\n",
+				EXISTING_FILENAME);
+		return 1;
+	} else {
+		if (PR_Close(t1) == PR_SUCCESS) {
+			printf ("Test passed \n");
+			return 0;
+		} else {
+			printf ("cannot close file\n");
+			printf ("error code is %d\n", PR_GetError());
+			return 1;
+		}
+	}
+}			
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_noacc.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_noacc.c
new file mode 100644
index 0000000..2bc6256
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_noacc.c
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: op_noacc.c
+**
+** Description: Test Program to verify the PR_NO_ACCESS_RIGHTS_ERROR in PR_Open
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+#include "plgetopt.h"
+
+static PRFileDesc *err01;
+PRIntn error_code;
+
+int main(int argc, char **argv)
+{
+#ifdef XP_PC
+    printf("op_noacc: Test not valid on MS-Windows.\n\tNo concept of 'mode' on Open() call\n");
+    return(0);
+#endif
+
+	
+    PR_STDIO_INIT();
+	err01 = PR_Open("err01.tmp", PR_CREATE_FILE | PR_RDWR, 0);
+	if (err01 == NULL) 
+		if (PR_GetError() == PR_NO_ACCESS_RIGHTS_ERROR) {
+				printf ("error code is %d\n",PR_GetError());
+				printf ("PASS\n");
+			return 0;
+		}
+		else {
+			printf ("FAIL\n");
+			return 1;
+		}
+}			
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_nofil.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_nofil.c
new file mode 100644
index 0000000..fa7ed6d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/op_nofil.c
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: op_nofil.c
+**
+** Description: Test Program to verify the PR_FILE_NOT_FOUND_ERROR
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+#include "plgetopt.h"
+
+/*
+ * A file name that cannot exist
+ */
+#define NO_SUCH_FILE "/no/such/file.tmp"
+
+static PRFileDesc *t1;
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+	t1 = PR_Open(NO_SUCH_FILE,  PR_RDONLY, 0666);
+	if (t1 == NULL) {
+		if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) {
+			printf ("error code is PR_FILE_NOT_FOUND_ERROR, as expected\n");
+			printf ("PASS\n");
+			return 0;
+		} else {
+			printf ("error code is %d \n", PR_GetError());
+			printf ("FAIL\n");
+			return 1;
+		}
+	}
+	printf ("File %s exists on this machine!?\n", NO_SUCH_FILE);
+	if (PR_Close(t1) == PR_FAILURE) {
+		printf ("cannot close file\n");
+		printf ("error code is %d \n", PR_GetError());
+	}
+	printf ("FAIL\n");
+	return 1;
+}			
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/openfile.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/openfile.c
new file mode 100644
index 0000000..8d64a1a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/openfile.c
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This test calls PR_OpenFile to create a bunch of files
+ * with various file modes.
+ */
+
+#include "prio.h"
+#include "prerror.h"
+#include "prinit.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TEMPLATE_FILE_NAME "template.txt"
+
+int main(int argc, char **argv)
+{
+    FILE *template;
+    char buf[32];
+    PRInt32 nbytes;
+    PRFileDesc *fd;
+
+    
+    /* Write in text mode.  Let stdio deal with line endings. */
+    template = fopen(TEMPLATE_FILE_NAME, "w");
+    fputs("line 1\nline 2\n", template);
+    fclose(template);
+
+    /* Read in binary mode */
+    fd = PR_OpenFile(TEMPLATE_FILE_NAME, PR_RDONLY, 0666);
+    nbytes = PR_Read(fd, buf, sizeof(buf));
+    PR_Close(fd);
+    PR_Delete(TEMPLATE_FILE_NAME);
+
+    fd = PR_OpenFile("tfil0700.txt", PR_RDWR | PR_CREATE_FILE, 0700);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0500.txt", PR_RDWR | PR_CREATE_FILE, 0500);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0400.txt", PR_RDWR | PR_CREATE_FILE, 0400);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0644.txt", PR_RDWR | PR_CREATE_FILE, 0644);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0664.txt", PR_RDWR | PR_CREATE_FILE, 0664);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0660.txt", PR_RDWR | PR_CREATE_FILE, 0660);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0666.txt", PR_RDWR | PR_CREATE_FILE, 0666);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0640.txt", PR_RDWR | PR_CREATE_FILE, 0640);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    PR_Cleanup();
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/parent.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/parent.c
new file mode 100644
index 0000000..91bf5ee
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/parent.c
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** file:        parent.c
+** description: test the process machinery
+*/
+
+#include "prmem.h"
+#include "prprf.h"
+#include "prinit.h"
+#include "prproces.h"
+#include "prinrval.h"
+
+typedef struct Child
+{
+    const char *name;
+    char **argv;
+    PRProcess *process;
+    PRProcessAttr *attr;
+} Child;
+
+/* for the default test 'cvar -c 2000' */
+static char *default_argv[] = {"cvar", "-c", "2000", NULL};
+
+static void PrintUsage(void)
+{
+    PR_fprintf(PR_GetSpecialFD(PR_StandardError),
+        "Usage: parent [-d] child [options]\n");
+}
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+    PRInt32 test_status = 1;
+    PRIntervalTime t_start, t_elapsed;
+    PRFileDesc *debug = NULL;
+    Child *child = PR_NEWZAP(Child);
+
+    if (1 == argc)
+    {
+        /* no command-line arguments: run the default test */
+        child->argv = default_argv;
+    }
+    else
+    {
+        argv += 1;  /* don't care about our program name */
+        while (*argv != NULL && argv[0][0] == '-')
+        {
+            if (argv[0][1] == 'd')
+                debug = PR_GetSpecialFD(PR_StandardError);
+            else
+            {
+                PrintUsage();
+                return 2;  /* not sufficient */
+            }
+            argv += 1;
+        }
+        child->argv = argv;
+    }
+
+    if (NULL == *child->argv)
+    {
+        PrintUsage();
+        return 2;
+    }
+
+    child->name = *child->argv;
+    if (NULL != debug) PR_fprintf(debug, "Forking %s\n", child->name);
+
+    child->attr = PR_NewProcessAttr();
+    PR_ProcessAttrSetStdioRedirect(
+        child->attr, PR_StandardOutput,
+        PR_GetSpecialFD(PR_StandardOutput));
+    PR_ProcessAttrSetStdioRedirect(
+        child->attr, PR_StandardError,
+        PR_GetSpecialFD(PR_StandardError));
+
+    t_start = PR_IntervalNow();
+    child->process = PR_CreateProcess(
+        child->name, child->argv, NULL, child->attr);
+    t_elapsed = (PRIntervalTime) (PR_IntervalNow() - t_start);
+
+    PR_DestroyProcessAttr(child->attr);
+
+    test_status = (NULL == child->process) ? 1 : 0;
+    if (NULL != debug)
+    {
+        PR_fprintf(
+            debug, "Child was %sforked\n",
+            (0 == test_status) ? "" : "NOT ");
+        if (0 == test_status)
+            PR_fprintf(
+                debug, "PR_CreateProcess took %lu microseconds\n",
+                PR_IntervalToMicroseconds(t_elapsed));
+    }
+
+    if (0 == test_status)
+    {
+        if (NULL != debug) PR_fprintf(debug, "Waiting for child to exit\n");
+        rv = PR_WaitProcess(child->process, &test_status);
+        if (PR_SUCCESS == rv)
+        {
+            if (NULL != debug)
+                PR_fprintf(
+                    debug, "Child exited %s\n",
+                    (0 == test_status) ? "successfully" : "with error");
+        }
+        else
+        {
+            test_status = 1;
+            if (NULL != debug)
+                PR_fprintf(debug, "PR_WaitProcess failed\n");
+        }
+    }
+    PR_DELETE(child);
+    PR_Cleanup();
+    return test_status;
+    
+}  /* main */
+
+/* parent.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/parsetm.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/parsetm.c
new file mode 100644
index 0000000..21f0da8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/parsetm.c
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This test program should eventually become a full-blown test for
+ * PR_ParseTimeString.  Right now it just verifies that PR_ParseTimeString
+ * doesn't crash on an out-of-range time string (bug 480740).
+ */
+
+#include "prtime.h"
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRBool debug_mode = PR_TRUE;
+
+static char *dayOfWeek[] =
+	{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
+static char *month[] =
+	{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
+
+static void PrintExplodedTime(const PRExplodedTime *et) {
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
+	    et->tm_hour, et->tm_min, et->tm_sec);
+
+    /* Print time zone */
+    totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	if (debug_mode) printf("UTC ");
+    } else {
+        sign = "+";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        if (debug_mode) 
+            printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
+    }
+
+    /* Print year */
+    if (debug_mode) printf("%hd", et->tm_year);
+}
+
+int main(int argc, char **argv)
+{
+    PRTime ct;
+    PRExplodedTime et;
+    PRStatus rv;
+    char *sp1 = "Sat, 1 Jan 3001 00:00:00";  /* no time zone */
+    char *sp2 = "Fri, 31 Dec 3000 23:59:60";  /* no time zone, not normalized */
+
+#if _MSC_VER >= 1400 && !defined(WINCE)
+    /* Run this test in the US Pacific Time timezone. */
+    _putenv_s("TZ", "PST8PDT");
+    _tzset();
+#endif
+
+    rv = PR_ParseTimeString(sp1, PR_FALSE, &ct);
+    printf("rv = %d\n", rv);
+    PR_ExplodeTime(ct, PR_GMTParameters, &et);
+    PrintExplodedTime(&et);
+    printf("\n");
+
+    rv = PR_ParseTimeString(sp2, PR_FALSE, &ct);
+    printf("rv = %d\n", rv);
+    PR_ExplodeTime(ct, PR_GMTParameters, &et);
+    PrintExplodedTime(&et);
+    printf("\n");
+
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/peek.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/peek.c
new file mode 100644
index 0000000..22fcfec
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/peek.c
@@ -0,0 +1,392 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * A test case for the PR_MSG_PEEK flag of PR_Recv().
+ *
+ * Test both blocking and non-blocking sockets.
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BUFFER_SIZE 1024
+
+static int iterations = 10;
+
+/*
+ * In iteration i, recv_amount[i] is the number of bytes we
+ * wish to receive, and send_amount[i] is the number of bytes
+ * we actually send.  Therefore, the number of elements in the
+ * recv_amount or send_amount array should equal to 'iterations'.
+ * For this test to pass we need to ensure that
+ *     recv_amount[i] <= BUFFER_SIZE,
+ *     send_amount[i] <= BUFFER_SIZE,
+ *     send_amount[i] <= recv_amount[i].
+ */
+static PRInt32 recv_amount[10] = {
+    16, 128, 256, 1024, 512, 512, 128, 256, 32, 32};
+static PRInt32 send_amount[10] = {
+    16,  64, 128, 1024, 512, 256, 128,  64, 16, 32};
+
+/* Blocking I/O */
+static void ServerB(void *arg)
+{
+    PRFileDesc *listenSock = (PRFileDesc *) arg;
+    PRFileDesc *sock;
+    char buf[BUFFER_SIZE];
+    PRInt32 nbytes;
+    int i;
+    int j;
+
+    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == sock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+
+    for (i = 0; i < iterations; i++) {
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "server: peeked expected data\n");
+
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "server: peeked expected data\n");
+
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                0, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "server: received expected data\n");
+
+        PR_Sleep(PR_SecondsToInterval(1));
+        memset(buf, 2*i+1, send_amount[i]);
+        nbytes = PR_Send(sock, buf, send_amount[i],
+                0, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Send failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+    }
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+/* Non-blocking I/O */
+static void ClientNB(void *arg)
+{
+    PRFileDesc *sock;
+    PRSocketOptionData opt;
+    PRUint16 port = (PRUint16) arg;
+    PRNetAddr addr;
+    char buf[BUFFER_SIZE];
+    PRPollDesc pd;
+    PRInt32 npds;
+    PRInt32 nbytes;
+    int i;
+    int j;
+
+    sock = PR_OpenTCPSocket(PR_AF_INET6);
+    if (NULL == sock) {
+        fprintf(stderr, "PR_OpenTCPSocket failed\n");
+        exit(1);
+    }
+    opt.option = PR_SockOpt_Nonblocking;
+    opt.value.non_blocking = PR_TRUE;
+    if (PR_SetSocketOption(sock, &opt) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetSocketOption failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, port, &addr)
+            == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+        if (PR_GetError() != PR_IN_PROGRESS_ERROR) {
+            fprintf(stderr, "PR_Connect failed\n");
+            exit(1);
+        }
+        pd.fd = sock;
+        pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+        npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == npds) {
+            fprintf(stderr, "PR_Poll failed\n");
+            exit(1);
+        }
+        if (1 != npds) {
+            fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
+            exit(1);
+        }
+        if (PR_GetConnectStatus(&pd) == PR_FAILURE) {
+            fprintf(stderr, "PR_GetConnectStatus failed\n");
+            exit(1);
+        }
+    }
+
+    for (i = 0; i < iterations; i++) {
+        PR_Sleep(PR_SecondsToInterval(1));
+        memset(buf, 2*i, send_amount[i]);
+        while ((nbytes = PR_Send(sock, buf, send_amount[i],
+                0, PR_INTERVAL_NO_TIMEOUT)) == -1) {
+            if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+                fprintf(stderr, "PR_Send failed\n");
+                exit(1);
+            }
+            pd.fd = sock;
+            pd.in_flags = PR_POLL_WRITE;
+            npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+            if (-1 == npds) {
+                fprintf(stderr, "PR_Poll failed\n");
+                exit(1);
+            }
+            if (1 != npds) {
+                fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
+                exit(1);
+            }
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+
+        memset(buf, 0, sizeof(buf));
+        while ((nbytes = PR_Recv(sock, buf, recv_amount[i],
+                PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT)) == -1) {
+            if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+                fprintf(stderr, "PR_Recv failed\n");
+                exit(1);
+            }
+            pd.fd = sock;
+            pd.in_flags = PR_POLL_READ;
+            npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+            if (-1 == npds) {
+                fprintf(stderr, "PR_Poll failed\n");
+                exit(1);
+            }
+            if (1 != npds) {
+                fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
+                exit(1);
+            }
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i+1) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i+1, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "client: peeked expected data\n");
+
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i+1) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i+1, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "client: peeked expected data\n");
+
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                0, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i+1) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i+1, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "client: received expected data\n");
+    }
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+static void
+RunTest(PRThreadScope scope, PRFileDesc *listenSock, PRUint16 port)
+{
+    PRThread *server, *client;
+
+    server = PR_CreateThread(PR_USER_THREAD, ServerB, listenSock,
+            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == server) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    client = PR_CreateThread(
+            PR_USER_THREAD, ClientNB, (void *) port,
+            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == client) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+
+    if (PR_JoinThread(server) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(client) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock;
+    PRNetAddr addr;
+    PRUint16 port;
+
+    listenSock = PR_OpenTCPSocket(PR_AF_INET6);
+    if (NULL == listenSock) {
+        fprintf(stderr, "PR_OpenTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetSockName failed\n");
+        exit(1);
+    }
+    port = PR_ntohs(addr.ipv6.port);
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    fprintf(stderr, "Running the test with local threads\n");
+    RunTest(PR_LOCAL_THREAD, listenSock, port);
+    fprintf(stderr, "Running the test with global threads\n");
+    RunTest(PR_GLOBAL_THREAD, listenSock, port);
+
+    if (PR_Close(listenSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/perf.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/perf.c
new file mode 100644
index 0000000..4e2fc68
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/perf.c
@@ -0,0 +1,474 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int _debug_on = 0;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+#include "obsolete/prsem.h"
+
+PRLock *lock;
+PRMonitor *mon;
+PRMonitor *mon2;
+
+#define DEFAULT_COUNT    1000
+
+PRInt32 count;
+
+static void nop(int a, int b, int c)
+{
+}
+
+static void LocalProcedureCall(void)
+{
+    PRInt32 i;
+
+    for (i = 0; i < count; i++) {
+    nop(i, i, 5);
+    }
+}
+
+static void DLLProcedureCall(void)
+{
+    PRInt32 i;
+	PRThreadState state;
+	PRThread *self = PR_GetCurrentThread();
+
+    for (i = 0; i < count; i++) {
+    	state = PR_GetThreadState(self);
+    }
+}
+
+static void Now(void)
+{
+    PRInt32 i;
+    PRTime time;
+
+    for (i = 0; i < count; i++) {
+        time = PR_Now();
+    }
+}
+
+static void Interval(void)
+{
+    PRInt32 i;
+    PRIntervalTime time;
+
+    for (i = 0; i < count; i++) {
+        time = PR_IntervalNow();
+    }
+}
+
+static void IdleLock(void)
+{
+    PRInt32 i;
+
+    for (i = 0; i < count; i++) {
+    PR_Lock(lock);
+    PR_Unlock(lock);
+    }
+}
+
+static void IdleMonitor(void)
+{
+    PRInt32 i;
+
+    for (i = 0; i < count; i++) {
+    PR_EnterMonitor(mon);
+    PR_ExitMonitor(mon);
+    }
+}
+
+static void IdleCMonitor(void)
+{
+    PRInt32 i;
+
+    for (i = 0; i < count; i++) {
+    PR_CEnterMonitor((void*)7);
+    PR_CExitMonitor((void*)7);
+    }
+}
+
+/************************************************************************/
+
+static void PR_CALLBACK dull(void *arg)
+{
+}
+
+static void CDThread(void)
+{
+    PRInt32 i;
+    int num_threads = count;
+
+    /*
+     * Cannot create too many threads
+     */
+    if (num_threads > 1000)
+    num_threads = 1000;
+
+    for (i = 0; i < num_threads; i++) {
+        PRThread *t = PR_CreateThread(PR_USER_THREAD,
+                      dull, 0, 
+                      PR_PRIORITY_NORMAL,
+                      PR_LOCAL_THREAD,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+        if (NULL == t) {
+            fprintf(stderr, "CDThread: cannot create thread %3d\n", i);
+        } else {
+            DPRINTF(("CDThread: created thread %3d \n",i));
+        }
+        PR_Sleep(0);
+    }
+}
+
+static int alive;
+static int cxq;
+
+static void PR_CALLBACK CXReader(void *arg)
+{
+    PRInt32 i, n;
+
+    PR_EnterMonitor(mon);
+    n = count / 2;
+    for (i = 0; i < n; i++) {
+    while (cxq == 0) {
+            DPRINTF(("CXReader: thread = 0x%lx waiting\n",
+                    PR_GetCurrentThread()));
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+    --cxq;
+    PR_Notify(mon);
+    }
+    PR_ExitMonitor(mon);
+
+    PR_EnterMonitor(mon2);
+    --alive;
+    PR_Notify(mon2);
+    PR_ExitMonitor(mon2);
+    DPRINTF(("CXReader: thread = 0x%lx exiting\n", PR_GetCurrentThread()));
+}
+
+static void PR_CALLBACK CXWriter(void *arg)
+{
+    PRInt32 i, n;
+
+    PR_EnterMonitor(mon);
+    n = count / 2;
+    for (i = 0; i < n; i++) {
+    while (cxq == 1) {
+            DPRINTF(("CXWriter: thread = 0x%lx waiting\n",
+                    PR_GetCurrentThread()));
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+    ++cxq;
+    PR_Notify(mon);
+    }
+    PR_ExitMonitor(mon);
+
+    PR_EnterMonitor(mon2);
+    --alive;
+    PR_Notify(mon2);
+    PR_ExitMonitor(mon2);
+    DPRINTF(("CXWriter: thread = 0x%lx exiting\n", PR_GetCurrentThread()));
+}
+
+static void ContextSwitch(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *t1, *t2;
+
+    PR_EnterMonitor(mon2);
+    alive = 2;
+    cxq = 0;
+
+    t1 = PR_CreateThread(PR_USER_THREAD,
+                      CXReader, 0, 
+                      PR_PRIORITY_NORMAL,
+                      scope1,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+    if (NULL == t1) {
+        fprintf(stderr, "ContextSwitch: cannot create thread\n");
+    } else {
+        DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n",
+                (scope1 == PR_GLOBAL_THREAD ?
+                "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),
+                            t1));
+    }
+    t2 = PR_CreateThread(PR_USER_THREAD,
+                      CXWriter, 0, 
+                      PR_PRIORITY_NORMAL,
+                      scope2,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+    if (NULL == t2) {
+        fprintf(stderr, "ContextSwitch: cannot create thread\n");
+    } else {
+        DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n",
+                (scope2 == PR_GLOBAL_THREAD ?
+                "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),
+                            t2));
+    }
+
+    /* Wait for both of the threads to exit */
+    while (alive) {
+    PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_ExitMonitor(mon2);
+}
+
+static void ContextSwitchUU(void)
+{
+    ContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void ContextSwitchUK(void)
+{
+    ContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void ContextSwitchKU(void)
+{
+    ContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void ContextSwitchKK(void)
+{
+    ContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+/************************************************************************/
+
+static void PR_CALLBACK SemaThread(void *argSema)
+{
+    PRSemaphore **sem = (PRSemaphore **)argSema;
+    PRInt32 i, n;
+
+    n = count / 2;
+    for (i = 0; i < n; i++) {
+        DPRINTF(("SemaThread: thread = 0x%lx waiting on sem = 0x%lx\n",
+                PR_GetCurrentThread(), sem[0]));
+        PR_WaitSem(sem[0]);
+        DPRINTF(("SemaThread: thread = 0x%lx posting on sem = 0x%lx\n",
+                PR_GetCurrentThread(), sem[1]));
+        PR_PostSem(sem[1]);
+    }
+
+    PR_EnterMonitor(mon2);
+    --alive;
+    PR_Notify(mon2);
+    PR_ExitMonitor(mon2);
+    DPRINTF(("SemaThread: thread = 0x%lx exiting\n", PR_GetCurrentThread()));
+}
+
+static  PRSemaphore *sem_set1[2];
+static  PRSemaphore *sem_set2[2];
+
+static void SemaContextSwitch(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *t1, *t2;
+    sem_set1[0] = PR_NewSem(1);
+    sem_set1[1] = PR_NewSem(0);
+    sem_set2[0] = sem_set1[1];
+    sem_set2[1] = sem_set1[0];
+
+    PR_EnterMonitor(mon2);
+    alive = 2;
+    cxq = 0;
+
+    t1 = PR_CreateThread(PR_USER_THREAD,
+                      SemaThread, 
+                      sem_set1, 
+                      PR_PRIORITY_NORMAL,
+                      scope1,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+    if (NULL == t1) {
+        fprintf(stderr, "SemaContextSwitch: cannot create thread\n");
+    } else {
+        DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n",
+                (scope1 == PR_GLOBAL_THREAD ?
+                "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),
+                            t1));
+    }
+    t2 = PR_CreateThread(PR_USER_THREAD,
+                      SemaThread, 
+                      sem_set2, 
+                      PR_PRIORITY_NORMAL,
+                      scope2,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+    if (NULL == t2) {
+        fprintf(stderr, "SemaContextSwitch: cannot create thread\n");
+    } else {
+        DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n",
+                (scope2 == PR_GLOBAL_THREAD ?
+                "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),
+                            t2));
+    }
+
+    /* Wait for both of the threads to exit */
+    while (alive) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_ExitMonitor(mon2);
+
+    PR_DestroySem(sem_set1[0]);
+    PR_DestroySem(sem_set1[1]);
+}
+
+static void SemaContextSwitchUU(void)
+{
+    SemaContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void SemaContextSwitchUK(void)
+{
+    SemaContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void SemaContextSwitchKU(void)
+{
+    SemaContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void SemaContextSwitchKK(void)
+{
+    SemaContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow() - start;
+    d = (double)PR_IntervalToMicroseconds(stop);
+
+    printf("%40s: %6.2f usec\n", msg, d / count);
+}
+
+int main(int argc, char **argv)
+{
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 'c':  /* loop count */
+            count = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (0 == count) count = DEFAULT_COUNT;
+    
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+	PR_BlockClockInterrupts();
+	PR_UnblockClockInterrupts();
+    PR_STDIO_INIT();
+
+    lock = PR_NewLock();
+    mon = PR_NewMonitor();
+    mon2 = PR_NewMonitor();
+
+    Measure(LocalProcedureCall, "local procedure call overhead");
+    Measure(DLLProcedureCall, "DLL procedure call overhead");
+    Measure(Now, "current calendar time");
+    Measure(Interval, "interval time");
+    Measure(IdleLock, "idle lock lock/unlock pair");
+    Measure(IdleMonitor, "idle monitor entry/exit pair");
+    Measure(IdleCMonitor, "idle cache monitor entry/exit pair");
+    Measure(CDThread, "create/destroy thread pair");
+    Measure(ContextSwitchUU, "context switch - user/user");
+    Measure(ContextSwitchUK, "context switch - user/kernel");
+    Measure(ContextSwitchKU, "context switch - kernel/user");
+    Measure(ContextSwitchKK, "context switch - kernel/kernel");
+    Measure(SemaContextSwitchUU, "sema context switch - user/user");
+    Measure(SemaContextSwitchUK, "sema context switch - user/kernel");
+    Measure(SemaContextSwitchKU, "sema context switch - kernel/user");
+    Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel");
+
+    printf("--------------\n");
+    printf("Adding 7 additional CPUs\n");
+
+    PR_SetConcurrency(8);
+    printf("--------------\n");
+
+    Measure(LocalProcedureCall, "local procedure call overhead");
+    Measure(DLLProcedureCall, "DLL procedure call overhead");
+    Measure(Now, "current calendar time");
+    Measure(Interval, "interval time");
+    Measure(IdleLock, "idle lock lock/unlock pair");
+    Measure(IdleMonitor, "idle monitor entry/exit pair");
+    Measure(IdleCMonitor, "idle cache monitor entry/exit pair");
+    Measure(CDThread, "create/destroy thread pair");
+    Measure(ContextSwitchUU, "context switch - user/user");
+    Measure(ContextSwitchUK, "context switch - user/kernel");
+    Measure(ContextSwitchKU, "context switch - kernel/user");
+    Measure(ContextSwitchKK, "context switch - kernel/kernel");
+    Measure(SemaContextSwitchUU, "sema context switch - user/user");
+    Measure(SemaContextSwitchUK, "sema context switch - user/kernel");
+    Measure(SemaContextSwitchKU, "sema context switch - kernel/user");
+    Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel");
+
+    PR_DestroyLock(lock);
+    PR_DestroyMonitor(mon);
+    PR_DestroyMonitor(mon2);
+
+    PR_Cleanup();
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeping.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeping.c
new file mode 100644
index 0000000..494cca6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeping.c
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: pipeping.c
+ *
+ * Description:
+ * This test runs in conjunction with the pipepong test.
+ * This test creates two pipes and redirects the stdin and
+ * stdout of the pipepong test to the pipes.  Then this
+ * test writes "ping" to the pipepong test and the pipepong
+ * test writes "pong" back.  To run this pair of tests,
+ * just invoke pipeping.
+ *
+ * Tested areas: process creation, pipes, file descriptor
+ * inheritance, standard I/O redirection.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+#include "prproces.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_OS2
+static char *child_argv[] = { "pipepong.exe", NULL };
+#else
+static char *child_argv[] = { "pipepong", NULL };
+#endif
+
+#define NUM_ITERATIONS 10
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *in_pipe[2];
+    PRFileDesc *out_pipe[2];
+    PRStatus status;
+    PRProcess *process;
+    PRProcessAttr *attr;
+    char buf[1024];
+    PRInt32 nBytes;
+    PRInt32 exitCode;
+    int idx;
+
+    status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+    status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+
+    status = PR_SetFDInheritable(in_pipe[0], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(in_pipe[1], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(out_pipe[0], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(out_pipe[1], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+
+    attr = PR_NewProcessAttr();
+    if (attr == NULL) {
+        fprintf(stderr, "PR_NewProcessAttr failed\n");
+        exit(1);
+    }
+
+    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, out_pipe[0]);
+    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, in_pipe[1]);
+
+    process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
+    if (process == NULL) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+    PR_DestroyProcessAttr(attr);
+    status = PR_Close(out_pipe[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(in_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        strcpy(buf, "ping");
+        printf("ping process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(out_pipe[1], buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
+                    PR_GetOSError());
+            exit(1);
+        }
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(in_pipe[0], buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        printf("ping process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "pong") != 0) {
+            fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
+    status = PR_Close(in_pipe[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(out_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_WaitProcess(process, &exitCode);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exitCode == 0) {
+        printf("PASS\n");
+        return 0;
+    } else {
+        printf("FAIL\n");
+        return 1;
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeping2.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeping2.c
new file mode 100644
index 0000000..012b327
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeping2.c
@@ -0,0 +1,192 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: pipeping2.c
+ *
+ * Description:
+ * This test runs in conjunction with the pipepong2 test.
+ * This test creates two pipes and passes two pipe fd's
+ * to the pipepong2 test.  Then this test writes "ping" to
+ * to the pipepong2 test and the pipepong2 test writes "pong"
+ * back.  To run this pair of tests, just invoke pipeping2.
+ *
+ * Tested areas: process creation, pipes, file descriptor
+ * inheritance.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+#include "prproces.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+static char *child_argv[] = { "pipepong2", NULL };
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *in_pipe[2];
+    PRFileDesc *out_pipe[2];
+    PRStatus status;
+    PRProcess *process;
+    PRProcessAttr *attr;
+    char buf[1024];
+    PRInt32 nBytes;
+    PRInt32 exitCode;
+    int idx;
+
+    status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+    status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+
+    status = PR_SetFDInheritable(in_pipe[0], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(in_pipe[1], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(out_pipe[0], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(out_pipe[1], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+
+    attr = PR_NewProcessAttr();
+    if (attr == NULL) {
+        fprintf(stderr, "PR_NewProcessAttr failed\n");
+        exit(1);
+    }
+
+    status = PR_ProcessAttrSetInheritableFD(attr, out_pipe[0], "PIPE_READ");
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n");
+        exit(1);
+    }
+    status = PR_ProcessAttrSetInheritableFD(attr, in_pipe[1], "PIPE_WRITE");
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n");
+        exit(1);
+    }
+
+    process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
+    if (process == NULL) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+    PR_DestroyProcessAttr(attr);
+    status = PR_Close(out_pipe[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(in_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        strcpy(buf, "ping");
+        printf("ping process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(out_pipe[1], buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(in_pipe[0], buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed\n");
+            exit(1);
+        }
+        printf("ping process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "pong") != 0) {
+            fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
+    status = PR_Close(in_pipe[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(out_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_WaitProcess(process, &exitCode);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exitCode == 0) {
+        printf("PASS\n");
+        return 0;
+    } else {
+        printf("FAIL\n");
+        return 1;
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipepong.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipepong.c
new file mode 100644
index 0000000..19a7523
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipepong.c
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: pipepong.c
+ *
+ * Description:
+ * This test runs in conjunction with the pipeping test.
+ * The pipeping test creates two pipes and redirects the
+ * stdin and stdout of this test to the pipes.  Then the
+ * pipeping test writes "ping" to this test and this test
+ * writes "pong" back.  Note that this test does not depend
+ * on NSPR at all.  To run this pair of tests, just invoke
+ * pipeping.
+ *
+ * Tested areas: process creation, pipes, file descriptor
+ * inheritance, standard I/O redirection.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+int main(int argc, char **argv)
+{
+    char buf[1024];
+    size_t nBytes;
+    int idx;
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        memset(buf, 0, sizeof(buf));
+        nBytes = fread(buf, 1, 5, stdin);
+        fprintf(stderr, "pong process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "ping") != 0) {
+            fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+
+        strcpy(buf, "pong");
+        fprintf(stderr, "pong process: sending \"%s\"\n", buf);
+        nBytes = fwrite(buf, 1, 5, stdout);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong process: fwrite failed\n");
+            exit(1);
+        }
+        fflush(stdout);
+    }
+
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipepong2.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipepong2.c
new file mode 100644
index 0000000..aad1265
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipepong2.c
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: pipepong2.c
+ *
+ * Description:
+ * This test runs in conjunction with the pipeping2 test.
+ * The pipeping2 test creates two pipes and passes two
+ * pipe fd's to this test.  Then the pipeping2 test writes
+ * "ping" to this test and this test writes "pong" back.
+ * To run this pair of tests, just invoke pipeping2.
+ *
+ * Tested areas: process creation, pipes, file descriptor
+ * inheritance.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *pipe_read, *pipe_write;
+    PRStatus status;
+    char buf[1024];
+    PRInt32 nBytes;
+    int idx;
+
+    pipe_read = PR_GetInheritedFD("PIPE_READ");
+    if (pipe_read == NULL) {
+        fprintf(stderr, "PR_GetInheritedFD failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(pipe_read, PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    pipe_write = PR_GetInheritedFD("PIPE_WRITE");
+    if (pipe_write == NULL) {
+        fprintf(stderr, "PR_GetInheritedFD failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(pipe_write, PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(pipe_read, buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        printf("pong process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "ping") != 0) {
+            fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+
+        strcpy(buf, "pong");
+        printf("pong process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(pipe_write, buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed\n");
+            exit(1);
+        }
+    }
+
+    status = PR_Close(pipe_read);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(pipe_write);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeself.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeself.c
new file mode 100644
index 0000000..c6a620a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pipeself.c
@@ -0,0 +1,260 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: pipeself.c
+ *
+ * Description:
+ * This test has two threads communicating with each other using
+ * two unidirectional pipes.  The primordial thread is the ping
+ * thread and the other thread is the pong thread.  The ping
+ * thread writes "ping" to the pong thread and the pong thread
+ * writes "pong" back.
+ */
+
+#include "prio.h"
+#include "prerror.h"
+#include "prthread.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NUM_ITERATIONS 10
+
+static PRFileDesc *ping_in, *ping_out;
+static PRFileDesc *pong_in, *pong_out;
+
+static void PongThreadFunc(void *arg)
+{
+    char buf[1024];
+    int idx;
+    PRInt32 nBytes;
+    PRStatus status;
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(pong_in, buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed\n");
+            exit(1);
+        }
+        printf("pong thread: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong thread: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "ping") != 0) {
+            fprintf(stderr, "pong thread: expected \"ping\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+        strcpy(buf, "pong");
+        printf("pong thread: sending \"%s\"\n", buf);
+        nBytes = PR_Write(pong_out, buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
+                    PR_GetOSError());
+            exit(1);
+        }
+    }
+
+    status = PR_Close(pong_in);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(pong_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRStatus status;
+    PRThread *pongThread;
+    char buf[1024];
+    PRInt32 nBytes;
+    int idx;
+
+    status = PR_CreatePipe(&ping_in, &pong_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+    status = PR_CreatePipe(&pong_in, &ping_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+
+    pongThread = PR_CreateThread(PR_USER_THREAD, PongThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (pongThread == NULL) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        strcpy(buf, "ping");
+        printf("ping thread: sending \"%s\"\n", buf);
+        nBytes = PR_Write(ping_out, buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
+                    PR_GetOSError());
+            exit(1);
+        }
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(ping_in, buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed\n");
+            exit(1);
+        }
+        printf("ping thread: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "ping thread: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "pong") != 0) {
+            fprintf(stderr, "ping thread: expected \"pong\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
+    status = PR_Close(ping_in);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(ping_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_JoinThread(pongThread);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+	/*
+	 * Test PR_Available for pipes
+	 */
+    status = PR_CreatePipe(&ping_in, &ping_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+	nBytes = PR_Write(ping_out, buf, 250);
+	if (nBytes == -1) {
+		fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
+				PR_GetOSError());
+		exit(1);
+	}
+	nBytes = PR_Available(ping_in);
+	if (nBytes < 0) {
+		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
+				PR_GetOSError());
+		exit(1);
+	} else if (nBytes != 250) {
+		fprintf(stderr, "PR_Available: expected 250 bytes but got %d bytes\n",
+				nBytes);
+		exit(1);
+	}
+	printf("PR_Available: expected %d, got %d bytes\n",250, nBytes);
+	/* read some data */
+	nBytes = PR_Read(ping_in, buf, 7);
+	if (nBytes == -1) {
+		fprintf(stderr, "PR_Read failed\n");
+		exit(1);
+	}
+	/* check available data */
+	nBytes = PR_Available(ping_in);
+	if (nBytes < 0) {
+		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
+				PR_GetOSError());
+		exit(1);
+	} else if (nBytes != (250 - 7)) {
+		fprintf(stderr, "PR_Available: expected 243 bytes but got %d bytes\n",
+				nBytes);
+		exit(1);
+	}
+	printf("PR_Available: expected %d, got %d bytes\n",243, nBytes);
+	/* read all data */
+	nBytes = PR_Read(ping_in, buf, sizeof(buf));
+	if (nBytes == -1) {
+		fprintf(stderr, "PR_Read failed\n");
+		exit(1);
+	} else if (nBytes != 243) {
+		fprintf(stderr, "PR_Read failed: expected %d, got %d bytes\n",
+							243, nBytes);
+		exit(1);
+	}
+	/* check available data */
+	nBytes = PR_Available(ping_in);
+	if (nBytes < 0) {
+		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
+				PR_GetOSError());
+		exit(1);
+	} else if (nBytes != 0) {
+		fprintf(stderr, "PR_Available: expected 0 bytes but got %d bytes\n",
+				nBytes);
+		exit(1);
+	}
+	printf("PR_Available: expected %d, got %d bytes\n", 0, nBytes);
+
+    status = PR_Close(ping_in);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(ping_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+#endif /* XP_UNIX */
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_er.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_er.c
new file mode 100755
index 0000000..4a3d9cb
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_er.c
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: prpoll_err.c
+**
+** Description: This program tests PR_Poll with sockets.
+**              error reporting operation is tested
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+#ifdef XP_BEOS
+#include <stdio.h>
+int main()
+{
+    printf( "This test is not ported to the BeOS\n" );
+    return 0;
+}
+#else
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "primpl.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static void
+ClientThreadFunc(void *arg)
+{
+    PRFileDesc *badFD = (PRFileDesc *) arg;
+    /*
+     * Make the fd invalid
+     */
+#if defined(XP_UNIX)
+    close(PR_FileDesc2NativeHandle(badFD));
+#elif defined(XP_OS2)
+    soclose(PR_FileDesc2NativeHandle(badFD));
+#elif defined(WIN32) || defined(WIN16)
+    closesocket(PR_FileDesc2NativeHandle(badFD));
+#else
+#error "Unknown architecture"
+#endif
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *badFD;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    char buf[128];
+    PRPollDesc pds0[10], pds1[10], *pds, *other_pds;
+    PRIntn npds;
+    PRInt32 retVal;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Poll with sockets.\n");
+		printf("error reporting is  tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the poll descriptor array */
+    pds = pds0;
+    other_pds = pds1;
+    memset(pds, 0, sizeof(pds));
+    pds[0].fd = listenSock1;
+    pds[0].in_flags = PR_POLL_READ;
+    pds[1].fd = listenSock2;
+    pds[1].in_flags = PR_POLL_READ;
+    npds = 2;
+
+
+    /* Testing bad fd */
+    if (debug_mode) printf("PR_Poll should detect a bad file descriptor\n");
+    if ((badFD = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a TCP socket\n");
+	goto exit_now;
+    }
+
+    pds[2].fd = badFD;
+    pds[2].in_flags = PR_POLL_READ;
+    npds = 3;
+
+    if (PR_CreateThread(PR_USER_THREAD, ClientThreadFunc,
+            badFD, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD, 0) == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        exit(1);
+    }
+
+    retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
+    if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) {
+	fprintf(stderr, "Failed to detect the bad fd: "
+		"PR_Poll returns %d, out_flags is 0x%hx\n",
+		retVal, pds[2].out_flags);
+	failed_already=1;	
+	goto exit_now;
+    }
+    if (debug_mode) printf("PR_Poll detected the bad fd.  Test passed.\n\n");
+    PR_Cleanup();
+	goto exit_now;
+exit_now:
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}
+
+#endif /* XP_BEOS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_nm.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_nm.c
new file mode 100644
index 0000000..b2000b7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_nm.c
@@ -0,0 +1,377 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: prpoll_norm.c
+**
+** Description: This program tests PR_Poll with sockets.
+**              Normal operation are tested
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+#include "obsolete/probslet.h"
+
+#include "private/pprio.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+#define NUM_ITERATIONS 5
+
+static void PR_CALLBACK
+clientThreadFunc(void *arg)
+{
+    PRUintn port = (PRUintn) arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[128];
+    int i;
+    PRStatus sts;
+    PRInt32 n;
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons((PRUint16)port);
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    memset(buf, 0, sizeof(buf));
+    PR_snprintf(buf, sizeof(buf), "%hu", port);
+
+    for (i = 0; i < NUM_ITERATIONS; i++) {
+	sock = PR_NewTCPSocket();
+	PR_ASSERT(sock != NULL);
+	
+    sts = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(sts == PR_SUCCESS);
+
+	n = PR_Write(sock, buf, sizeof(buf));
+	PR_ASSERT(n >= 0);
+
+	sts = PR_Close(sock);
+	PR_ASSERT(sts == PR_SUCCESS);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    char buf[128];
+    PRThread *clientThread;
+    PRPollDesc pds0[20], pds1[20], *pds, *other_pds;
+    PRIntn npds;
+    PRInt32 retVal;
+    PRIntn i, j;
+    PRSocketOptionData optval;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Poll with sockets.\n");
+		printf("Normal operation are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    optval.option = PR_SockOpt_Nonblocking;
+    optval.value.non_blocking = PR_TRUE;
+    PR_SetSocketOption(listenSock1, &optval);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    PR_SetSocketOption(listenSock2, &optval);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the poll descriptor array */
+    pds = pds0;
+    other_pds = pds1;
+    memset(pds, 0, sizeof(pds));
+    pds[0].fd = listenSock1;
+    pds[0].in_flags = PR_POLL_READ;
+    pds[1].fd = listenSock2;
+    pds[1].in_flags = PR_POLL_READ;
+    /* Add some unused entries to test if they are ignored by PR_Poll() */
+    memset(&pds[2], 0, sizeof(pds[2]));
+    memset(&pds[3], 0, sizeof(pds[3]));
+    memset(&pds[4], 0, sizeof(pds[4]));
+    npds = 5;
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort1,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort2,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	failed_already=1;		
+	goto exit_now;
+    }
+
+    if (debug_mode) {
+		printf("Two client threads are created.  Each of them will\n");
+		printf("send data to one of the two ports the server is listening on.\n");
+		printf("The data they send is the port number.  Each of them send\n");
+		printf("the data five times, so you should see ten lines below,\n");
+		printf("interleaved in an arbitrary order.\n");
+	}
+
+    /* two clients, three events per iteration: accept, read, close */
+    i = 0;
+    while (i < 2 * 3 * NUM_ITERATIONS) {
+	PRPollDesc *tmp;
+	int nextIndex;
+	int nEvents = 0;
+
+	retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(retVal != 0);  /* no timeout */
+	if (retVal == -1) {
+	    fprintf(stderr, "PR_Poll failed\n");
+		failed_already=1;			
+	    goto exit_now;
+	}
+
+	nextIndex = 2;
+	/* the two listening sockets */
+	for (j = 0; j < 2; j++) {
+	    other_pds[j] = pds[j];
+	    PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
+		    && (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
+	    if (pds[j].out_flags & PR_POLL_READ) {
+		PRFileDesc *sock;
+
+		nEvents++;
+		sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT);
+		if (sock == NULL) {
+		    fprintf(stderr, "PR_Accept() failed\n");
+			failed_already=1;	
+		    goto exit_now;
+		}
+		other_pds[nextIndex].fd = sock;
+		other_pds[nextIndex].in_flags = PR_POLL_READ;
+		nextIndex++;
+	    } else if (pds[j].out_flags & PR_POLL_ERR) {
+		fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
+		failed_already=1;	
+		goto exit_now;
+	    } else if (pds[j].out_flags & PR_POLL_NVAL) {
+		fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n",
+			PR_FileDesc2NativeHandle(pds[j].fd));
+		failed_already=1;	
+		goto exit_now;
+	    }
+	}
+
+	for (j = 2; j < npds; j++) {
+            if (NULL == pds[j].fd) {
+                /*
+                 * Keep the unused entries in the poll descriptor array
+                 * for testing purposes.
+                 */
+                other_pds[nextIndex] = pds[j];
+                nextIndex++;
+                continue;
+            }
+
+	    PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
+		    && (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
+	    if (pds[j].out_flags & PR_POLL_READ) {
+                PRInt32 nAvail;
+		PRInt32 nRead;
+
+		nEvents++;
+                nAvail = PR_Available(pds[j].fd);
+		nRead = PR_Read(pds[j].fd, buf, sizeof(buf));
+                PR_ASSERT(nAvail == nRead);
+		if (nRead == -1) {
+		    fprintf(stderr, "PR_Read() failed\n");
+			failed_already=1;	
+		    goto exit_now;
+                } else if (nRead == 0) {
+                    PR_Close(pds[j].fd);
+                    continue;
+                } else {
+                    /* Just to be safe */
+                    buf[127] = '\0';
+                    if (debug_mode) printf("The server received \"%s\" from a client\n", buf);
+                }
+	    } else if (pds[j].out_flags & PR_POLL_ERR) {
+		fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
+		failed_already=1;			
+		goto exit_now;
+	    } else if (pds[j].out_flags & PR_POLL_NVAL) {
+		fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n");
+		failed_already=1;			
+		goto exit_now;
+	    }
+            other_pds[nextIndex] = pds[j];
+            nextIndex++;
+	}
+
+	PR_ASSERT(retVal == nEvents);
+	/* swap */
+	tmp = pds;
+	pds = other_pds;
+	other_pds = tmp;
+	npds = nextIndex;
+	i += nEvents;
+    }
+
+    if (debug_mode) printf("Tests passed\n");
+
+exit_now:
+
+    if (listenSock1) {
+        PR_Close(listenSock1);
+    }
+    if (listenSock2) {
+        PR_Close(listenSock2);
+    }
+
+    PR_Cleanup();
+	
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_to.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_to.c
new file mode 100644
index 0000000..e1a101f
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/poll_to.c
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: prpoll_to.c
+**
+** Description: This program tests PR_Poll with sockets.
+**              Timeout operation is tested
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+
+#include "private/pprio.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    char buf[128];
+    PRPollDesc pds0[10], pds1[10], *pds, *other_pds;
+    PRIntn npds;
+    PRInt32 retVal;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Poll with sockets.\n");
+		printf("Timeout is tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	if (!debug_mode)  failed_already=1;
+	goto exit_now;
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	if (!debug_mode)  failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	if (!debug_mode)  failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	if (!debug_mode)  failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the poll descriptor array */
+    pds = pds0;
+    other_pds = pds1;
+    memset(pds, 0, sizeof(pds));
+    pds[0].fd = listenSock1;
+    pds[0].in_flags = PR_POLL_READ;
+    pds[1].fd = listenSock2;
+    pds[1].in_flags = PR_POLL_READ;
+    npds = 2;
+
+    /* Testing timeout */
+    if (debug_mode) printf("PR_Poll should time out in 5 seconds\n");
+    retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5));
+    if (retVal != 0) {
+	PR_snprintf(buf, sizeof(buf),
+		"PR_Poll should time out and return 0, but it returns %ld\n",
+		retVal);
+	fprintf(stderr, "%s", buf);
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    if (debug_mode) printf("PR_Poll timed out.  Test passed.\n\n");
+
+exit_now:
+
+    if (listenSock1) {
+        PR_Close(listenSock1);
+    }
+    if (listenSock2) {
+        PR_Close(listenSock2);
+    }
+
+    PR_Cleanup();
+
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/pollable.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pollable.c
new file mode 100644
index 0000000..20da55a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/pollable.c
@@ -0,0 +1,293 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * A test for the pollable events.
+ *
+ * A number of threads are in a ring configuration, each waiting on
+ * a pollable event that is set by its upstream neighbor.
+ */
+
+#include "prinit.h"
+#include "prio.h"
+#include "prthread.h"
+#include "prerror.h"
+#include "prmem.h"
+#include "prlog.h"
+#include "prprf.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+#define DEFAULT_THREADS 10
+#define DEFAULT_LOOPS 100
+
+PRIntn numThreads = DEFAULT_THREADS;
+PRIntn numIterations = DEFAULT_LOOPS;
+PRIntervalTime dally = PR_INTERVAL_NO_WAIT;
+PRFileDesc *debug_out = NULL;
+PRBool debug_mode = PR_FALSE;
+PRBool verbosity = PR_FALSE;
+
+typedef struct ThreadData {
+    PRFileDesc *event;
+    int index;
+    struct ThreadData *next;
+} ThreadData;
+
+void ThreadRoutine(void *arg)
+{
+    ThreadData *data = (ThreadData *) arg;
+    PRIntn i;
+    PRPollDesc pd;
+    PRInt32 rv;
+
+    pd.fd = data->event;
+    pd.in_flags = PR_POLL_READ;
+
+    for (i = 0; i < numIterations; i++) {
+        rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+        if (rv == -1) {
+            PR_fprintf(PR_STDERR, "PR_Poll failed\n");
+            exit(1);
+        }
+        if (verbosity) {
+            PR_fprintf(debug_out, "thread %d awakened\n", data->index);
+        }
+        PR_ASSERT(rv != 0);
+        PR_ASSERT(pd.out_flags & PR_POLL_READ);
+        if (PR_WaitForPollableEvent(data->event) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "consume event failed\n");
+            exit(1);
+        }
+        if (dally != PR_INTERVAL_NO_WAIT) {
+            PR_Sleep(dally);
+        }
+        if (verbosity) {
+            PR_fprintf(debug_out, "thread %d posting event\n", data->index);
+        }
+        if (PR_SetPollableEvent(data->next->event) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "post event failed\n");
+            exit(1);
+        }
+    }
+}
+
+static void Help(void)
+{
+    debug_out = PR_STDOUT;
+
+    PR_fprintf(
+            debug_out, "Usage: pollable [-c n] [-t n] [-d] [-v] [-G] [-C n] [-D n]\n");
+    PR_fprintf(
+            debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
+    PR_fprintf(
+            debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
+    PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n");
+    PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
+    PR_fprintf(debug_out, "-D n\tdally setting (msecs) (default: 0)\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    ThreadData selfData;
+    ThreadData *data;
+    PRThread **thread;
+    void *block;
+    PRIntn i;
+    PRIntervalTime timeStart, timeEnd;
+    PRPollDesc pd;
+    PRInt32 rv;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRBool help = PR_FALSE;
+    PRUintn concurrency = 1;
+    PRUintn average;
+    PLOptStatus os;
+    PLOptState *opt;
+
+    PR_STDIO_INIT();
+
+    opt = PL_CreateOptState(argc, argv, "hdvc:t:C:GD:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) {
+            continue;
+        }
+        switch (opt->option) {
+            case 'v':  /* verbose mode */
+                verbosity = PR_TRUE;
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop counter */
+                numIterations = atoi(opt->value);
+                break;
+            case 't':  /* thread limit */
+                numThreads = atoi(opt->value);
+                break;
+            case 'C':  /* Concurrency limit */
+                concurrency = atoi(opt->value);
+                break;
+            case 'G':  /* global threads only */
+                thread_scope = PR_GLOBAL_THREAD;
+                break;
+            case 'D':  /* dally */
+                dally = PR_MillisecondsToInterval(atoi(opt->value));
+                break;
+            case 'h':  /* help message */
+                Help();
+                help = PR_TRUE;
+                break;
+            default:
+                break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (help) {
+        return 1;
+    }
+
+    if (concurrency > 1) {
+        PR_SetConcurrency(concurrency);
+    }
+
+    if (PR_TRUE == debug_mode) {
+        debug_out = PR_STDOUT;
+	PR_fprintf(debug_out, "Test parameters\n");
+        PR_fprintf(debug_out, "\tThreads involved: %d\n", numThreads);
+        PR_fprintf(debug_out, "\tIteration limit: %d\n", numIterations);
+        PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
+        PR_fprintf(debug_out, "\tThread type: %s\n",
+                (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
+    }
+
+    /*
+     * Malloc a block of memory and divide it into data and thread.
+     */
+    block = PR_MALLOC(numThreads * (sizeof(ThreadData) + sizeof(PRThread *)));
+    if (block == NULL) {
+        PR_fprintf(PR_STDERR, "cannot malloc, failed\n");
+        exit(1);
+    }
+    data = (ThreadData *) block;
+    thread = (PRThread **) &data[numThreads];
+
+    /* Pollable event */
+    selfData.event = PR_NewPollableEvent();
+    if (selfData.event == NULL) {
+        PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    selfData.next = &data[0];
+    for (i = 0; i < numThreads; i++) {
+        data[i].event = PR_NewPollableEvent();
+        if (data[i].event == NULL) {
+            PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        data[i].index = i;
+        if (i != numThreads - 1) {
+            data[i].next = &data[i + 1];
+        } else {
+            data[i].next = &selfData;
+        }
+
+        thread[i] = PR_CreateThread(PR_USER_THREAD,
+                ThreadRoutine, &data[i], PR_PRIORITY_NORMAL,
+                thread_scope, PR_JOINABLE_THREAD, 0);
+        if (thread[i] == NULL) {
+            PR_fprintf(PR_STDERR, "cannot create thread\n");
+            exit(1);
+        }
+    }
+
+    timeStart = PR_IntervalNow();
+    pd.fd = selfData.event;
+    pd.in_flags = PR_POLL_READ;
+    for (i = 0; i < numIterations; i++) {
+        if (dally != PR_INTERVAL_NO_WAIT) {
+            PR_Sleep(dally);
+        }
+        if (verbosity) {
+            PR_fprintf(debug_out, "main thread posting event\n");
+        }
+        if (PR_SetPollableEvent(selfData.next->event) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "set event failed\n");
+            exit(1);
+        }
+        rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+        if (rv == -1) {
+            PR_fprintf(PR_STDERR, "wait failed\n");
+            exit(1);
+        }
+        PR_ASSERT(rv != 0);
+        PR_ASSERT(pd.out_flags & PR_POLL_READ);
+        if (verbosity) {
+            PR_fprintf(debug_out, "main thread awakened\n");
+        }
+	if (PR_WaitForPollableEvent(selfData.event) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "consume event failed\n");
+            exit(1);
+        }
+    }
+    timeEnd = PR_IntervalNow();
+
+    if (debug_mode) {
+        average = PR_IntervalToMicroseconds(timeEnd - timeStart)
+                / (numIterations * numThreads);
+        PR_fprintf(debug_out, "Average switch times %d usecs for %d threads\n",
+                average, numThreads);
+    }
+
+    for (i = 0; i < numThreads; i++) {
+        if (PR_JoinThread(thread[i]) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "join thread failed\n");
+            exit(1);
+        }
+        PR_DestroyPollableEvent(data[i].event);
+    }
+    PR_DELETE(block);
+	PR_DestroyPollableEvent(selfData.event);
+
+    PR_fprintf(PR_STDOUT, "PASSED\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest.c
new file mode 100644
index 0000000..f89b27d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest.c
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:	prftest.c
+ * Description:
+ *     This is a simple test of the PR_snprintf() function defined
+ *     in prprf.c.
+ */
+
+#include "prlong.h"
+#include "prprf.h"
+
+#include <string.h>
+
+#define BUF_SIZE 128
+
+int main(int argc, char **argv)
+{
+    PRInt16 i16;
+    PRIntn n;
+    PRInt32 i32;
+    PRInt64 i64;
+    char buf[BUF_SIZE];
+    char answer[BUF_SIZE];
+    int i, rv = 0;
+
+    i16 = -1;
+    n = -1;
+    i32 = -1;
+    LL_I2L(i64, i32);
+
+    PR_snprintf(buf, BUF_SIZE, "%hx %x %lx %llx", i16, n, i32, i64);
+    strcpy(answer, "ffff ");
+    for (i = PR_BYTES_PER_INT * 2; i; i--) {
+		strcat(answer, "f");
+    }
+    strcat(answer, " ffffffff ffffffffffffffff");
+
+    if (!strcmp(buf, answer)) {
+		printf("PR_snprintf test 1 passed\n");
+    } else {
+		printf("PR_snprintf test 1 failed\n");
+		printf("Converted string is %s\n", buf);
+		printf("Should be %s\n", answer);
+		rv = 1;
+    }
+
+    i16 = -32;
+    n = 30;
+    i32 = 64;
+    LL_I2L(i64, 333);
+    PR_snprintf(buf, BUF_SIZE, "%d %hd %lld %ld", n, i16, i64, i32);
+    if (!strcmp(buf, "30 -32 333 64")) {
+		printf("PR_snprintf test 2 passed\n");
+    } else {
+		printf("PR_snprintf test 2 failed\n");
+		printf("Converted string is %s\n", buf);
+		printf("Should be 30 -32 333 64\n");
+		rv = 1;
+    }
+
+    return rv;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest1.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest1.c
new file mode 100644
index 0000000..1e59bf1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest1.c
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:	prftest1.c
+** Description:
+**     This is a simple test of the PR_snprintf() function defined
+**     in prprf.c.
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include "prttools.h"
+
+#include "prinit.h"
+#include "prlong.h"
+#include "prprf.h"
+
+#include <string.h>
+
+#define BUF_SIZE 128
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**				status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static void Test_Result (int result)
+{
+	if (result == PASS)
+		printf ("PASS\n");
+	else
+		printf ("FAIL\n");
+}
+
+int main(int argc, char **argv)
+{
+    PRInt16 i16;
+    PRIntn n;
+    PRInt32 i32;
+    PRInt64 i64;
+    char buf[BUF_SIZE];
+    char answer[BUF_SIZE];
+    int i;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	/* main test */
+    PR_STDIO_INIT();
+	
+    i16 = -1;
+    n = -1;
+    i32 = -1;
+    LL_I2L(i64, i32);
+
+    PR_snprintf(buf, BUF_SIZE, "%hx %x %lx %llx", i16, n, i32, i64);
+    strcpy(answer, "ffff ");
+    for (i = PR_BYTES_PER_INT * 2; i; i--) {
+	strcat(answer, "f");
+    }
+    strcat(answer, " ffffffff ffffffffffffffff");
+
+    if (!strcmp(buf, answer)) {
+	if (debug_mode) printf("PR_snprintf test 1 passed\n");
+	else Test_Result (PASS);
+    } else {
+		if (debug_mode) {
+			printf("PR_snprintf test 1 failed\n");
+			printf("Converted string is %s\n", buf);
+			printf("Should be %s\n", answer);
+		}
+		else
+			Test_Result (FAIL);
+    }
+
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest2.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest2.c
new file mode 100644
index 0000000..256266a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prftest2.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:	prftest2.c
+** Description:
+**     This is a simple test of the PR_snprintf() function defined
+**     in prprf.c.
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prlong.h"
+#include "prinit.h"
+#include "prprf.h"
+
+#include <string.h>
+
+#define BUF_SIZE 128
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char **argv)
+{
+    PRInt16 i16;
+    PRIntn n;
+    PRInt32 i32;
+    PRInt64 i64;
+    char buf[BUF_SIZE];
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	/* main test */
+	
+
+    PR_STDIO_INIT();
+    i16 = -32;
+    n = 30;
+    i32 = 64;
+    LL_I2L(i64, 333);
+    PR_snprintf(buf, BUF_SIZE, "%d %hd %lld %ld", n, i16, i64, i32);
+    if (!strcmp(buf, "30 -32 333 64")) {
+		if (debug_mode) printf("PR_snprintf test 2 passed\n");
+    } else {
+		if (debug_mode) {
+			printf("PR_snprintf test 2 failed\n");
+			printf("Converted string is %s\n", buf);
+			printf("Should be 30 -32 333 64\n");
+		}
+		else failed_already=1;
+    }
+	if(failed_already)
+	{
+        printf("FAILED\n");
+		return 1;
+	}
+	else
+	{
+        printf("PASSED\n");
+		return 0;
+	}
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/primblok.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/primblok.c
new file mode 100644
index 0000000..865ff11
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/primblok.c
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:        primblok.c
+ * Purpose:     testing whether the primordial thread can block in a
+ *              native blocking function without affecting the correct
+ *              functioning of NSPR I/O functions (Bugzilla bug #30746)
+ */
+
+#if !defined(WINNT)
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("This test is not relevant on this platform\n");
+    return 0;
+}
+
+#else /* WINNT */
+
+#include "nspr.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define TEST_FILE_NAME "primblok.dat"
+
+/* use InterlockedExchange to update this variable */
+static LONG iothread_done;
+
+static void PR_CALLBACK IOThread(void *arg)
+{
+    PRFileDesc *fd;
+    char buf[32];
+    PRInt32 nbytes;
+
+    /* Give the primordial thread one second to block */
+    Sleep(1000);
+
+    /*
+     * See if our PR_Write call will hang when the primordial
+     * thread is blocking in a native blocking function.
+     */
+    fd = PR_Open(TEST_FILE_NAME, PR_WRONLY|PR_CREATE_FILE, 0666);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_Open failed\n");
+        exit(1);
+    }
+    memset(buf, 0xaf, sizeof(buf));
+    fprintf(stderr, "iothread: calling PR_Write\n");
+    nbytes = PR_Write(fd, buf, sizeof(buf));
+    fprintf(stderr, "iothread: PR_Write returned\n");
+    if (nbytes != sizeof(buf)) {
+        fprintf(stderr, "PR_Write returned %d\n", nbytes);
+        exit(1);
+    }
+    if (PR_Close(fd) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_Delete failed\n");
+        exit(1);
+    }
+
+    /* Tell the main thread that we are done */
+    InterlockedExchange(&iothread_done, 1);
+}
+
+int main(int argc, char **argv)
+{
+    PRThread *iothread;
+
+    /* Must be a global thread */
+    iothread = PR_CreateThread(
+        PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL,
+        PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (iothread == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        exit(1);
+    }
+
+    /*
+     * Block in a native blocking function.
+     * Give iothread 5 seconds to finish its task.
+     */
+    Sleep(5000);
+
+    /*
+     * Is iothread done or is it hung?
+     *
+     * I'm actually only interested in reading the value
+     * of iothread_done.  I'm using InterlockedExchange as
+     * a thread-safe way to read iothread_done.
+     */
+    if (InterlockedExchange(&iothread_done, 1) == 0) {
+        fprintf(stderr, "iothread is hung\n");
+        fprintf(stderr, "FAILED\n");
+        exit(1);
+    }
+
+    if (PR_JoinThread(iothread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    printf("PASSED\n");
+    return 0;
+}  /* main */
+
+#endif /* WINNT */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/priotest.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/priotest.c
new file mode 100644
index 0000000..e08fb8a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/priotest.c
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:        priotest.c
+ * Purpose:     testing priorities
+ */
+
+#include "prcmon.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmon.h"
+#include "prprf.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DEFAULT_DURATION 5
+
+static PRBool failed = PR_FALSE;
+static PRIntervalTime oneSecond;
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE;
+
+static PRUint32 PerSecond(PRIntervalTime timein)
+{
+    PRUint32 loop = 0;
+    while (((PRIntervalTime)(PR_IntervalNow()) - timein) < oneSecond)
+        loop += 1;
+    return loop;
+}  /* PerSecond */
+
+static void PR_CALLBACK Low(void *arg)
+{
+    PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg;
+    while (1)
+    {
+        t0 = PerSecond(PR_IntervalNow());
+        *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8;
+        t3 = t2; t2 = t1; t1 = t0;
+    }
+}  /* Low */
+
+static void PR_CALLBACK High(void *arg)
+{
+    PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg;
+    while (1)
+    {
+        PRIntervalTime timein = PR_IntervalNow();
+        PR_Sleep(oneSecond >> 2);  /* 0.25 seconds */
+        t0 = PerSecond(timein);
+        *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8;
+        t3 = t2; t2 = t1; t1 = t0;
+    }
+}  /* High */
+
+static void Help(void)
+{
+    PR_fprintf(
+		debug_out, "Usage: priotest [-d] [-c n]\n");
+    PR_fprintf(
+		debug_out, "-c n\tduration of test in seconds (default: %d)\n", DEFAULT_DURATION);
+    PR_fprintf(
+        debug_out, "-d\tturn on debugging output (default: FALSE)\n");
+}  /* Help */
+
+static void RudimentaryTests(void)
+{
+    /*
+    ** Try some rudimentary tests like setting valid priority and
+    ** getting it back, or setting invalid priorities and getting
+    ** back a valid answer.
+    */
+    PRThreadPriority priority;
+    PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
+    priority = PR_GetThreadPriority(PR_GetCurrentThread());
+    failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority))
+        ? PR_TRUE : PR_FALSE;
+    if (debug_mode && (PR_PRIORITY_URGENT != priority))
+    {
+        PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n");
+    }
+
+
+    PR_SetThreadPriority(
+        PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1));
+    priority = PR_GetThreadPriority(PR_GetCurrentThread());
+    failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority))
+        ? PR_TRUE : PR_FALSE;
+    if (debug_mode && (PR_PRIORITY_FIRST != priority))
+    {
+        PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n");
+    }
+
+    PR_SetThreadPriority(
+        PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1));
+    priority = PR_GetThreadPriority(PR_GetCurrentThread());
+    failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority))
+        ? PR_TRUE : PR_FALSE;
+    if (debug_mode && (PR_PRIORITY_LAST != priority))
+    {
+        PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n");
+    }
+
+}  /* RudimentataryTests */
+
+static void CreateThreads(PRUint32 *lowCount, PRUint32 *highCount)
+{
+    (void)PR_CreateThread(
+        PR_USER_THREAD, Low, lowCount, PR_PRIORITY_LOW,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    (void)PR_CreateThread(
+        PR_USER_THREAD, High, highCount, PR_PRIORITY_HIGH,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+} /* CreateThreads */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    PRIntn duration = DEFAULT_DURATION;
+    PRUint32 totalCount, highCount = 0, lowCount = 0;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:");
+
+    debug_out = PR_STDOUT;
+    oneSecond = PR_SecondsToInterval(1);
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+        case 'c':  /* test duration */
+			duration = atoi(opt->value);
+            break;
+        case 'h':  /* help message */
+         default:
+			Help();
+			return 2;
+        }
+    }
+	PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+
+    if (duration == 0) duration = DEFAULT_DURATION;
+
+    RudimentaryTests();
+
+    printf("Priority test: running for %d seconds\n\n", duration);
+
+    (void)PerSecond(PR_IntervalNow());
+    totalCount = PerSecond(PR_IntervalNow());
+
+    PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
+
+    if (debug_mode)
+    {
+        PR_fprintf(debug_out,
+		    "The high priority thread should get approximately three\n");
+        PR_fprintf( debug_out,
+		    "times what the low priority thread manages. A maximum of \n");
+        PR_fprintf( debug_out, "%d cycles are available.\n\n", totalCount);
+    }
+
+    duration = (duration + 4) / 5;
+    CreateThreads(&lowCount, &highCount);
+    while (duration--)
+    {
+        PRIntn loop = 5;
+        while (loop--) PR_Sleep(oneSecond);
+        if (debug_mode)
+            PR_fprintf(debug_out, "high : low :: %d : %d\n", highCount, lowCount);
+    }
+
+
+    PR_ProcessExit((failed) ? 1 : 0);
+
+	PR_ASSERT(!"You can't get here -- but you did!");
+	return 1;  /* or here */
+
+}  /* main */
+
+/* priotest.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/provider.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/provider.c
new file mode 100644
index 0000000..0f56615
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/provider.c
@@ -0,0 +1,1386 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *
+ * Notes:
+ * [1] lth. The call to Sleep() is a hack to get the test case to run
+ * on Windows 95. Without it, the test case fails with an error
+ * WSAECONNRESET following a recv() call. The error is caused by the
+ * server side thread termination without a shutdown() or closesocket()
+ * call. Windows docmunentation suggests that this is predicted
+ * behavior; that other platforms get away with it is ... serindipity.
+ * The test case should shutdown() or closesocket() before
+ * thread termination. I didn't have time to figure out where or how
+ * to do it. The Sleep() call inserts enough delay to allow the
+ * client side to recv() all his data before the server side thread
+ * terminates. Whew! ...
+ *
+ ** Modification History:
+ * 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+ *             The debug mode will print all of the printfs associated with this test.
+ *             The regress mode will be the default mode. Since the regress tool limits
+ *           the output to a one line status:PASS or FAIL,all of the printf statements
+ *             have been handled with an if (debug_mode) statement. 
+ */
+
+#include "prclist.h"
+#include "prcvar.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prtime.h"
+#include "prmem.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prthread.h"
+
+#include "pprio.h"
+#include "primpl.h"
+
+#include "plstr.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(XP_UNIX)
+#include <math.h>
+#endif
+
+/*
+** This is the beginning of the test
+*/
+
+#define RECV_FLAGS 0
+#define SEND_FLAGS 0
+#define BUFFER_SIZE 1024
+#define DEFAULT_BACKLOG 5
+#define DEFAULT_PORT 13000
+#define DEFAULT_CLIENTS 1
+#define ALLOWED_IN_ACCEPT 1
+#define DEFAULT_CLIPPING 1000
+#define DEFAULT_WORKERS_MIN 1
+#define DEFAULT_WORKERS_MAX 1
+#define DEFAULT_SERVER "localhost"
+#define DEFAULT_EXECUTION_TIME 10
+#define DEFAULT_CLIENT_TIMEOUT 4000
+#define DEFAULT_SERVER_TIMEOUT 4000
+#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGH
+
+typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t;
+
+static void PR_CALLBACK Worker(void *arg);
+typedef struct CSPool_s CSPool_t;
+typedef struct CSWorker_s CSWorker_t;
+typedef struct CSServer_s CSServer_t;
+typedef enum Verbosity
+{
+    TEST_LOG_ALWAYS,
+    TEST_LOG_ERROR,
+    TEST_LOG_WARNING,
+    TEST_LOG_NOTICE,
+    TEST_LOG_INFO,
+    TEST_LOG_STATUS,
+    TEST_LOG_VERBOSE
+} Verbosity;
+
+static enum {
+    thread_nspr, thread_pthread, thread_sproc, thread_win32
+} thread_provider;
+
+static PRInt32 domain = AF_INET;
+static PRInt32 protocol = 6;  /* TCP */
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE;
+static PRBool pthread_stats = PR_FALSE;
+static Verbosity verbosity = TEST_LOG_ALWAYS;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+struct CSWorker_s
+{
+    PRCList element;        /* list of the server's workers */
+
+    PRThread *thread;       /* this worker objects thread */
+    CSServer_t *server;     /* back pointer to server structure */
+};
+
+struct CSPool_s
+{
+    PRCondVar *exiting;
+    PRCondVar *acceptComplete;
+    PRUint32 accepting, active, workers;
+};
+
+struct CSServer_s
+{
+    PRCList list;           /* head of worker list */
+
+    PRLock *ml;
+    PRThread *thread;       /* the main server thread */
+    PRCondVar *stateChange;
+
+    PRUint16 port;          /* port we're listening on */
+    PRUint32 backlog;       /* size of our listener backlog */
+    PRFileDesc *listener;   /* the fd accepting connections */
+
+    CSPool_t pool;          /* statistics on worker threads */
+    CSState_t state;        /* the server's state */
+    struct                  /* controlling worker counts */
+    {
+        PRUint32 minimum, maximum, accepting;
+    } workers;
+
+    /* statistics */
+    PRIntervalTime started, stopped;
+    PRUint32 operations, bytesTransferred;
+};
+
+typedef struct CSDescriptor_s
+{
+    PRInt32 size;       /* size of transfer */
+    char filename[60];  /* filename, null padded */
+} CSDescriptor_t;
+
+typedef struct CSClient_s
+{
+    PRLock *ml;
+    PRThread *thread;
+    PRCondVar *stateChange;
+    PRNetAddr serverAddress;
+
+    CSState_t state;
+
+    /* statistics */
+    PRIntervalTime started, stopped;
+    PRUint32 operations, bytesTransferred;
+} CSClient_t;
+
+#define TEST_LOG(l, p, a) \
+    do { \
+        if (debug_mode || (p <= verbosity)) printf a; \
+    } while (0)
+
+PRLogModuleInfo *cltsrv_log_file = NULL;
+
+#define MY_ASSERT(_expr) \
+    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))
+
+#define TEST_ASSERT(_expr) \
+    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))
+
+static void _MY_Assert(const char *s, const char *file, PRIntn ln)
+{
+    PL_PrintError(NULL);
+    PR_Assert(s, file, ln);
+}  /* _MY_Assert */
+
+static PRBool Aborted(PRStatus rv)
+{
+    return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ?
+        PR_TRUE : PR_FALSE;
+}
+
+static void TimeOfDayMessage(const char *msg, PRThread* me)
+{
+    char buffer[100];
+    PRExplodedTime tod;
+    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod);
+    (void)PR_FormatTime(buffer, sizeof(buffer), "%H:%M:%S", &tod);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("%s(0x%p): %s\n", msg, me, buffer));
+}  /* TimeOfDayMessage */
+
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRIntn index;
+    char buffer[1024];
+    PRFileDesc *fd = NULL;
+    PRUintn clipping = DEFAULT_CLIPPING;
+    CSClient_t *client = (CSClient_t*)arg;
+    PRThread *me = client->thread = PR_GetCurrentThread();
+    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
+    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT);
+
+
+    for (index = 0; index < sizeof(buffer); ++index)
+        buffer[index] = (char)index;
+
+    client->started = PR_IntervalNow();
+
+    PR_Lock(client->ml);
+    client->state = cs_run;
+    PR_NotifyCondVar(client->stateChange);
+    PR_Unlock(client->ml);
+
+    TimeOfDayMessage("Client started at", me);
+
+    while (cs_run == client->state)
+    {
+        PRInt32 bytes, descbytes, filebytes, netbytes;
+
+        (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer));
+        TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, 
+            ("\tClient(0x%p): connecting to server at %s\n", me, buffer));
+
+        fd = PR_Socket(domain, SOCK_STREAM, protocol);
+        TEST_ASSERT(NULL != fd);
+        rv = PR_Connect(fd, &client->serverAddress, timeout);
+        if (PR_FAILURE == rv)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tClient(0x%p): conection failed\n", me));
+            goto aborted;
+        }
+
+        memset(descriptor, 0, sizeof(*descriptor));
+        descriptor->size = PR_htonl(descbytes = rand() % clipping);
+        PR_snprintf(
+            descriptor->filename, sizeof(descriptor->filename),
+            "CS%p%p-%p.dat", client->started, me, client->operations);
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes));
+        bytes = PR_Send(
+            fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout);
+        if (sizeof(CSDescriptor_t) != bytes)
+        {
+            if (Aborted(PR_FAILURE)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\tClient(0x%p): send descriptor timeout\n", me));
+                goto retry;
+            }
+        }
+        TEST_ASSERT(sizeof(*descriptor) == bytes);
+
+        netbytes = 0;
+        while (netbytes < descbytes)
+        {
+            filebytes = sizeof(buffer);
+            if ((descbytes - netbytes) < filebytes)
+                filebytes = descbytes - netbytes;
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\tClient(0x%p): sending %d bytes\n", me, filebytes));
+            bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
+            if (filebytes != bytes)
+            {
+                if (Aborted(PR_FAILURE)) goto aborted;
+                if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                {
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): send data timeout\n", me));
+                    goto retry;
+                }
+            }
+            TEST_ASSERT(bytes == filebytes);
+            netbytes += bytes;
+        }
+        filebytes = 0;
+        while (filebytes < descbytes)
+        {
+            netbytes = sizeof(buffer);
+            if ((descbytes - filebytes) < netbytes)
+                netbytes = descbytes - filebytes;
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\tClient(0x%p): receiving %d bytes\n", me, netbytes));
+            bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
+            if (-1 == bytes)
+            {
+                if (Aborted(PR_FAILURE))
+                {
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive data aborted\n", me));
+                    goto aborted;
+                }
+                else if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive data timeout\n", me));
+				else
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive error (%d, %d)\n",
+						me, PR_GetError(), PR_GetOSError()));
+                goto retry;
+           }
+            if (0 == bytes)
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tClient(0x%p): unexpected end of stream\n",
+                    PR_GetCurrentThread()));
+                break;
+            }
+            filebytes += bytes;
+        }
+
+        rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+        if (Aborted(rv)) goto aborted;
+        TEST_ASSERT(PR_SUCCESS == rv);
+retry:
+        (void)PR_Close(fd); fd = NULL;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_INFO,
+            ("\tClient(0x%p): disconnected from server\n", me));
+
+        PR_Lock(client->ml);
+        client->operations += 1;
+        client->bytesTransferred += 2 * descbytes;
+        rv = PR_WaitCondVar(client->stateChange, rand() % clipping);
+        PR_Unlock(client->ml);
+        if (Aborted(rv)) break;
+    }
+
+aborted:
+    client->stopped = PR_IntervalNow();
+
+    PR_ClearInterrupt();
+    if (NULL != fd) rv = PR_Close(fd);
+
+    PR_Lock(client->ml);
+    client->state = cs_exit;
+    PR_NotifyCondVar(client->stateChange);
+    PR_Unlock(client->ml);
+    PR_DELETE(descriptor);
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("\tClient(0x%p): stopped after %u operations and %u bytes\n",
+        PR_GetCurrentThread(), client->operations, client->bytesTransferred));
+
+}  /* Client */
+
+static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
+{
+    PRStatus drv, rv;
+    char buffer[1024];
+    PRFileDesc *file = NULL;
+    PRThread * me = PR_GetCurrentThread();
+    PRInt32 bytes, descbytes, netbytes, filebytes = 0;
+    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
+    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\tProcessRequest(0x%p): receiving desciptor\n", me));
+    bytes = PR_Recv(
+        fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout);
+    if (-1 == bytes)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto exit;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tProcessRequest(0x%p): receive timeout\n", me));
+        }
+        goto exit;
+    }
+    if (0 == bytes)
+    {
+        rv = PR_FAILURE;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_ERROR,
+            ("\tProcessRequest(0x%p): unexpected end of file\n", me));
+        goto exit;
+    }
+    descbytes = PR_ntohl(descriptor->size);
+    TEST_ASSERT(sizeof(*descriptor) == bytes);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE, 
+        ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n",
+        me, descbytes, descriptor->filename));
+
+    file = PR_Open(
+        descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666);
+    if (NULL == file)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto aborted;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tProcessRequest(0x%p): open file timeout\n", me));
+            goto aborted;
+        }
+    }
+    TEST_ASSERT(NULL != file);
+
+    filebytes = 0;
+    while (filebytes < descbytes)
+    {
+        netbytes = sizeof(buffer);
+        if ((descbytes - filebytes) < netbytes)
+            netbytes = descbytes - filebytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes));
+        bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
+        if (-1 == bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): receive data timeout\n", me));
+                goto aborted;
+            }
+            /*
+             * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED)
+             * on NT here.  This is equivalent to ECONNRESET on Unix.
+             *     -wtc
+             */
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_WARNING,
+                ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n",
+                me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+        if(0 == bytes)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_WARNING,
+                ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me));
+            rv = PR_FAILURE;
+            goto aborted;
+        }
+        filebytes += bytes;
+        netbytes = bytes;
+        /* The byte count for PR_Write should be positive */
+        MY_ASSERT(netbytes > 0);
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes));
+        bytes = PR_Write(file, buffer, netbytes);
+        if (netbytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): write file timeout\n", me));
+                goto aborted;
+            }
+        }
+        TEST_ASSERT(bytes > 0);
+    }
+
+    PR_Lock(server->ml);
+    server->operations += 1;
+    server->bytesTransferred += filebytes;
+    PR_Unlock(server->ml);
+
+    rv = PR_Close(file); file = NULL;
+    if (Aborted(rv)) goto aborted;
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename));
+    file = PR_Open(descriptor->filename, PR_RDONLY, 0);
+    if (NULL == file)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto aborted;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\t\tProcessRequest(0x%p): open file timeout\n",
+                PR_GetCurrentThread()));
+            goto aborted;
+        }
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_ERROR,
+            ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n",
+            me, PR_GetError(), PR_GetOSError()));
+        goto aborted;
+    }
+    TEST_ASSERT(NULL != file);
+
+    netbytes = 0;
+    while (netbytes < descbytes)
+    {
+        filebytes = sizeof(buffer);
+        if ((descbytes - netbytes) < filebytes)
+            filebytes = descbytes - netbytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes));
+        bytes = PR_Read(file, buffer, filebytes);
+        if (filebytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): read file timeout\n", me));
+            else
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n",
+                    me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+        TEST_ASSERT(bytes > 0);
+        netbytes += bytes;
+        filebytes = bytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes));
+        bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
+        if (filebytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): send data timeout\n", me));
+                goto aborted;
+            }
+            break;
+        }
+       TEST_ASSERT(bytes > 0);
+    }
+    
+    PR_Lock(server->ml);
+    server->bytesTransferred += filebytes;
+    PR_Unlock(server->ml);
+
+    rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+    if (Aborted(rv)) goto aborted;
+
+    rv = PR_Close(file); file = NULL;
+    if (Aborted(rv)) goto aborted;
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+aborted:
+    PR_ClearInterrupt();
+    if (NULL != file) PR_Close(file);
+    drv = PR_Delete(descriptor->filename);
+    TEST_ASSERT(PR_SUCCESS == drv);
+exit:
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\t\tProcessRequest(0x%p): Finished\n", me));
+
+    PR_DELETE(descriptor);
+
+#if defined(WIN95)
+    PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */
+#endif
+    return rv;
+}  /* ProcessRequest */
+
+typedef void (*StartFn)(void*);
+typedef struct StartObject
+{
+    StartFn start;
+    void *arg;
+} StartObject;
+
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include "md/_pth.h"
+#include <pthread.h>
+
+static void *pthread_start(void *arg)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+    return NULL;
+}  /* pthread_start */
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+#include <sys/types.h>
+#include <sys/prctl.h>
+static void sproc_start(void *arg, PRSize size)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+}  /* sproc_start */
+#endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
+
+#if defined(WIN32)
+#include <process.h>  /* for _beginthreadex() */
+
+static PRUintn __stdcall windows_start(void *arg)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+    return 0;
+}  /* windows_start */
+#endif /* defined(WIN32) */
+
+static PRStatus JoinThread(PRThread *thread)
+{
+    PRStatus rv;
+    switch (thread_provider)
+    {
+    case thread_nspr:
+        rv = PR_JoinThread(thread);
+        break;
+    case thread_pthread:
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+        rv = PR_SUCCESS;
+        break;
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+    case thread_win32:
+#if defined(WIN32)
+        rv = PR_SUCCESS;
+        break;
+#endif
+    default:
+        rv = PR_FAILURE;
+        break;
+    }
+    return rv;    
+}  /* JoinThread */
+
+static PRStatus NewThread(
+    StartFn start, void *arg, PRThreadPriority prio, PRThreadState state)
+{
+    PRStatus rv;
+
+    switch (thread_provider)
+    {
+    case thread_nspr:
+        {
+            PRThread *thread = PR_CreateThread(
+                PR_USER_THREAD, start, arg,
+                PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+                PR_JOINABLE_THREAD, 0);
+            rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS;
+        }
+        break;
+    case thread_pthread:
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+        {
+            int rv;
+            pthread_t id;
+            pthread_attr_t tattr;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+
+            rv = _PT_PTHREAD_ATTR_INIT(&tattr);
+            PR_ASSERT(0 == rv);
+
+            rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+            PR_ASSERT(0 == rv);
+
+            rv = pthread_attr_setstacksize(&tattr, 64 * 1024);
+            PR_ASSERT(0 == rv);
+
+            rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object);
+            (void)_PT_PTHREAD_ATTR_DESTROY(&tattr);
+            return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+        break;
+
+    case thread_sproc:
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+        {
+            PRInt32 pid;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+            pid = sprocsp(
+                sproc_start, PR_SALL, start_object, NULL, 64 * 1024);
+            rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
+        break;
+    case thread_win32:
+#if defined(WIN32)
+        {
+            void *th;
+            PRUintn id;       
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+            th = (void*)_beginthreadex(
+                NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */  
+                0U, /* DWORD - initial thread stack size, in bytes */
+                windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */
+                start_object, /* LPVOID - argument for new thread */
+                0U, /*DWORD dwCreationFlags - creation flags */
+                &id /* LPDWORD - pointer to returned thread identifier */ );
+
+            rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif
+        break;
+    default:
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+    }
+    return rv;
+}  /* NewThread */
+
+static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool)
+{
+    PRStatus rv;
+    CSWorker_t *worker = PR_NEWZAP(CSWorker_t);
+    worker->server = server;
+    PR_INIT_CLIST(&worker->element);
+    rv = NewThread(
+        Worker, worker, DEFAULT_SERVER_PRIORITY, PR_UNJOINABLE_THREAD);
+    if (PR_FAILURE == rv) PR_DELETE(worker);
+
+    TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
+        ("\tCreateWorker(0x%p): create new worker (0x%p)\n",
+        PR_GetCurrentThread(), worker->thread));
+
+    return rv;
+}  /* CreateWorker */
+
+static void PR_CALLBACK Worker(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr from;
+    PRFileDesc *fd = NULL;
+    CSWorker_t *worker = (CSWorker_t*)arg;
+    CSServer_t *server = worker->server;
+    CSPool_t *pool = &server->pool;
+
+    PRThread *me = worker->thread = PR_GetCurrentThread();
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_NOTICE,
+        ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1));
+
+    PR_Lock(server->ml);
+    PR_APPEND_LINK(&worker->element, &server->list);
+    pool->workers += 1;  /* define our existance */
+
+    while (cs_run == server->state)
+    {
+        while (pool->accepting >= server->workers.accepting)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\t\tWorker(0x%p): waiting for accept slot[%d]\n",
+                me, pool->accepting));
+            rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT);
+            if (Aborted(rv) || (cs_run != server->state))
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_NOTICE,
+                    ("\tWorker(0x%p): has been %s\n",
+                    me, (Aborted(rv) ? "interrupted" : "stopped")));
+                goto exit;
+            }
+        } 
+        pool->accepting += 1;  /* how many are really in accept */
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\t\tWorker(0x%p): calling accept\n", me));
+        fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT);
+
+        PR_Lock(server->ml);        
+        pool->accepting -= 1;
+        PR_NotifyCondVar(pool->acceptComplete);
+
+        if ((NULL == fd) && Aborted(PR_FAILURE))
+        {
+            if (NULL != server->listener)
+            {
+                PR_Close(server->listener);
+                server->listener = NULL;
+            }
+            goto exit;
+        }
+
+        if (NULL != fd)
+        {
+            /*
+            ** Create another worker of the total number of workers is
+            ** less than the minimum specified or we have none left in
+            ** accept() AND we're not over the maximum.
+            ** This sort of presumes that the number allowed in accept
+            ** is at least as many as the minimum. Otherwise we'll keep
+            ** creating new threads and deleting them soon after.
+            */
+            PRBool another =
+                ((pool->workers < server->workers.minimum) ||
+                ((0 == pool->accepting)
+                    && (pool->workers < server->workers.maximum))) ?
+                    PR_TRUE : PR_FALSE;
+            pool->active += 1;
+            PR_Unlock(server->ml);
+
+            if (another) (void)CreateWorker(server, pool);
+
+            rv = ProcessRequest(fd, server);
+            if (PR_SUCCESS != rv)
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tWorker(0x%p): server process ended abnormally\n", me));
+            (void)PR_Close(fd); fd = NULL;
+
+            PR_Lock(server->ml);
+            pool->active -= 1;
+        }
+    }
+
+exit:
+    PR_ClearInterrupt();    
+    PR_Unlock(server->ml);
+
+    if (NULL != fd)
+    {
+        (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+        (void)PR_Close(fd);
+    }
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_NOTICE,
+        ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers));
+
+    PR_Lock(server->ml);
+    pool->workers -= 1;  /* undefine our existance */
+    PR_REMOVE_AND_INIT_LINK(&worker->element);
+    PR_NotifyCondVar(pool->exiting);
+    PR_Unlock(server->ml);
+
+    PR_DELETE(worker);  /* destruction of the "worker" object */
+
+}  /* Worker */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr serverAddress;
+    CSServer_t *server = (CSServer_t*)arg;
+    PRThread *me = server->thread = PR_GetCurrentThread();
+    PRSocketOptionData sockOpt;
+
+    server->listener = PR_Socket(domain, SOCK_STREAM, protocol);
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    rv = PR_SetSocketOption(server->listener, &sockOpt);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    memset(&serverAddress, 0, sizeof(serverAddress));
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress);
+
+    rv = PR_Bind(server->listener, &serverAddress);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    rv = PR_Listen(server->listener, server->backlog);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    server->started = PR_IntervalNow();
+    TimeOfDayMessage("Server started at", me);
+
+    PR_Lock(server->ml);
+    server->state = cs_run;
+    PR_NotifyCondVar(server->stateChange);
+    PR_Unlock(server->ml);
+
+    /*
+    ** Create the first worker (actually, a thread that accepts
+    ** connections and then processes the work load as needed).
+    ** From this point on, additional worker threads are created
+    ** as they are needed by existing worker threads.
+    */
+    rv = CreateWorker(server, &server->pool);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    /*
+    ** From here on this thread is merely hanging around as the contact
+    ** point for the main test driver. It's just waiting for the driver
+    ** to declare the test complete.
+    */
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\tServer(0x%p): waiting for state change\n", me));
+
+    PR_Lock(server->ml);
+    while ((cs_run == server->state) && !Aborted(rv))
+    {
+        rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(server->ml);
+    PR_ClearInterrupt();
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_INFO,
+        ("\tServer(0x%p): shutting down workers\n", me));
+
+    /*
+    ** Get all the worker threads to exit. They know how to
+    ** clean up after themselves, so this is just a matter of
+    ** waiting for clorine in the pool to take effect. During
+    ** this stage we're ignoring interrupts.
+    */
+    server->workers.minimum = server->workers.maximum = 0;
+
+    PR_Lock(server->ml);
+    while (!PR_CLIST_IS_EMPTY(&server->list))
+    {
+        PRCList *head = PR_LIST_HEAD(&server->list);
+        CSWorker_t *worker = (CSWorker_t*)head;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker));
+        rv = PR_Interrupt(worker->thread);
+        TEST_ASSERT(PR_SUCCESS == rv);
+        PR_REMOVE_AND_INIT_LINK(head);
+    }
+
+    while (server->pool.workers > 0)
+    {
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE,
+            ("\tServer(0x%p): waiting for %u workers to exit\n",
+            me, server->pool.workers));
+        (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    server->state = cs_exit;
+    PR_NotifyCondVar(server->stateChange);
+    PR_Unlock(server->ml);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("\tServer(0x%p): stopped after %u operations and %u bytes\n",
+        me, server->operations, server->bytesTransferred));
+
+    if (NULL != server->listener) PR_Close(server->listener);
+    server->stopped = PR_IntervalNow();
+
+}  /* Server */
+
+static void WaitForCompletion(PRIntn execution)
+{
+    while (execution > 0)
+    { 
+        PRIntn dally = (execution > 30) ? 30 : execution;
+        PR_Sleep(PR_SecondsToInterval(dally));
+        if (pthread_stats) PT_FPrintStats(debug_out, "\nPThread Statistics\n");
+        execution -= dally;
+    }
+}  /* WaitForCompletion */
+
+static void Help(void)
+{
+    PR_fprintf(debug_out, "cltsrv test program usage:\n");
+    PR_fprintf(debug_out, "\t-a <n>       threads allowed in accept        (5)\n");
+    PR_fprintf(debug_out, "\t-b <n>       backlock for listen              (5)\n");
+    PR_fprintf(debug_out, "\t-c <threads> number of clients to create      (1)\n");
+    PR_fprintf(debug_out, "\t-w <threads> minimal number of server threads (1)\n");
+    PR_fprintf(debug_out, "\t-W <threads> maximum number of server threads (1)\n");
+    PR_fprintf(debug_out, "\t-e <seconds> duration of the test in seconds  (10)\n");
+    PR_fprintf(debug_out, "\t-s <string>  dsn name of server               (localhost)\n");
+    PR_fprintf(debug_out, "\t-G           use GLOBAL threads               (LOCAL)\n");
+    PR_fprintf(debug_out, "\t-T <string>  thread provider ('n' | 'p' | 'w')(n)\n");
+    PR_fprintf(debug_out, "\t-X           use XTP as transport             (TCP)\n");
+    PR_fprintf(debug_out, "\t-6           Use IPv6                         (IPv4)\n");
+    PR_fprintf(debug_out, "\t-v           verbosity (accumulative)         (0)\n");
+    PR_fprintf(debug_out, "\t-p           pthread statistics               (FALSE)\n");
+    PR_fprintf(debug_out, "\t-d           debug mode                       (FALSE)\n");
+    PR_fprintf(debug_out, "\t-h           this message\n");
+}  /* Help */
+
+static Verbosity IncrementVerbosity(void)
+{
+    PRIntn verboge = (PRIntn)verbosity + 1;
+    return (Verbosity)verboge;
+}  /* IncrementVerbosity */
+
+int main(int argc, char **argv)
+{
+    PRUintn index;
+    PRBool boolean;
+    CSClient_t *client;
+    PRStatus rv, joinStatus;
+    CSServer_t *server = NULL;
+	char *thread_type;
+
+    PRUintn backlog = DEFAULT_BACKLOG;
+    PRUintn clients = DEFAULT_CLIENTS;
+    const char *serverName = DEFAULT_SERVER;
+    PRBool serverIsLocal = PR_TRUE;
+    PRUintn accepting = ALLOWED_IN_ACCEPT;
+    PRUintn workersMin = DEFAULT_WORKERS_MIN;
+    PRUintn workersMax = DEFAULT_WORKERS_MAX;
+    PRIntn execution = DEFAULT_EXECUTION_TIME;
+
+    /*
+     * -G           use global threads
+     * -a <n>       threads allowed in accept
+     * -b <n>       backlock for listen
+     * -c <threads> number of clients to create
+     * -w <threads> minimal number of server threads
+     * -W <threads> maximum number of server threads
+     * -e <seconds> duration of the test in seconds
+     * -s <string>  dsn name of server (implies no server here)
+     * -v           verbosity
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:w:W:e:s:T:vdhp");
+
+#if defined(WIN32)
+	thread_provider = thread_win32;
+#elif defined(_PR_PTHREADS)
+	thread_provider = thread_pthread;
+#elif defined(IRIX)
+	thread_provider = thread_sproc;
+#else
+    thread_provider = thread_nspr;
+#endif
+
+    debug_out = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'X':  /* use XTP as transport */
+            protocol = 36;
+            break;
+		case '6':  /* Use IPv6 */
+            domain = PR_AF_INET6;
+            break;
+        case 'a':  /* the value for accepting */
+            accepting = atoi(opt->value);
+            break;
+        case 'b':  /* the value for backlock */
+            backlog = atoi(opt->value);
+            break;
+        case 'T':  /* the thread provider */
+            if ('n' == *opt->value) thread_provider = thread_nspr;
+            else if ('p' == *opt->value) thread_provider = thread_pthread;
+            else if ('w' == *opt->value) thread_provider = thread_win32;
+            else {Help(); return 2; }
+            break;
+        case 'c':  /* number of client threads */
+            clients = atoi(opt->value);
+            break;
+        case 'w':  /* minimum server worker threads */
+            workersMin = atoi(opt->value);
+            break;
+        case 'W':  /* maximum server worker threads */
+            workersMax = atoi(opt->value);
+            break;
+        case 'e':  /* program execution time in seconds */
+            execution = atoi(opt->value);
+            break;
+        case 's':  /* server's address */
+            serverName = opt->value;
+            break;
+        case 'v':  /* verbosity */
+            verbosity = IncrementVerbosity();
+            break;
+        case 'd':  /* debug mode */
+            debug_mode = PR_TRUE;
+            break;
+        case 'p':  /* pthread mode */
+            pthread_stats = PR_TRUE;
+            break;
+        case 'h':
+        default:
+            Help();
+            return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE;
+    if (0 == execution) execution = DEFAULT_EXECUTION_TIME;
+    if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX;
+    if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN;
+    if (0 == accepting) accepting = ALLOWED_IN_ACCEPT;
+    if (0 == backlog) backlog = DEFAULT_BACKLOG;
+
+    if (workersMin > accepting) accepting = workersMin;
+
+    PR_STDIO_INIT();
+    TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread());
+
+    cltsrv_log_file = PR_NewLogModule("cltsrv_log");
+    MY_ASSERT(NULL != cltsrv_log_file);
+    boolean = PR_SetLogFile("cltsrv.log");
+    MY_ASSERT(boolean);
+
+    if (serverIsLocal)
+    {
+        /* Establish the server */
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_INFO,
+            ("main(0x%p): starting server\n", PR_GetCurrentThread()));
+
+        server = PR_NEWZAP(CSServer_t);
+        PR_INIT_CLIST(&server->list);
+        server->state = cs_init;
+        server->ml = PR_NewLock();
+        server->backlog = backlog;
+        server->port = DEFAULT_PORT;
+        server->workers.minimum = workersMin;
+        server->workers.maximum = workersMax;
+        server->workers.accepting = accepting;
+        server->stateChange = PR_NewCondVar(server->ml);
+        server->pool.exiting = PR_NewCondVar(server->ml);
+        server->pool.acceptComplete = PR_NewCondVar(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE,
+            ("main(0x%p): creating server thread\n", PR_GetCurrentThread()));
+
+        rv = NewThread(
+            Server, server, PR_PRIORITY_HIGH, PR_JOINABLE_THREAD);
+        TEST_ASSERT(PR_SUCCESS == rv);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): waiting for server init\n", PR_GetCurrentThread()));
+
+        PR_Lock(server->ml);
+        while (server->state == cs_init)
+            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): server init complete (port #%d)\n",
+            PR_GetCurrentThread(), server->port));
+    }
+
+    if (clients != 0)
+    {
+        /* Create all of the clients */
+        PRHostEnt host;
+        char buffer[BUFFER_SIZE];
+        client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t));
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): creating %d client threads\n",
+            PR_GetCurrentThread(), clients));
+        
+        if (!serverIsLocal)
+        {
+            rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host);
+            if (PR_SUCCESS != rv)
+            {
+                PL_FPrintError(PR_STDERR, "PR_GetHostByName");
+                return 2;
+            }
+        }
+
+        for (index = 0; index < clients; ++index)
+        {
+            client[index].state = cs_init;
+            client[index].ml = PR_NewLock();
+            if (serverIsLocal)
+            {
+                (void)PR_InitializeNetAddr(
+                    PR_IpAddrLoopback, DEFAULT_PORT,
+                    &client[index].serverAddress);
+            }
+            else
+            {
+                (void)PR_EnumerateHostEnt(
+                    0, &host, DEFAULT_PORT, &client[index].serverAddress);
+            }
+            client[index].stateChange = PR_NewCondVar(client[index].ml);
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_INFO,
+                ("main(0x%p): creating client threads\n", PR_GetCurrentThread()));
+            rv = NewThread(
+                Client, &client[index], PR_PRIORITY_NORMAL, PR_JOINABLE_THREAD);
+            TEST_ASSERT(PR_SUCCESS == rv);
+            PR_Lock(client[index].ml);
+            while (cs_init == client[index].state)
+                PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
+            PR_Unlock(client[index].ml);
+        }
+    }
+
+    /* Then just let them go at it for a bit */
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("main(0x%p): waiting for execution interval (%d seconds)\n",
+        PR_GetCurrentThread(), execution));
+
+    WaitForCompletion(execution);
+
+    TimeOfDayMessage("Shutting down", PR_GetCurrentThread());
+
+    if (clients != 0)
+    {
+        for (index = 0; index < clients; ++index)
+        {
+            TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
+                ("main(0x%p): notifying client(0x%p) to stop\n",
+                PR_GetCurrentThread(), client[index].thread));
+
+            PR_Lock(client[index].ml);
+            if (cs_run == client[index].state)
+            {
+                client[index].state = cs_stop;
+                PR_Interrupt(client[index].thread);
+                while (cs_stop == client[index].state)
+                    PR_WaitCondVar(
+                        client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
+            }
+            PR_Unlock(client[index].ml);
+
+            TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, 
+                ("main(0x%p): joining client(0x%p)\n",
+                PR_GetCurrentThread(), client[index].thread));
+
+		    joinStatus = JoinThread(client[index].thread);
+		    TEST_ASSERT(PR_SUCCESS == joinStatus);
+            PR_DestroyCondVar(client[index].stateChange);
+            PR_DestroyLock(client[index].ml);
+        }
+        PR_DELETE(client);
+    }
+
+    if (NULL != server)
+    {
+        /* All clients joined - retrieve the server */
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE, 
+            ("main(0x%p): notifying server(0x%p) to stop\n",
+            PR_GetCurrentThread(), server->thread));
+
+        PR_Lock(server->ml);
+        server->state = cs_stop;
+        PR_Interrupt(server->thread);
+        while (cs_exit != server->state)
+            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE, 
+            ("main(0x%p): joining server(0x%p)\n",
+            PR_GetCurrentThread(), server->thread));
+        joinStatus = JoinThread(server->thread);
+        TEST_ASSERT(PR_SUCCESS == joinStatus);
+
+        PR_DestroyCondVar(server->stateChange);
+        PR_DestroyCondVar(server->pool.exiting);
+        PR_DestroyCondVar(server->pool.acceptComplete);
+        PR_DestroyLock(server->ml);
+        PR_DELETE(server);
+    }
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS, 
+        ("main(0x%p): test complete\n", PR_GetCurrentThread()));
+
+	if (thread_provider == thread_win32)
+		thread_type = "\nWin32 Thread Statistics\n";
+	else if (thread_provider == thread_pthread)
+		thread_type = "\npthread Statistics\n";
+	else if (thread_provider == thread_sproc)
+		thread_type = "\nsproc Statistics\n";
+    else {
+		PR_ASSERT(thread_provider == thread_nspr);
+		thread_type = "\nPRThread Statistics\nn";
+	}
+
+    PT_FPrintStats(debug_out, thread_type);
+
+    TimeOfDayMessage("Test exiting at", PR_GetCurrentThread());
+    PR_Cleanup();
+    return 0;
+}  /* main */
+
+/* cltsrv.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/prpoll.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prpoll.c
new file mode 100644
index 0000000..116a484
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prpoll.c
@@ -0,0 +1,383 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#ifdef XP_UNIX
+#include <unistd.h>  /* for close() */
+#endif
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+
+#include "private/pprio.h"
+
+#define CLIENT_LOOPS	5
+#define BUF_SIZE		128
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef WINCE
+
+int main(int argc, char **argv)
+{
+    fprintf(stderr, "Invalid/Broken Test for WinCE/WinMobile\n");
+    exit(1);
+}
+
+#else
+
+static void
+clientThreadFunc(void *arg)
+{
+    PRUint16 port = (PRUint16) arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[BUF_SIZE];
+    int i;
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons(port);
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    PR_snprintf(buf, sizeof(buf), "%hu", port);
+
+    for (i = 0; i < 5; i++) {
+	sock = PR_NewTCPSocket();
+        PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+
+	PR_Write(sock, buf, sizeof(buf));
+	PR_Close(sock);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *badFD;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    char buf[BUF_SIZE];
+    PRThread *clientThread;
+    PRPollDesc pds0[10], pds1[10], *pds, *other_pds;
+    PRIntn npds;
+    PRInt32 retVal;
+    PRInt32 rv;
+    PROsfd sd;
+    struct sockaddr_in saddr;
+    PRIntn saddr_len;
+    PRUint16 listenPort3;
+    PRFileDesc *socket_poll_fd;
+    PRIntn i, j;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    printf("This program tests PR_Poll with sockets.\n");
+    printf("Timeout, error reporting, and normal operation are tested.\n\n");
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	exit(1);
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	exit(1);
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	exit(1);
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	exit(1);
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	exit(1);
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	exit(1);
+    }
+    /* Set up the poll descriptor array */
+    pds = pds0;
+    other_pds = pds1;
+    memset(pds, 0, sizeof(pds));
+	npds = 0;
+    pds[npds].fd = listenSock1;
+    pds[npds].in_flags = PR_POLL_READ;
+	npds++;
+    pds[npds].fd = listenSock2;
+    pds[npds].in_flags = PR_POLL_READ;
+	npds++;
+
+	sd = socket(AF_INET, SOCK_STREAM, 0);
+	PR_ASSERT(sd >= 0);
+	memset((char *) &saddr, 0, sizeof(saddr));
+	saddr.sin_family = AF_INET;
+	saddr.sin_addr.s_addr = htonl(INADDR_ANY);
+	saddr.sin_port = htons(0);
+
+	rv = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr));
+	PR_ASSERT(rv == 0);
+	saddr_len = sizeof(saddr);
+	rv = getsockname(sd, (struct sockaddr *) &saddr, &saddr_len);
+	PR_ASSERT(rv == 0);
+    listenPort3 = ntohs(saddr.sin_port);
+
+	rv = listen(sd, 5);
+	PR_ASSERT(rv == 0);
+    pds[npds].fd = socket_poll_fd = PR_CreateSocketPollFd(sd);
+	PR_ASSERT(pds[npds].fd);
+    pds[npds].in_flags = PR_POLL_READ;
+    npds++;
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu, %hu and %hu\n\n",
+	    listenPort1, listenPort2, listenPort3);
+    printf("%s", buf);
+
+    /* Testing timeout */
+    printf("PR_Poll should time out in 5 seconds\n");
+    retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5));
+    if (retVal != 0) {
+	PR_snprintf(buf, sizeof(buf),
+		"PR_Poll should time out and return 0, but it returns %ld\n",
+		retVal);
+	fprintf(stderr, "%s", buf);
+	exit(1);
+    }
+    printf("PR_Poll timed out.  Test passed.\n\n");
+
+    /* Testing bad fd */
+    printf("PR_Poll should detect a bad file descriptor\n");
+    if ((badFD = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a TCP socket\n");
+	exit(1);
+    }
+
+    pds[npds].fd = badFD;
+    pds[npds].in_flags = PR_POLL_READ;
+    npds++;
+    PR_Close(badFD);  /* make the fd bad */
+#if 0
+    retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
+    if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) {
+	fprintf(stderr, "Failed to detect the bad fd: "
+		"PR_Poll returns %d, out_flags is 0x%hx\n",
+		retVal, pds[npds - 1].out_flags);
+	exit(1);
+    }
+    printf("PR_Poll detected the bad fd.  Test passed.\n\n");
+#endif
+    npds--;
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort1,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort2,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort3,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+
+    printf("Three client threads are created.  Each of them will\n");
+    printf("send data to one of the three ports the server is listening on.\n");
+    printf("The data they send is the port number.  Each of them send\n");
+    printf("the data five times, so you should see ten lines below,\n");
+    printf("interleaved in an arbitrary order.\n");
+
+    /* 30 events total */
+    i = 0;
+    while (i < 30) {
+		PRPollDesc *tmp;
+		int nextIndex;
+		int nEvents = 0;
+
+		retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
+		PR_ASSERT(retVal != 0);  /* no timeout */
+		if (retVal == -1) {
+			fprintf(stderr, "PR_Poll failed\n");
+			exit(1);
+		}
+
+		nextIndex = 3;
+		/* the three listening sockets */
+		for (j = 0; j < 3; j++) {
+			other_pds[j] = pds[j];
+			PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
+				&& (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
+			if (pds[j].out_flags & PR_POLL_READ) {
+				PRFileDesc *sock;
+
+				nEvents++;
+				if (j == 2) {
+					PROsfd newsd;
+					newsd = accept(PR_FileDesc2NativeHandle(pds[j].fd), NULL, 0);
+					if (newsd == -1) {
+						fprintf(stderr, "accept() failed\n");
+						exit(1);
+					}
+					other_pds[nextIndex].fd  = PR_CreateSocketPollFd(newsd);
+					PR_ASSERT(other_pds[nextIndex].fd);
+					other_pds[nextIndex].in_flags = PR_POLL_READ;
+				} else {
+					sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT);
+					if (sock == NULL) {
+						fprintf(stderr, "PR_Accept() failed\n");
+						exit(1);
+					}
+					other_pds[nextIndex].fd = sock;
+					other_pds[nextIndex].in_flags = PR_POLL_READ;
+				}
+				nextIndex++;
+			} else if (pds[j].out_flags & PR_POLL_ERR) {
+				fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
+				exit(1);
+			} else if (pds[j].out_flags & PR_POLL_NVAL) {
+				fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n",
+					PR_FileDesc2NativeHandle(pds[j].fd));
+				exit(1);
+			}
+		}
+
+		for (j = 3; j < npds; j++) {
+			PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
+				&& (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
+			if (pds[j].out_flags & PR_POLL_READ) {
+				PRInt32 nBytes;
+
+				nEvents++;
+				/* XXX: This call is a hack and should be fixed */
+				if (PR_GetDescType(pds[j].fd) == (PRDescType) 0) {
+					nBytes = recv(PR_FileDesc2NativeHandle(pds[j].fd), buf,
+										sizeof(buf), 0);
+					if (nBytes == -1) {
+						fprintf(stderr, "recv() failed\n");
+						exit(1);
+					}
+					printf("Server read %d bytes from native fd %d\n",nBytes,
+										PR_FileDesc2NativeHandle(pds[j].fd));
+#ifdef WIN32
+					closesocket((SOCKET)PR_FileDesc2NativeHandle(pds[j].fd));
+#else
+					close(PR_FileDesc2NativeHandle(pds[j].fd));
+#endif
+					PR_DestroySocketPollFd(pds[j].fd);
+				} else {
+					nBytes = PR_Read(pds[j].fd, buf, sizeof(buf));
+					if (nBytes == -1) {
+						fprintf(stderr, "PR_Read() failed\n");
+						exit(1);
+					}
+					PR_Close(pds[j].fd);
+				}
+				/* Just to be safe */
+				buf[BUF_SIZE - 1] = '\0';
+				printf("The server received \"%s\" from a client\n", buf);
+			} else if (pds[j].out_flags & PR_POLL_ERR) {
+				fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
+				exit(1);
+			} else if (pds[j].out_flags & PR_POLL_NVAL) {
+				fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n");
+				exit(1);
+			} else {
+				other_pds[nextIndex] = pds[j];
+				nextIndex++;
+			}
+		}
+
+		PR_ASSERT(retVal == nEvents);
+		/* swap */
+		tmp = pds;
+		pds = other_pds;
+		other_pds = tmp;
+		npds = nextIndex;
+		i += nEvents;
+    }
+    PR_DestroySocketPollFd(socket_poll_fd);
+
+    printf("All tests finished\n");
+    PR_Cleanup();
+    return 0;
+}
+
+
+#endif   /* ifdef WINCE */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/prpollml.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prpollml.c
new file mode 100644
index 0000000..f740f09
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prpollml.c
@@ -0,0 +1,172 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This test exercises the code that allocates and frees the syspoll_list
+ * array of PRThread in the pthreads version.  This test is intended to be
+ * run under Purify to verify that there is no memory leak.
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef SYMBIAN
+#define POLL_DESC_COUNT 128
+#else
+#define POLL_DESC_COUNT 256  /* This should be greater than the
+                              * STACK_POLL_DESC_COUNT macro in
+                              * ptio.c to cause syspoll_list to
+                              * be created. */
+#endif
+
+static PRPollDesc pd[POLL_DESC_COUNT];
+
+static void Test(void)
+{
+    int i;
+    PRInt32 rv;
+    PRIntervalTime timeout;
+
+    timeout = PR_MillisecondsToInterval(10);
+    /* cause syspoll_list to grow */
+    for (i = 1; i <= POLL_DESC_COUNT; i++) {
+        rv = PR_Poll(pd, i, timeout);
+        if (rv != 0) {
+            fprintf(stderr,
+                "PR_Poll should time out but returns %d (%d, %d)\n",
+                (int) rv, (int) PR_GetError(), (int) PR_GetOSError());
+            exit(1);
+        }
+    }
+    /* syspoll_list should be large enough for all these */
+    for (i = POLL_DESC_COUNT; i >= 1; i--) {
+        rv = PR_Poll(pd, i, timeout);
+        if (rv != 0) {
+            fprintf(stderr, "PR_Poll should time out but returns %d\n", 
+                             (int) rv);
+            exit(1);
+        }
+    }
+}
+
+static void ThreadFunc(void *arg)
+{
+    Test();
+}
+
+int main(int argc, char **argv)
+{
+    int i;
+    PRThread *thread;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons(0);
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    for (i = 0; i < POLL_DESC_COUNT; i++) {
+        sock = PR_NewTCPSocket();
+        if (sock == NULL) {
+            fprintf(stderr, "PR_NewTCPSocket failed (%d, %d)\n",
+                            (int) PR_GetError(), (int) PR_GetOSError());
+            fprintf(stderr, "Ensure the per process file descriptor limit "
+                            "is greater than %d.", POLL_DESC_COUNT);
+            exit(1);
+        }
+        if (PR_Bind(sock, &addr) == PR_FAILURE) {
+            fprintf(stderr, "PR_Bind failed (%d, %d)\n",
+                            (int) PR_GetError(), (int) PR_GetOSError());
+            exit(1);
+        }
+        if (PR_Listen(sock, 5) == PR_FAILURE) {
+            fprintf(stderr, "PR_Listen failed (%d, %d)\n",
+                            (int) PR_GetError(), (int) PR_GetOSError());
+            exit(1);
+        }
+    
+        pd[i].fd = sock;
+        pd[i].in_flags = PR_POLL_READ;
+    }
+
+    /* first run the test on the primordial thread */
+    Test();
+
+    /* then run the test on all three kinds of threads */
+    thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == thread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(thread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == thread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(thread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == thread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(thread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    for (i = 0; i < POLL_DESC_COUNT; i++) {
+        if (PR_Close(pd[i].fd) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        }
+    }
+    PR_Cleanup();
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/prselect.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prselect.c
new file mode 100644
index 0000000..ff6ebdc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prselect.c
@@ -0,0 +1,372 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1997 - Netscape Communications Corporation
+**
+** Name: prselect_err.c
+**
+** Description: tests PR_Select with sockets Error condition functions.
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include "prttools.h"
+
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prerror.h"
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**				status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static Test_Result (int result)
+{
+	if (result == PASS)
+		printf ("PASS\n");
+	else
+		printf ("FAIL\n");
+}
+
+static void
+clientThreadFunc(void *arg)
+{
+    PRUint16 port = (PRUint16) arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[128];
+    int i;
+
+    addr.inet.family = AF_INET;
+    addr.inet.port = PR_htons(port);
+    addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+    PR_snprintf(buf, sizeof(buf), "%hu", port);
+
+    for (i = 0; i < 5; i++) {
+	sock = PR_NewTCPSocket();
+        PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+	PR_Write(sock, buf, sizeof(buf));
+	PR_Close(sock);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *badFD;
+    PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds;
+    PRIntn nfds;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    PR_fd_set readFdSet;
+    char buf[128];
+    PRThread *clientThread;
+    PRInt32 retVal;
+    PRIntn i, j;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Select with sockets.  Timeout, error\n");
+		printf("reporting, and normal operation are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    printf("%s", buf);
+
+    /* Set up the fd set */
+    PR_FD_ZERO(&readFdSet);
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+    /* Testing timeout */
+    if (debug_mode) printf("PR_Select should time out in 5 seconds\n");
+    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+	    PR_SecondsToInterval(5));
+    if (retVal != 0) {
+	PR_snprintf(buf, sizeof(buf),
+		"PR_Select should time out and return 0, but it returns %ld\n",
+		retVal);
+	fprintf(stderr, "%s", buf);
+	if (retVal == -1) {
+	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
+		    PR_GetOSError());
+			if (!debug_mode) Test_Result(FAIL);
+	}
+	exit(1);
+    }
+    if (debug_mode) printf("PR_Select timed out.  Test passed.\n\n");
+	else Test_Result(PASS);
+
+    /* Testing bad fd */
+    printf("PR_Select should detect a bad file descriptor\n");
+    if ((badFD = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a TCP socket\n");
+	exit(1);
+    }
+
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+    PR_FD_SET(badFD, &readFdSet);
+    PR_Close(badFD);  /* make the fd bad */
+    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+	    PR_INTERVAL_NO_TIMEOUT);
+    if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) {
+	fprintf(stderr, "Failed to detect the bad fd: "
+		"PR_Select returns %d\n", retVal);
+	if (retVal == -1) {
+	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
+		    PR_GetOSError());
+	}
+	exit(1);
+    }
+    printf("PR_Select detected a bad fd.  Test passed.\n\n");
+    PR_FD_CLR(badFD, &readFdSet);
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort1,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort2,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    printf("Two client threads are created.  Each of them will\n");
+    printf("send data to one of the two ports the server is listening on.\n");
+    printf("The data they send is the port number.  Each of them send\n");
+    printf("the data five times, so you should see ten lines below,\n");
+    printf("interleaved in an arbitrary order.\n");
+
+    /* set up the fd array */
+    fds = fds0;
+    other_fds = fds1;
+    fds[0] = listenSock1;
+    fds[1] = listenSock2;
+    nfds = 2;
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+    /* 20 events total */
+    i = 0;
+    while (i < 20) {
+	PRFileDesc **tmp;
+	int nextIndex;
+	int nEvents = 0;
+
+	retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+		PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(retVal != 0);  /* no timeout */
+	if (retVal == -1) {
+	    fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(),
+		    PR_GetOSError());
+	    exit(1);
+	}
+
+	nextIndex = 2;
+	/* the two listening sockets */
+	for (j = 0; j < 2; j++) {
+	    other_fds[j] = fds[j];
+	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
+		PRFileDesc *sock;
+
+		nEvents++;
+		sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT);
+		if (sock == NULL) {
+		    fprintf(stderr, "PR_Accept() failed\n");
+		    exit(1);
+		}
+		other_fds[nextIndex] = sock;
+		PR_FD_SET(sock, &readFdSet);
+		nextIndex++;
+	    }
+	    PR_FD_SET(fds[j], &readFdSet);
+	}
+
+	for (j = 2; j < nfds; j++) {
+	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
+		PRInt32 nBytes;
+
+		PR_FD_CLR(fds[j], &readFdSet);
+		nEvents++;
+		nBytes = PR_Read(fds[j], buf, sizeof(buf));
+		if (nBytes == -1) {
+		    fprintf(stderr, "PR_Read() failed\n");
+		    exit(1);
+		}
+		/* Just to be safe */
+		buf[127] = '\0';
+		PR_Close(fds[j]);
+		printf("The server received \"%s\" from a client\n", buf);
+	    } else {
+		PR_FD_SET(fds[j], &readFdSet);
+		other_fds[nextIndex] = fds[j];
+		nextIndex++;
+	    }
+	}
+
+	PR_ASSERT(retVal == nEvents);
+	/* swap */
+	tmp = fds;
+	fds = other_fds;
+	other_fds = tmp;
+	nfds = nextIndex;
+	i += nEvents;
+    }
+
+    printf("All tests finished\n");
+    PR_Cleanup();
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/prttools.h b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prttools.h
new file mode 100644
index 0000000..dc38f31
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/prttools.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Used in Regress Tool */
+#define NOSTATUS 2
+#define PASS 1
+#define FAIL 0
+
+PRIntn debug_mode=0;
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/randseed.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/randseed.c
new file mode 100644
index 0000000..2cda2dc
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/randseed.c
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: rngseed.c
+** Description: 
+** Test NSPR's Random Number Seed generator
+**
+** Initial test: Just make sure it outputs some data.
+** 
+** ... more? ... check some iterations to ensure it is random (no dupes)
+** ... more? ... histogram distribution of random numbers
+*/
+
+#include "plgetopt.h"
+#include "nspr.h" 
+#include "prrng.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn  debug = 0;
+PRUint32  failed_already = 0;
+/* end Test harness infrastructure */
+
+PRIntn  optRandCount = 30;
+char    buf[40];
+PRSize  bufSize = sizeof(buf);
+PRSize  rSize;
+PRIntn  i;
+
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+    printf("Template: Help(): display your help message(s) here");
+    exit(1);
+} /* end Help() */
+
+static void PrintRand( void *buf, PRIntn size )
+{
+    PRUint32 *rp = buf;
+    PRIntn   i;
+
+    printf("%4.4d--\n", size );
+    while (size > 0 ) {
+        switch( size )  {
+            case 1 :
+                printf("%2.2X\n", *(rp++) );
+                size -= 4;    
+                break;
+            case 2 :
+                printf("%4.4X\n", *(rp++) );
+                size -= 4;    
+                break;
+            case 3 :
+                printf("%6.6X\n", *(rp++) );
+                size -= 4;    
+                break;
+            default:
+                while ( size >= 4) {
+                    PRIntn i = 3;
+                    do {
+                        printf("%8.8X ", *(rp++) );
+                        size -= 4;    
+                    } while( i-- );
+                    i = 3;
+                    printf("\n");
+                }
+                break;
+        } /* end switch() */
+    } /* end while() */
+} /* end PrintRand() */
+
+
+int main(int argc, char **argv)
+{
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "hdv");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_ERROR;
+                break;
+            case 'v':  /* verbose mode */
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+            case 'h':  /* help message */
+			    Help();
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+    for ( i = 0; i < optRandCount ; i++ ) {
+        memset( buf, 0, bufSize );
+        rSize = PR_GetRandomNoise( buf, bufSize );
+        if (!rSize) {
+            fprintf(stderr, "Not implemented\n" );
+            failed_already = PR_TRUE;
+            break;
+        }
+        if (debug) PrintRand( buf, rSize );
+    }
+
+    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end template.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/ranfile.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ranfile.c
new file mode 100644
index 0000000..c639382
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ranfile.c
@@ -0,0 +1,422 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Contact:     AOF<freier@netscape.com>
+**
+** Name: ranfile.c
+**
+** Description: Test to hammer on various components of NSPR
+** Modification History:
+** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prthread.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "prmem.h"
+#include "prinrval.h"
+#include "prio.h"
+
+#include <string.h>
+#include <stdio.h>
+
+static PRIntn debug_mode = 0;
+static PRIntn failed_already=0;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+typedef enum {sg_go, sg_stop, sg_done} Action;
+typedef enum {sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem;
+
+typedef struct Hammer_s {
+    PRLock *ml;
+    PRCondVar *cv;
+    PRUint32 id;
+    PRUint32 limit;
+    PRUint32 writes;
+    PRThread *thread;
+    PRIntervalTime timein;
+    Action action;
+    Problem problem;
+} Hammer_t;
+
+#define DEFAULT_LIMIT		10
+#define DEFAULT_THREADS		2
+#define DEFAULT_LOOPS		1
+
+static PRInt32 pageSize = 1024;
+static const char* baseName = "./";
+static const char *programName = "Random File";
+
+/***********************************************************************
+** PRIVATE FUNCTION:    RandomNum
+** DESCRIPTION:
+**   Generate a pseudo-random number
+** INPUTS:      None
+** OUTPUTS:     None
+** RETURN:      A pseudo-random unsigned number, 32-bits wide
+** SIDE EFFECTS:
+**      Updates random seed (a static)
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:
+**      Uses the current interval timer value, promoted to a 64 bit
+**      float as a multiplier for a static residue (which begins
+**      as an uninitialized variable). The result is bits [16..48)
+**      of the product. Seed is then updated with the return value
+**      promoted to a float-64.
+***********************************************************************/
+static PRUint32 RandomNum(void)
+{
+    PRUint32 rv;
+    PRUint64 shift;
+    static PRFloat64 seed = 0x58a9382;  /* Just make sure it isn't 0! */
+    PRFloat64 random = seed * (PRFloat64)PR_IntervalNow();
+    LL_USHR(shift, *((PRUint64*)&random), 16);
+    LL_L2UI(rv, shift);
+    seed = (PRFloat64)rv;
+    return rv;
+}  /* RandomNum */
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Thread
+** DESCRIPTION:
+**   Hammer on the file I/O system
+** INPUTS:      A pointer to the thread's private data
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      Creates, accesses and deletes a file
+** RESTRICTIONS:
+**      (Currently) must have file create permission in "/usr/tmp".
+** MEMORY:      NA
+** ALGORITHM:
+**      This function is a root of a thread
+**      1) Creates a (hopefully) unique file in /usr/tmp/
+**      2) Writes a zero to a random number of sequential pages
+**      3) Closes the file
+**      4) Reopens the file
+**      5) Seeks to a random page within the file
+**      6) Writes a one byte on that page
+**      7) Repeat steps [5..6] for each page in the file
+**      8) Close and delete the file
+**      9) Repeat steps [1..8] until told to stop
+**     10) Notify complete and return
+***********************************************************************/
+static void PR_CALLBACK Thread(void *arg)
+{
+    PRUint32 index;
+    char filename[30];
+    const char zero = 0;
+    PRFileDesc *file = NULL;
+    PRStatus rv = PR_SUCCESS;
+    Hammer_t *cd = (Hammer_t*)arg;
+
+    (void)sprintf(filename, "%ssg%04ld.dat", baseName, cd->id);
+
+    if (debug_mode) printf("Starting work on %s\n", filename);
+
+    while (PR_TRUE)
+    {
+        PRUint32 bytes;
+        PRUint32 minor = (RandomNum() % cd->limit) + 1;
+        PRUint32 random = (RandomNum() % cd->limit) + 1;
+        PRUint32 pages = (RandomNum() % cd->limit) + 10;
+        while (minor-- > 0)
+        {
+            cd->problem = sg_okay;
+            if (cd->action != sg_go) goto finished;
+            cd->problem = sg_open;
+            file = PR_Open(filename, PR_RDWR|PR_CREATE_FILE, 0666);
+            if (file == NULL) goto finished;
+            for (index = 0; index < pages; index++)
+            {
+                cd->problem = sg_okay;
+                if (cd->action != sg_go) goto close;
+                cd->problem = sg_seek;
+                bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET);
+                if (bytes != pageSize * index) goto close;
+                cd->problem = sg_write;
+                bytes = PR_Write(file, &zero, sizeof(zero));
+                if (bytes <= 0) goto close;
+                cd->writes += 1;
+            }
+            cd->problem = sg_close;
+            rv = PR_Close(file);
+            if (rv != PR_SUCCESS) goto purge;
+
+            cd->problem = sg_okay;
+            if (cd->action != sg_go) goto purge;
+
+            cd->problem = sg_open;
+            file = PR_Open(filename, PR_RDWR, 0666);
+            for (index = 0; index < pages; index++)
+            {
+                cd->problem = sg_okay;
+                if (cd->action != sg_go) goto close;
+                cd->problem = sg_seek;
+                bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET);
+                if (bytes != pageSize * index) goto close;
+                cd->problem = sg_write;
+                bytes = PR_Write(file, &zero, sizeof(zero));
+                if (bytes <= 0) goto close;
+                cd->writes += 1;
+                random = (random + 511) % pages;
+            }
+            cd->problem = sg_close;
+            rv = PR_Close(file);
+            if (rv != PR_SUCCESS) goto purge;
+            cd->problem = sg_delete;
+            rv = PR_Delete(filename);
+            if (rv != PR_SUCCESS) goto finished;
+       }
+    }
+
+close:
+    (void)PR_Close(file);
+purge:
+    (void)PR_Delete(filename);
+finished:
+    PR_Lock(cd->ml);
+    cd->action = sg_done;
+    PR_NotifyCondVar(cd->cv);
+    PR_Unlock(cd->ml);
+
+    if (debug_mode) printf("Ending work on %s\n", filename);
+
+    return;
+}  /* Thread */
+
+static Hammer_t hammer[100];
+static PRCondVar *cv;
+/***********************************************************************
+** PRIVATE FUNCTION:    main
+** DESCRIPTION:
+**   Hammer on the file I/O system
+** INPUTS:      The usual argc and argv
+**              argv[0] - program name (not used)
+**              argv[1] - the number of times to execute the major loop
+**              argv[2] - the number of threads to toss into the batch
+**              argv[3] - the clipping number applied to randoms
+**              default values: loops = 2, threads = 10, limit = 57
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      Creates, accesses and deletes lots of files
+** RESTRICTIONS:
+**      (Currently) must have file create permission in "/usr/tmp".
+** MEMORY:      NA
+** ALGORITHM:
+**      1) Fork a "Thread()"
+**      2) Wait for 'interleave' seconds
+**      3) For [0..'threads') repeat [1..2]
+**      4) Mark all objects to stop
+**      5) Collect the threads, accumulating the results
+**      6) For [0..'loops') repeat [1..5]
+**      7) Print accumulated results and exit
+**
+**      Characteristic output (from IRIX)
+**          Random File: Using loops = 2, threads = 10, limit = 57
+**          Random File: [min [avg] max] writes/sec average
+***********************************************************************/
+int main(int argc, char **argv)
+{
+    PRLock *ml;
+    PRUint32 id = 0;
+    int active, poll;
+    PRIntervalTime interleave;
+    PRIntervalTime duration = 0;
+    int limit = 0, loops = 0, threads = 0, times;
+    PRUint32 writes, writesMin = 0x7fffffff, writesTot = 0, durationTot = 0, writesMax = 0;
+
+    const char *where[] = {"okay", "open", "close", "delete", "write", "seek"};
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* global threads */
+			thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'l':  /* limiting number */
+			limit = atoi(opt->value);
+            break;
+        case 't':  /* number of threads */
+			threads = atoi(opt->value);
+            break;
+        case 'i':  /* iteration counter */
+			loops = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    interleave = PR_SecondsToInterval(10);
+
+    ml = PR_NewLock();
+    cv = PR_NewCondVar(ml);
+
+    if (loops == 0) loops = DEFAULT_LOOPS;
+    if (limit == 0) limit = DEFAULT_LIMIT;
+    if (threads == 0) threads = DEFAULT_THREADS;
+
+    if (debug_mode) printf(
+        "%s: Using loops = %d, threads = %d, limit = %d and %s threads\n",
+        programName, loops, threads, limit,
+        (thread_scope == PR_LOCAL_THREAD) ? "LOCAL" : "GLOBAL");
+
+    for (times = 0; times < loops; ++times)
+    {
+        if (debug_mode) printf("%s: Setting concurrency level to %d\n", programName, times + 1);
+        PR_SetConcurrency(times + 1);
+        for (active = 0; active < threads; active++)
+        {
+            hammer[active].ml = ml;
+            hammer[active].cv = cv;
+            hammer[active].id = id++;
+            hammer[active].writes = 0;
+            hammer[active].action = sg_go;
+            hammer[active].problem = sg_okay;
+            hammer[active].limit = (RandomNum() % limit) + 1;
+            hammer[active].timein = PR_IntervalNow();
+            hammer[active].thread = PR_CreateThread(
+                PR_USER_THREAD, Thread, &hammer[active],
+                PR_GetThreadPriority(PR_GetCurrentThread()),
+                thread_scope, PR_JOINABLE_THREAD, 0);
+
+            PR_Lock(ml);
+            PR_WaitCondVar(cv, interleave);  /* start new ones slowly */
+            PR_Unlock(ml);
+        }
+
+        /*
+         * The last thread started has had the opportunity to run for
+         * 'interleave' seconds. Now gather them all back in.
+         */
+        PR_Lock(ml);
+        for (poll = 0; poll < threads; poll++)
+        {
+            if (hammer[poll].action == sg_go)  /* don't overwrite done */
+                hammer[poll].action = sg_stop;  /* ask him to stop */
+        }
+        PR_Unlock(ml);
+
+        while (active > 0)
+        {
+            for (poll = 0; poll < threads; poll++)
+            {
+                PR_Lock(ml);
+                while (hammer[poll].action < sg_done)
+                    PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+                PR_Unlock(ml);
+
+                active -= 1;  /* this is another one down */
+                (void)PR_JoinThread(hammer[poll].thread);
+                hammer[poll].thread = NULL;
+                if (hammer[poll].problem == sg_okay)
+                {
+                    duration = PR_IntervalToMilliseconds(
+                        PR_IntervalNow() - hammer[poll].timein);
+                    writes = hammer[poll].writes * 1000 / duration;
+                    if (writes < writesMin) 
+                        writesMin = writes;
+                    if (writes > writesMax) 
+                        writesMax = writes;
+                    writesTot += hammer[poll].writes;
+                    durationTot += duration;
+                }
+                else
+                    if (debug_mode) printf(
+                        "%s: test failed %s after %ld seconds\n",
+                        programName, where[hammer[poll].problem], duration);
+					else failed_already=1;
+            }
+        }
+    }
+    if (debug_mode) printf(
+        "%s: [%ld [%ld] %ld] writes/sec average\n",
+        programName, writesMin, writesTot * 1000 / durationTot, writesMax);
+
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+
+	if (failed_already) 
+	{
+	    printf("FAIL\n");
+		return 1;
+	}
+    else
+    {
+        printf("PASS\n");
+		return 0;
+    }
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/reinit.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/reinit.c
new file mode 100644
index 0000000..8150021
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/reinit.c
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ludovico Cavedon <ludovico.cavedon@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* This test verifies that NSPR can be cleaned up and reinitialized. */
+
+#include "nspr.h"
+#include <stdio.h>
+
+int main()
+{
+    PRStatus rv;
+
+    fprintf(stderr, "Init 1\n");
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    fprintf(stderr, "Cleanup 1\n");
+    rv = PR_Cleanup();
+    if (rv != PR_SUCCESS) {
+        fprintf(stderr, "FAIL\n");
+        return 1;
+    }
+
+    fprintf(stderr, "Init 2\n");
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    fprintf(stderr, "Cleanup 2\n");
+    rv = PR_Cleanup();
+    if (rv != PR_SUCCESS) {
+        fprintf(stderr, "FAIL\n");
+        return 1;
+    }
+
+    fprintf(stderr, "PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/rmdir.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/rmdir.c
new file mode 100644
index 0000000..87f9dc3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/rmdir.c
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        rmdir.c
+** Description: Demonstrate bugzilla 80884. 
+**
+** after fix to unix_errors.c, message should report correct 
+** failure of PR_Rmdir().
+**
+**
+**
+*/
+
+#include <prio.h>
+#include <stdio.h>
+#include <prerror.h>
+#include <prlog.h>
+#include "plgetopt.h"
+
+#define DIRNAME "xxxBug80884/"
+#define FILENAME "file80883"
+
+PRBool  failed_already = PR_FALSE;
+PRBool	debug_mode = PR_FALSE;
+
+PRLogModuleInfo     *lm;
+
+/*
+** Help() -- print Usage information
+*/
+static void Help( void )  {
+    fprintf(stderr, "template usage:\n"
+                    "\t-d     debug mode\n"
+                    );
+} /* --- end Help() */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dh");
+    PRFileDesc* fd;
+    PRErrorCode err;
+
+    /* parse command line options */
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    lm = PR_NewLogModule( "testcase" );
+
+    (void) PR_MkDir( DIRNAME, 0777);
+    fd = PR_Open( DIRNAME FILENAME, PR_CREATE_FILE|PR_RDWR, 0666);
+    if (fd == 0) {
+        PRErrorCode err = PR_GetError();
+        fprintf(stderr, "create file fails: %d: %s\n", err,
+            PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
+        failed_already = PR_TRUE;
+        goto Finished;
+    }
+ 
+    PR_Close(fd);
+
+    if (PR_RmDir( DIRNAME ) == PR_SUCCESS) {
+        fprintf(stderr, "remove directory succeeds\n");
+        failed_already = PR_TRUE;
+        goto Finished;
+    }
+ 
+    err = PR_GetError();
+    fprintf(stderr, "remove directory fails with: %d: %s\n", err,
+        PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
+
+    (void) PR_Delete( DIRNAME FILENAME);
+    (void) PR_RmDir( DIRNAME );
+
+    return 0;
+
+Finished:
+    if ( debug_mode ) printf("%s\n", ( failed_already ) ? "FAILED" : "PASS" );
+    return( (failed_already)? 1 : 0 );
+}  /* --- end main() */
+/* --- end template.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/runtests.pl b/nspr-4.8.6/mozilla/nsprpub/pr/tests/runtests.pl
new file mode 100755
index 0000000..d4e1588
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/runtests.pl
@@ -0,0 +1,403 @@
+#!/usr/bin/perl
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Sun Microsystems, Inc.
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Christophe Ravel <christophe.ravel@sun.com>, Sun Microsystems
+#   Slavomir Katuscak <slavomir.katuscak@sun.com>, Sun Microsystems
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+use POSIX qw(:sys_wait_h);
+use POSIX qw(setsid);
+use FileHandle;
+
+# Constants
+$WINOS = "MSWin32";
+
+$osname = $^O;
+
+use Cwd;
+if ($osname =~ $WINOS) {
+    # Windows
+    require Win32::Process;
+    require Win32;
+}
+
+# Get environment variables.
+$output_file = $ENV{NSPR_TEST_LOGFILE};
+$timeout = $ENV{TEST_TIMEOUT};
+
+$timeout = 0 if (!defined($timeout));
+
+sub getTime {
+    ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime();
+
+    $year = 1900 + $yearOffset;
+
+    $theTime = sprintf("%04d-%02d-%02d %02d:%02d:%02d",$year,$month,$dayOfMonth,$hour,$minute,$second);
+    return $theTime;
+}
+
+sub open_log {
+
+    if (!defined($output_file)) {
+        print "No output file.\n";
+        # null device
+        if ($osname =~ $WINOS) {
+            $output_file = "nul";
+        } else {
+            $output_file = "/dev/null";
+        }
+    }
+    
+    # use STDOUT for OF (to print summary of test results)
+    open(OF, ">&STDOUT") or die "Can't reuse STDOUT for OF\n";
+    OF->autoflush;
+    # reassign STDOUT to $output_file (to print details of test results)
+    open(STDOUT, ">$output_file") or die "Can't open file $output_file for STDOUT\n";
+    STDOUT->autoflush;
+    # redirect STDERR to STDOUT
+    open(STDERR, ">&STDOUT") or die "Can't redirect STDERR to STDOUT\n";
+    STDERR->autoflush;
+    
+    # Print header test in summary
+    $now = getTime;
+    print OF "\nNSPR Test Results - tests\n";
+    print OF "\nBEGIN\t\t\t$now\n";
+    print OF "NSPR_TEST_LOGFILE\t$output_file\n";
+    print OF "TEST_TIMEOUT\t$timeout\n\n";
+    print OF "\nTest\t\t\tResult\n\n";
+}
+
+sub close_log {
+    # end of test marker in summary
+    $now = getTime;
+    print OF "END\t\t\t$now\n";
+
+    close(OF) or die "Can't close file OF\n";
+    close(STDERR) or die "Can't close STDERR\n";
+    close(STDOUT) or die "Can't close STDOUT\n";
+}
+
+sub print_begin {
+$lprog = shift;
+
+    # Summary output
+    print OF "$prog";
+    # Full output
+    $now = getTime;
+    print "BEGIN TEST: $lprog ($now)\n\n";
+}
+
+sub print_end {
+($lprog, $exit_status, $exit_signal, $exit_core) = @_;
+
+    if (($exit_status == 0) && ($exit_signal == 0) && ($exit_core == 0)) {
+        $str_status = "Passed";
+    } else {
+        $str_status = "FAILED";
+    }
+    if ($exit_signal != 0) {
+    	$str_signal = " - signal $exit_signal";
+    } else {
+    	$str_signal = "";
+    }
+    if ($exit_core != 0) {
+    	$str_core = " - core dumped";
+    } else {
+    	$str_core = "";
+    }
+    $now = getTime;
+    # Full output
+    print "\nEND TEST: $lprog ($now)\n";
+    print "TEST STATUS: $lprog = $str_status (exit status " . $exit_status . $str_signal . $str_core . ")\n";
+    print "--------------------------------------------------\n\n";
+    # Summary output
+    print OF "\t\t\t$str_status\n";
+}
+
+sub ux_start_prog {
+# parameters:
+$lprog = shift; # command to run
+
+    # Create a process group for the child
+    # so we can kill all of it if needed
+    setsid or die "setsid failed: $!";
+    # Start test program    
+    exec("./$lprog");
+    # We should not be here unless exec failed.
+    print "Faild to exec $lprog";
+    exit 1 << 8;
+}   
+
+sub ux_wait_timeout {
+# parameters:
+$lpid = shift;     # child process id
+$ltimeout = shift; # timeout
+
+    if ($ltimeout == 0) {
+        # No timeout: use blocking wait
+        $ret = waitpid($lpid,0);
+        # Exit and don't kill
+        $lstatus = $?;
+        $ltimeout = -1;
+    } else {
+        while ($ltimeout > 0) {
+            # Check status of child using non blocking wait
+            $ret = waitpid($lpid, WNOHANG);
+            if ($ret == 0) {
+                # Child still running
+    #           print "Time left=$ltimeout\n";
+                sleep 1;
+                $ltimeout--;
+            } else {
+                # Child has ended
+                $lstatus = $?;
+                # Exit the wait loop and don't kill
+                $ltimeout = -1;
+            }
+        }
+    }
+    
+    if ($ltimeout == 0) {
+        # we ran all the timeout: it's time to kill the child
+        print "Timeout ! Kill child process $lpid\n";
+        # Kill the child process and group
+        kill(-9,$lpid);
+        $lstatus = 9;
+    }
+    
+    return $lstatus;
+}
+
+sub ux_test_prog {
+# parameters:
+$prog = shift;  # Program to test
+
+    $child_pid = fork;
+    if ($child_pid == 0) {
+        # we are in the child process
+        print_begin($prog);
+        ux_start_prog($prog);
+    } else {
+        # we are in the parent process
+        $status = ux_wait_timeout($child_pid,$timeout);
+        # See Perlvar for documentation of $?
+        # exit status = $status >> 8
+        # exit signal = $status & 127 (no signal = 0)
+        # core dump = $status & 128 (no core = 0)
+        print_end($prog, $status >> 8, $status & 127, $status & 128);
+    }
+
+    return $status;
+}
+
+sub win_path {
+$lpath = shift;
+
+    # MSYS drive letter = /c/ -> c:/
+    $lpath =~ s/^\/(\w)\//$1:\//;
+    # Cygwin drive letter = /cygdrive/c/ -> c:/
+    $lpath =~ s/^\/cygdrive\/(\w)\//$1:\//;
+    # replace / with \\
+    $lpath =~ s/\//\\\\/g;
+    
+    return $lpath;
+}
+
+sub win_ErrorReport{
+    print Win32::FormatMessage( Win32::GetLastError() );
+}
+
+sub win_test_prog {
+# parameters:
+$prog = shift;  # Program to test
+
+    $status = 1;
+    $curdir = getcwd;
+    $curdir = win_path($curdir);
+    $prog_path = "$curdir\\$prog.exe";
+    
+    print_begin($prog);
+    
+    Win32::Process::Create($ProcessObj,
+                           "$prog_path",
+                           "$prog",
+                           0,
+                           NORMAL_PRIORITY_CLASS,
+                           ".")|| die win_ErrorReport();
+    $retwait = $ProcessObj->Wait($timeout * 1000);
+        
+    if ( $retwait == 0) {
+        # the prog didn't finish after the timeout: kill
+        $ProcessObj->Kill($status);
+        print "Timeout ! Process killed with exit status $status\n";
+    } else {
+        # the prog finished before the timeout: get exit status
+        $ProcessObj->GetExitCode($status);
+    }
+    # There is no signal, no core on Windows
+    print_end($prog, $status, 0, 0);
+
+    return $status
+}
+
+# MAIN ---------------
+@progs = (
+"accept",
+"acceptread",
+"acceptreademu",
+"affinity",
+"alarm",
+"anonfm",
+"atomic",
+"attach",
+"bigfile",
+"cleanup",
+"cltsrv",
+"concur",
+"cvar",
+"cvar2",
+"dlltest",
+"dtoa",
+"errcodes",
+"exit",
+"fdcach",
+"fileio",
+"foreign",
+"formattm",
+"fsync",
+"gethost",
+"getproto",
+"i2l",
+"initclk",
+"inrval",
+"instrumt",
+"intrio",
+"intrupt",
+"io_timeout",
+"ioconthr",
+"join",
+"joinkk",
+"joinku",
+"joinuk",
+"joinuu",
+"layer",
+"lazyinit",
+"libfilename",
+"lltest",
+"lock",
+"lockfile",
+"logfile",
+"logger",
+"many_cv",
+"multiwait",
+"nameshm1",
+"nblayer",
+"nonblock",
+"ntioto",
+"ntoh",
+"op_2long",
+"op_excl",
+"op_filnf",
+"op_filok",
+"op_nofil",
+"parent",
+"parsetm",
+"peek",
+"perf",
+"pipeping",
+"pipeping2",
+"pipeself",
+"poll_nm",
+"poll_to",
+"pollable",
+"prftest",
+"primblok",
+"provider",
+"prpollml",
+"ranfile",
+"randseed",
+"reinit",
+"rwlocktest",
+"sel_spd",
+"selct_er",
+"selct_nm",
+"selct_to",
+"selintr",
+"sema",
+"semaerr",
+"semaping",
+"sendzlf",
+"server_test",
+"servr_kk",
+"servr_uk",
+"servr_ku",
+"servr_uu",
+"short_thread",
+"sigpipe",
+"socket",
+"sockopt",
+"sockping",
+"sprintf",
+"stack",
+"stdio",
+"str2addr",
+"strod",
+"switch",
+"system",
+"testbit",
+"testfile",
+"threads",
+"timemac",
+"timetest",
+"tpd",
+"udpsrv",
+"vercheck",
+"version",
+"writev",
+"xnotify",
+"zerolen");
+
+open_log;
+
+foreach $current_prog (@progs) {
+    if ($osname =~ $WINOS) {
+        win_test_prog($current_prog);
+    } else {
+        ux_test_prog($current_prog);
+    }
+}
+
+close_log;
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/runtests.sh b/nspr-4.8.6/mozilla/nsprpub/pr/tests/runtests.sh
new file mode 100755
index 0000000..b6d20fd
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/runtests.sh
@@ -0,0 +1,301 @@
+#!/bin/sh
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# runtests.sh
+#	Bourne shell script for nspr tests
+#
+
+SYSTEM_INFO=`uname -a`
+OS_ARCH=`uname -s`
+
+if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "OS/2" ]
+then
+	NULL_DEVICE=nul
+else
+	NULL_DEVICE=/dev/null
+	FILE_D=`ulimit -n`
+	if [ $FILE_D -lt 512 ]
+	then
+		ulimit -n 512
+	fi
+fi
+
+#
+# Irrevelant tests
+#
+#bug1test 	- used to demonstrate a bug on NT
+#bigfile2   - requires 4Gig file creation. See BugZilla #5451
+#bigfile3   - requires 4Gig file creation. See BugZilla #5451
+#dbmalloc	- obsolete; originally for testing debug version of nspr's malloc
+#dbmalloc1	- obsolete; originally for testing debug version of nspr's malloc
+#depend		- obsolete; used to test a initial spec for library dependencies
+#dceemu		- used to tests special functions in NSPR for DCE emulation
+#ipv6		- IPV6 not in use by NSPR clients
+#mbcs       - tests use of multi-byte charset for filenames. See BugZilla #25140
+#sproc_ch	- obsolete; sproc-based tests for Irix
+#sproc_p	- obsolete; sproc-based tests for Irix
+#io_timeoutk - obsolete; subsumed in io_timeout
+#io_timeoutu - obsolete; subsumed in io_timeout
+#prftest1	- obsolete; subsumed by prftest
+#prftest2	- obsolete; subsumed by prftest
+#prselect	- obsolete; PR_Select is obsolete
+#select2	- obsolete; PR_Select is obsolete
+#sem		- obsolete; PRSemaphore is obsolete
+#stat		- for OS2?
+#suspend	- private interfaces PR_SuspendAll, PR_ResumeAll, etc..
+#thruput	- needs to be run manually as client/server
+#time		- used to measure time with native calls and nspr calls
+#tmoacc		- should be run with tmocon
+#tmocon		- should be run with tmoacc
+#op_noacc	- limited use
+#yield		- limited use for PR_Yield
+
+#
+# Tests not run (but should)
+#
+
+#forktest (failed on IRIX)
+#nbconn - fails on some platforms 
+#poll_er - fails on some platforms? limited use?
+#prpoll -  the bad-FD test needs to be moved to a different test
+#sleep	-  specific to OS/2
+
+LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE}
+
+#
+# Tests run on all platforms
+#
+
+TESTS="
+accept
+acceptread
+acceptreademu
+affinity
+alarm
+anonfm
+atomic
+attach
+bigfile
+cleanup
+cltsrv
+concur
+cvar
+cvar2
+dlltest
+dtoa
+errcodes
+exit
+fdcach
+fileio
+foreign
+formattm
+fsync
+gethost
+getproto
+i2l
+initclk
+inrval
+instrumt
+intrio
+intrupt
+io_timeout
+ioconthr
+join
+joinkk
+joinku
+joinuk
+joinuu
+layer
+lazyinit
+libfilename
+lltest
+lock
+lockfile
+logfile
+logger
+many_cv
+multiwait
+nameshm1
+nblayer
+nonblock
+ntioto
+ntoh
+op_2long
+op_excl
+op_filnf
+op_filok
+op_nofil
+parent
+parsetm
+peek
+perf
+pipeping
+pipeping2
+pipeself
+poll_nm
+poll_to
+pollable
+prftest
+primblok
+provider
+prpollml
+ranfile
+randseed
+reinit
+rwlocktest
+sel_spd
+selct_er
+selct_nm
+selct_to
+selintr
+sema
+semaerr
+semaping
+sendzlf
+server_test
+servr_kk
+servr_uk
+servr_ku
+servr_uu
+short_thread
+sigpipe
+socket
+sockopt
+sockping
+sprintf
+stack
+stdio
+str2addr
+strod
+switch
+system
+testbit
+testfile
+threads
+timemac
+timetest
+tpd
+udpsrv
+vercheck
+version
+writev
+xnotify
+zerolen"
+
+rval=0
+
+
+#
+# When set, value of the environment variable TEST_TIMEOUT is the maximum
+# time (secs) allowed for a test program beyond which it is terminated.
+# If TEST_TIMEOUT is not set or if it's value is 0, then test programs
+# don't timeout.
+#
+# Running runtests.ksh under MKS toolkit on NT, 95, 98 does not cause
+# timeout detection correctly. For these platforms, do not attempt timeout
+# test. (lth).
+#
+#
+
+OS_PLATFORM=`uname`
+OBJDIR=`basename $PWD`
+printf "\nNSPR Test Results - $OBJDIR\n\n"
+printf "BEGIN\t\t\t`date`\n"
+printf "NSPR_TEST_LOGFILE\t${LOGFILE}\n\n"
+printf "Test\t\t\tResult\n\n"
+if [ $OS_PLATFORM = "Windows_95" ] || [ $OS_PLATFORM = "Windows_98" ] || [ $OS_PLATFORM = "Windows_NT" ] || [ $OS_PLATFORM = "OS/2" ] ; then
+	for prog in $TESTS
+	do
+		printf "$prog"
+		printf "\nBEGIN TEST: $prog\n\n" >> ${LOGFILE} 2>&1
+		./$prog >> ${LOGFILE} 2>&1
+		if [ 0 = $? ] ; then
+			printf "\t\t\tPassed\n";
+		else
+			printf "\t\t\tFAILED\n";
+			rval=1
+		fi;
+		printf "\nEND TEST: $prog\n\n" >> ${LOGFILE} 2>&1
+	done
+else
+	for prog in $TESTS
+	do
+		printf "$prog"
+		printf "\nBEGIN TEST: $prog\n\n" >> ${LOGFILE} 2>&1
+		export test_rval
+		./$prog >> ${LOGFILE} 2>&1 &
+		test_pid=$!
+		sleep_pid=0
+		if test -n "$TEST_TIMEOUT" && test "$TEST_TIMEOUT" -gt 0
+		then
+		(sleep  $TEST_TIMEOUT; kill $test_pid >/dev/null 2>&1 ) &
+		sleep_pid=$!
+		fi
+		wait $test_pid
+		test_rval=$?
+		[ $sleep_pid -eq 0 ] || kill $sleep_pid >/dev/null 2>&1
+		if [ 0 = $test_rval ] ; then
+			printf "\t\t\tPassed\n";
+		else
+			printf "\t\t\tFAILED\n";
+			rval=1
+		fi;
+		printf "\nEND TEST: $prog\n\n" >> ${LOGFILE} 2>&1
+	done
+fi;
+
+printf "END\t\t\t`date`\n"
+exit $rval
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/runy2ktests.ksh b/nspr-4.8.6/mozilla/nsprpub/pr/tests/runy2ktests.ksh
new file mode 100644
index 0000000..e7a3250
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/runy2ktests.ksh
@@ -0,0 +1,269 @@
+#!/bin/ksh
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1999-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# runy2ktests.ksh
+#	Set system clock to Y2K dates of interest and run the Y2K tests.
+#	Needs root/administrator privilege
+#
+# WARNING: Because this script needs to be run with root/administrator
+#	privilege, thorough understanding of the script and extreme
+#	caution are urged.
+#
+
+#
+# SECTION I
+#	Define variables
+#
+
+SYSTEM_INFO=`uname -a`
+OS_ARCH=`uname -s`
+if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "Windows_95" ]
+then
+	NULL_DEVICE=nul
+else
+	NULL_DEVICE=/dev/null
+fi
+
+#
+# Test dates for NSPR Y2K tests
+#
+Y2KDATES="	123123591998.55
+			090923591999.55
+			123123591999.55
+			022823592000.55
+			022923592000.55
+			123123592000.55"
+
+Y2KDATES_AIX="	12312359.5598
+				09092359.5599
+				12312359.5599
+				02282359.5500
+				02292359.5500
+				12312359.5500"
+
+Y2KDATES_HPUX="	123123591998
+				090923591999
+				123123591999
+				022823592000
+				022923592000
+				123123592000"
+
+Y2KDATES_MKS="	1231235998.55
+				0909235999.55
+				1231235999.55
+				0228235900.55
+				0229235900.55
+				1231235900.55"
+
+#
+# NSPR Y2K tests
+#
+Y2KTESTS="
+y2k		\n
+y2ktmo	\n
+y2k		\n
+../runtests.ksh"
+
+Y2KTESTS_HPUX="
+y2k			\n
+y2ktmo -l 60\n
+y2k			\n
+../runtests.ksh"
+
+#
+# SECTION II
+#	Define functions
+#
+
+save_date()
+{
+	case $OS_ARCH in
+	AIX)
+		SAVED_DATE=`date "+%m%d%H%M.%S%y"`
+	;;
+	HP-UX)
+		SAVED_DATE=`date "+%m%d%H%M%Y"`
+	;;
+	Windows_NT)
+		SAVED_DATE=`date "+%m%d%H%M%y.%S"`
+	;;
+	Windows_95)
+		SAVED_DATE=`date "+%m%d%H%M%y.%S"`
+	;;
+	*)
+		SAVED_DATE=`date "+%m%d%H%M%Y.%S"`
+	;;
+	esac
+}
+
+set_date()
+{
+	case $OS_ARCH in
+	Windows_NT)
+#
+# The date command in MKS Toolkit releases 5.1 and 5.2
+# uses the current DST status for the date we want to
+# set the system clock to.  However, the DST status for
+# that date may be different from the current DST status.
+# We can work around this problem by invoking the date
+# command with the same date twice.
+#
+		date "$1" > $NULL_DEVICE
+		date "$1" > $NULL_DEVICE
+	;;
+	*)
+		date "$1" > $NULL_DEVICE
+	;;
+	esac
+}
+
+restore_date()
+{
+	set_date "$SAVED_DATE"
+}
+
+savedate()
+{
+	case $OS_ARCH in
+	AIX)
+		SAVED_DATE=`date "+%m%d%H%M.%S%y"`
+	;;
+	HP-UX)
+		SAVED_DATE=`date "+%m%d%H%M%Y"`
+	;;
+	Windows_NT)
+		SAVED_DATE=`date "+%m%d%H%M%y.%S"`
+	;;
+	Windows_95)
+		SAVED_DATE=`date "+%m%d%H%M%y.%S"`
+	;;
+	*)
+		SAVED_DATE=`date "+%m%d%H%M%Y.%S"`
+	;;
+	esac
+}
+
+set_y2k_test_parameters()
+{
+#
+# set dates
+#
+	case $OS_ARCH in
+	AIX)
+		DATES=$Y2KDATES_AIX
+	;;
+	HP-UX)
+		DATES=$Y2KDATES_HPUX
+	;;
+	Windows_NT)
+		DATES=$Y2KDATES_MKS
+	;;
+	Windows_95)
+		DATES=$Y2KDATES_MKS
+	;;
+	*)
+		DATES=$Y2KDATES
+	;;
+	esac
+
+#
+# set tests
+#
+	case $OS_ARCH in
+	HP-UX)
+		TESTS=$Y2KTESTS_HPUX
+	;;
+	*)
+		TESTS=$Y2KTESTS
+	;;
+	esac
+}
+
+#
+# runtests:
+#	-	runs each test in $TESTS after setting the
+#		system clock to each date in $DATES
+#
+
+runtests()
+{
+for newdate in ${DATES}
+do
+	set_date $newdate
+	echo $newdate
+	echo "BEGIN\t\t\t`date`"
+	echo "Date\t\t\t\t\tTest\t\t\tResult"
+	echo $TESTS | while read prog
+	do
+		echo "`date`\t\t\c"
+		echo "$prog\c"
+		./$prog >> ${LOGFILE} 2>&1
+		if [ 0 = $? ] ; then
+			echo "\t\t\tPassed";
+		else
+			echo "\t\t\tFAILED";
+		fi;
+	done
+	echo "END\t\t\t`date`\n"
+done
+
+}
+
+#
+# SECTION III
+#	Run tests
+#
+
+LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE}
+OBJDIR=`basename $PWD`
+echo "\nNSPR Year 2000 Test Results - $OBJDIR\n"
+echo "SYSTEM:\t\t\t${SYSTEM_INFO}"
+echo "NSPR_TEST_LOGFILE:\t${LOGFILE}\n"
+
+
+save_date
+
+#
+# Run NSPR Y2k and standard tests
+#
+
+set_y2k_test_parameters
+runtests
+
+restore_date
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/rwlocktest.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/rwlocktest.c
new file mode 100644
index 0000000..c31eeb3
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/rwlocktest.c
@@ -0,0 +1,241 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/*
+ *
+ * RWLock tests
+ *
+ *	Several threads are created to access and modify data arrays using
+ * 	PRRWLocks for synchronization. Two data arrays, array_A and array_B, are
+ *	initialized with random data and a third array, array_C, is initialized
+ *	with the sum of the first 2 arrays.
+ *
+ *	Each one of the threads acquires a read lock to verify that the sum of
+ *	the arrays A and B is equal to array C, and acquires a write lock to
+ *	consistently update arrays A and B so that their is equal to array C.
+ *		
+ */
+ 
+#include "nspr.h"
+#include "plgetopt.h"
+#include "prrwlock.h"
+
+static int _debug_on;
+static void rwtest(void *args);
+static PRInt32 *array_A,*array_B,*array_C;
+static void update_array(void);
+static void check_array(void);
+
+typedef struct thread_args {
+	PRRWLock	*rwlock;
+	PRInt32		loop_cnt;
+} thread_args;
+
+PRFileDesc  *output;
+PRFileDesc  *errhandle;
+
+#define	DEFAULT_THREAD_CNT	4
+#define	DEFAULT_LOOP_CNT	100
+#define	TEST_ARRAY_SIZE		100
+
+int main(int argc, char **argv)
+{
+    PRInt32 cnt;
+	PRStatus rc;
+	PRInt32 i;
+
+	PRInt32 thread_cnt = DEFAULT_THREAD_CNT;
+	PRInt32 loop_cnt = DEFAULT_LOOP_CNT;
+	PRThread **threads;
+	thread_args *params;
+	PRRWLock	*rwlock1;
+
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 't':  /* thread count */
+            thread_cnt = atoi(opt->value);
+            break;
+        case 'c':  /* loop count */
+            loop_cnt = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	PR_SetConcurrency(4);
+
+    output = PR_GetSpecialFD(PR_StandardOutput);
+    errhandle = PR_GetSpecialFD(PR_StandardError);
+
+	rwlock1 = PR_NewRWLock(0,"Lock 1");
+	if (rwlock1 == NULL) {
+		PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n",
+								PR_GetError());
+		return 1;
+	}
+
+	threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
+	params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt);
+
+	/*
+	 * allocate and initialize data arrays
+	 */
+	array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
+	array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
+	array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
+	cnt = 0;
+	for (i=0; i < TEST_ARRAY_SIZE;i++) {
+		array_A[i] = cnt++;
+		array_B[i] = cnt++;
+		array_C[i] = array_A[i] + array_B[i];
+	}
+
+	if (_debug_on)
+		PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0],
+							thread_cnt, loop_cnt);
+	for(cnt = 0; cnt < thread_cnt; cnt++) {
+		PRThreadScope scope;
+
+		params[cnt].rwlock = rwlock1;
+		params[cnt].loop_cnt = loop_cnt;
+
+		/*
+		 * create LOCAL and GLOBAL threads alternately
+		 */
+		if (cnt & 1)
+			scope = PR_LOCAL_THREAD;
+		else
+			scope = PR_GLOBAL_THREAD;
+
+		threads[cnt] = PR_CreateThread(PR_USER_THREAD,
+						  rwtest, &params[cnt],
+						  PR_PRIORITY_NORMAL,
+						  scope,
+						  PR_JOINABLE_THREAD,
+						  0);
+		if (threads[cnt] == NULL) {
+			PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
+								PR_GetError());
+			PR_ProcessExit(2);
+		}
+		if (_debug_on)
+			PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0],
+										threads[cnt]);
+	}
+
+	for(cnt = 0; cnt < thread_cnt; cnt++) {
+    	rc = PR_JoinThread(threads[cnt]);
+		PR_ASSERT(rc == PR_SUCCESS);
+
+	}
+
+	PR_DELETE(threads);
+	PR_DELETE(params);
+
+	PR_DELETE(array_A);	
+	PR_DELETE(array_B);	
+	PR_DELETE(array_C);	
+
+	PR_DestroyRWLock(rwlock1);
+
+	
+	printf("PASS\n");
+	return 0;
+}
+
+static void rwtest(void *args)
+{
+    PRInt32 index;
+	thread_args *arg = (thread_args *) args;
+
+
+	for (index = 0; index < arg->loop_cnt; index++) {
+
+		/*
+		 * verify sum, update arrays and verify sum again
+		 */
+
+		PR_RWLock_Rlock(arg->rwlock);
+		check_array();
+		PR_RWLock_Unlock(arg->rwlock);
+
+		PR_RWLock_Wlock(arg->rwlock);
+		update_array();
+		PR_RWLock_Unlock(arg->rwlock);
+
+		PR_RWLock_Rlock(arg->rwlock);
+		check_array();
+		PR_RWLock_Unlock(arg->rwlock);
+	}
+	if (_debug_on)
+		PR_fprintf(output,
+		"Thread[0x%x] lock = 0x%x exiting\n",
+				PR_GetCurrentThread(), arg->rwlock);
+
+}
+
+static void check_array(void)
+{
+PRInt32 i;
+
+	for (i=0; i < TEST_ARRAY_SIZE;i++)
+		if (array_C[i] != (array_A[i] + array_B[i])) {
+			PR_fprintf(output, "Error - data check failed\n");
+			PR_ProcessExit(1);
+		}
+}
+
+static void update_array(void)
+{
+PRInt32 i;
+
+	for (i=0; i < TEST_ARRAY_SIZE;i++) {
+		array_A[i] += i;
+		array_B[i] -= i;
+	}
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sel_spd.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sel_spd.c
new file mode 100644
index 0000000..56388e6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sel_spd.c
@@ -0,0 +1,555 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Test the speed of select within NSPR
+ *
+ */
+
+#include "nspr.h"
+#include "prpriv.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#ifdef SYMBIAN
+#include <getopt.h>
+#endif
+
+#define PORT_BASE 19000
+
+typedef struct timer_slot_t {
+	unsigned long d_connect;
+	unsigned long d_cl_data;
+	unsigned long d_sv_data;
+	unsigned long d_close;
+	unsigned long d_total;
+	unsigned long requests;
+} timer_slot_t;
+
+static long _iterations = 5;
+static long _client_data = 8192;
+
+#ifdef SYMBIAN
+/*
+ * Symbian OS does not scale well specially the requirement for thread stack
+ * space and buffer allocation space.  It is easy to get into a fragmented
+ * memory and not be able to allocate thread stack or client/server data
+ * buffer.
+ */
+static long _server_data = (8*1024);
+static long _threads_max = 10, _threads = 10;
+#else
+static long _server_data = (128*1024);
+static long _threads_max = 10, _threads = 10;
+#endif
+
+static int verbose=0;
+static PRMonitor *exit_cv;
+static long _thread_exit_count;
+static timer_slot_t *timer_data;
+static PRThreadScope scope1, scope2;
+
+void tally_results(int);
+
+/* return the diff in microseconds */
+unsigned long _delta(PRIntervalTime *start, PRIntervalTime *stop)
+{
+	/*
+	 * Will C do the right thing with unsigned arithemtic?
+	 */
+	return PR_IntervalToMicroseconds(*stop - *start);
+}
+
+int _readn(PRFileDesc *sock, char *buf, int len)
+{
+	int rem;
+	int bytes;
+
+	for (rem=len; rem; rem -= bytes) {
+		bytes = PR_Recv(sock, buf+len-rem, rem, 0, PR_INTERVAL_NO_TIMEOUT);
+		if (bytes <= 0)
+            return -1;
+	}
+	return len;
+}
+
+void
+_thread_exit(int id)
+{
+	PR_EnterMonitor(exit_cv);
+#ifdef DEBUG
+	fprintf(stdout, "Thread %d EXIT\n", id);
+#endif
+
+	_thread_exit_count--;
+	if (_thread_exit_count == 0) {
+#ifdef DEBUG
+	fprintf(stdout, "Thread %d EXIT triggered notify\n", id);
+#endif
+		PR_Notify(exit_cv);
+	}
+	PR_ExitMonitor(exit_cv);
+}
+
+void
+_server_thread(void *arg_id)
+{
+	void _client_thread(void *);
+	PRThread *thread;
+	int *id =  (int *)arg_id;
+	PRFileDesc *sock;
+	PRSocketOptionData sockopt;
+	PRNetAddr sa;
+	PRFileDesc * newsock;
+	char *data_buffer = NULL;
+	int data_buffer_size;
+	int index;
+	PRIntervalTime start,
+	      connect_done,
+	      read_done,
+	      write_done,
+	      close_done;
+	
+
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d alive\n", *id);
+#endif
+
+	data_buffer_size = (_client_data>_server_data?_client_data:_server_data);
+
+	if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL ) {
+		fprintf(stderr, "Error creating buffer in server thread %d\n", *id);
+		goto done;
+	}
+
+
+	if ( (sock = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr, "Error creating socket in server thread %d\n", *id);
+		goto done;
+	}
+
+	sockopt.option = PR_SockOpt_Reuseaddr;
+	sockopt.value.reuse_addr = PR_TRUE;
+	if ( PR_SetSocketOption(sock, &sockopt) == PR_FAILURE) {
+		fprintf(stderr, "Error setting socket option in server thread %d\n", *id);
+		goto done;
+	}
+
+	memset(&sa, 0 , sizeof(sa));
+	sa.inet.family = PR_AF_INET;
+	sa.inet.port = PR_htons(PORT_BASE + *id);
+	sa.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+	if ( PR_Bind(sock, &sa) < 0) {
+		fprintf(stderr, "Error binding socket in server thread %d errno = %d\n", *id, errno);
+		goto done;
+	}
+
+	if ( PR_Listen(sock, 32) < 0 ) {
+		fprintf(stderr, "Error listening to socket in server thread %d\n", *id);
+		goto done;
+	}
+
+	/* Tell the client to start */
+	if ( (thread = PR_CreateThread(PR_USER_THREAD, 
+                                      _client_thread, 
+                                      id, 
+                                      PR_PRIORITY_NORMAL, 
+                                      scope2, 
+                                      PR_UNJOINABLE_THREAD, 
+                                      0)) == NULL)
+		fprintf(stderr, "Error creating client thread %d\n", *id);
+
+	for (index = 0; index< _iterations; index++) {
+
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d loop %d\n", *id, index);
+#endif
+
+		start = PR_IntervalNow();
+
+		if ( (newsock = PR_Accept(sock, &sa,
+					PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+			fprintf(stderr, "Error accepting connection %d in server thread %d\n",
+				index, *id);
+			goto done;
+		}
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d got connection %d\n", *id, newsock);
+#endif
+
+
+		connect_done = PR_IntervalNow();
+		
+		if ( _readn(newsock, data_buffer, _client_data) < _client_data) {
+			fprintf(stderr, "Error reading client data for iteration %d in server thread %d\n", index, *id );
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d read %d bytes\n", *id, _client_data);
+#endif
+		read_done = PR_IntervalNow();
+
+		if ( PR_Send(newsock, data_buffer, _server_data, 0,
+				PR_INTERVAL_NO_TIMEOUT) < _server_data) {
+			fprintf(stderr, "Error sending client data for iteration %d in server thread %d\n", index, *id );
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d write %d bytes\n", *id, _server_data);
+#endif
+
+		write_done = PR_IntervalNow();
+
+		PR_Close(newsock);
+
+		close_done = PR_IntervalNow();
+
+		timer_data[2*(*id)].d_connect += _delta(&start, &connect_done);
+		timer_data[2*(*id)].d_cl_data += _delta(&connect_done, &read_done);
+		timer_data[2*(*id)].d_sv_data += _delta(&read_done, &write_done);
+		timer_data[2*(*id)].d_close += _delta(&write_done, &close_done);
+		timer_data[2*(*id)].d_total += _delta(&start, &close_done);
+		timer_data[2*(*id)].requests++;
+
+
+#ifdef DEBUG
+		fprintf(stdout, "server: %d %d %d %d %d\n",
+			 _delta(&start, &connect_done), _delta(&connect_done, &read_done),
+			 _delta(&read_done, &write_done), _delta(&write_done, &close_done),
+			_delta(&start, &close_done));
+#endif
+	}
+
+done:
+	if (data_buffer != NULL) PR_Free (data_buffer);
+	if (sock) PR_Close(sock);
+	_thread_exit(*id);
+	return;
+}
+
+void
+_client_thread(void *arg_id)
+{
+	int *id =  (int *)arg_id;
+	int index;
+	PRNetAddr sa;
+	PRFileDesc *sock_h;
+	char *data_buffer = NULL;
+	int data_buffer_size;
+	int bytes;
+	PRIntervalTime start,
+	      connect_done,
+	      read_done,
+	      write_done,
+	      close_done;
+	PRStatus rv;
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d alive\n", *id);
+#endif
+
+	data_buffer_size = (_client_data>_server_data?_client_data:_server_data);
+
+	if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL) {
+		fprintf(stderr, "Error creating buffer in server thread %d\n", *id);
+		goto done;
+	}
+
+	memset(&sa, 0 , sizeof(sa));
+	rv = PR_InitializeNetAddr(PR_IpAddrLoopback, PORT_BASE + *id, &sa);
+	PR_ASSERT(PR_SUCCESS == rv);
+	
+	for (index = 0; index< _iterations; index++) {
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d loop %d\n", *id, index);
+#endif
+
+		start = PR_IntervalNow();
+		if ( (sock_h = PR_NewTCPSocket()) == NULL) {
+			fprintf(stderr, "Error creating socket %d in client thread %d\n",
+				index, *id);
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d socket created %d\n", *id, sock_h);
+#endif
+
+		if ( PR_Connect(sock_h, &sa,
+				PR_INTERVAL_NO_TIMEOUT) < 0) {
+			fprintf(stderr, "Error accepting connection %d in client thread %d\n",
+				index, *id);
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d socket connected %d\n", *id, sock_h);
+#endif
+
+		connect_done = PR_IntervalNow();
+		if ( PR_Send(sock_h, data_buffer, _client_data, 0,
+				PR_INTERVAL_NO_TIMEOUT) < _client_data) {
+			fprintf(stderr, "Error sending client data for iteration %d in client thread %d\n", index, *id );
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d socket wrote %d\n", *id, _client_data);
+#endif
+
+		write_done = PR_IntervalNow();
+		if ( (bytes = _readn(sock_h, data_buffer, _server_data)) < _server_data) {
+			fprintf(stderr, "Error reading server data for iteration %d in client thread %d (read %d bytes)\n", index, *id, bytes );
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d socket read %d\n", *id, _server_data);
+#endif
+
+		read_done = PR_IntervalNow();
+		PR_Close(sock_h);
+		close_done = PR_IntervalNow();
+
+		timer_data[2*(*id)+1].d_connect += _delta(&start, &connect_done);
+		timer_data[2*(*id)+1].d_cl_data += _delta(&connect_done, &write_done);
+		timer_data[2*(*id)+1].d_sv_data += _delta(&write_done, &read_done);
+		timer_data[2*(*id)+1].d_close += _delta(&read_done, &close_done);
+		timer_data[2*(*id)+1].d_total += _delta(&start, &close_done);
+		timer_data[2*(*id)+1].requests++;
+	}
+done:
+	if (data_buffer != NULL) PR_Free (data_buffer);
+	_thread_exit(*id);
+
+	return;
+}
+
+static
+void do_work(void)
+{
+    int index;
+
+	_thread_exit_count = _threads * 2;
+	for (index=0; index<_threads; index++) {
+		PRThread *thread;
+		int *id = (int *)PR_Malloc(sizeof(int));
+
+		*id = index;
+
+		if ( (thread = PR_CreateThread(PR_USER_THREAD, 
+                                       _server_thread, 
+                                       id, 
+                                       PR_PRIORITY_NORMAL, 
+                                       scope1, 
+                                       PR_UNJOINABLE_THREAD, 
+                                       0)) == NULL)
+			fprintf(stderr, "Error creating server thread %d\n", index);
+	}
+	
+	PR_EnterMonitor(exit_cv);
+	while (_thread_exit_count > 0)
+		PR_Wait(exit_cv, PR_INTERVAL_NO_TIMEOUT);
+	PR_ExitMonitor(exit_cv);
+
+	fprintf(stdout, "TEST COMPLETE!\n");
+
+	tally_results(verbose);
+
+}
+
+static void do_workUU(void)
+{
+    scope1 = PR_LOCAL_THREAD;
+    scope2 = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workUK(void)
+{
+    scope1 = PR_LOCAL_THREAD;
+    scope2 = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+static void do_workKU(void)
+{
+    scope1 = PR_GLOBAL_THREAD;
+    scope2 = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workKK(void)
+{
+    scope1 = PR_GLOBAL_THREAD;
+    scope2 = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    printf("%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+int main(int argc, char **argv)
+{
+#if defined(XP_UNIX) || defined(XP_OS2)
+	int opt;
+	PR_IMPORT_DATA(char *) optarg;
+#endif
+
+#if defined(XP_UNIX) || defined(XP_OS2)
+	while ( (opt = getopt(argc, argv, "c:s:i:t:v")) != EOF) {
+		switch(opt) {
+			case 'i':
+				_iterations = atoi(optarg);
+				break;
+			case 't':
+				_threads_max = _threads = atoi(optarg);
+				break;
+			case 'c':
+				_client_data = atoi(optarg);
+				break;
+			case 's':
+				_server_data = atoi(optarg);
+				break;
+			case 'v':
+				verbose = 1;
+				break;
+			default: 
+				break;
+		}
+	}
+#endif
+
+	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+	fprintf(stdout, "Running test for %d iterations with %d simultaneous threads.\n", 
+		_iterations, _threads);
+	fprintf(stdout, "\tWill send %d bytes of client data and %d bytes of server data\n", 
+		_client_data, _server_data);
+
+	if ( (exit_cv = PR_NewMonitor()) == NULL) 
+		fprintf(stderr, "Error creating monitor for exit cv\n");
+	if ( (timer_data = (timer_slot_t *)PR_Malloc(2*_threads * sizeof(timer_slot_t))) == NULL) 
+		fprintf(stderr, "error allocating thread time results array\n");
+	memset(timer_data, 0 , 2*_threads*sizeof(timer_slot_t));
+
+    Measure(do_workUU, "select loop user/user");
+    Measure(do_workUK, "select loop user/kernel");
+    Measure(do_workKU, "select loop kernel/user");
+    Measure(do_workKK, "select loop kernel/kernel");
+
+
+	return 0;
+}
+
+void
+tally_results(int verbose)
+{
+	int index;
+	unsigned long tot_connect = 0;
+	unsigned long tot_cl_data = 0;
+	unsigned long tot_sv_data = 0;
+	unsigned long tot_close = 0;
+	unsigned long tot_all = 0;
+	unsigned long tot_requests = 0;
+
+	fprintf(stdout, "Server results:\n\n");
+	for (index=0; index<_threads_max*2; index+=2) {
+
+		if (verbose)
+			fprintf(stdout, "server thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n",
+				index, timer_data[index].requests, timer_data[index].d_connect,
+				timer_data[index].d_cl_data, timer_data[index].d_sv_data,
+				timer_data[index].d_close, timer_data[index].d_total);
+
+		tot_connect += timer_data[index].d_connect / _threads;
+		tot_cl_data += timer_data[index].d_cl_data / _threads;
+		tot_sv_data += timer_data[index].d_sv_data / _threads;
+		tot_close += timer_data[index].d_close / _threads;
+		tot_all += timer_data[index].d_total / _threads;
+		tot_requests += timer_data[index].requests / _threads;
+	}
+	fprintf(stdout, "----------\n");
+	fprintf(stdout, "server per thread totals %u\t%u\t%u\t%u\t%u\n",
+		tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close);
+	fprintf(stdout, "server per thread elapsed time %u\n", tot_all);
+	fprintf(stdout, "----------\n");
+
+	tot_connect = tot_cl_data = tot_sv_data = tot_close = tot_all = tot_requests = 0;
+	fprintf(stdout, "Client results:\n\n");
+	for (index=1; index<_threads_max*2; index+=2) {
+
+		if (verbose)
+			fprintf(stdout, "client thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n",
+				index, timer_data[index].requests, timer_data[index].d_connect,
+				timer_data[index].d_cl_data, timer_data[index].d_sv_data,
+				timer_data[index].d_close, timer_data[index].d_total);
+
+		tot_connect += timer_data[index].d_connect / _threads;
+		tot_cl_data += timer_data[index].d_cl_data / _threads;
+		tot_sv_data += timer_data[index].d_sv_data / _threads;
+		tot_close += timer_data[index].d_close / _threads;
+		tot_all += timer_data[index].d_total / _threads;
+		tot_requests += timer_data[index].requests / _threads;
+	}
+	fprintf(stdout, "----------\n");
+	fprintf(stdout, "client per thread totals %u\t%u\t%u\t%u\t%u\n",
+		tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close);
+	fprintf(stdout, "client per thread elapsed time %u\n", tot_all);
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_er.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_er.c
new file mode 100755
index 0000000..2a5b8b2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_er.c
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1997 - Netscape Communications Corporation
+**
+** Name: prselect_err.c
+**
+** Description: tests PR_Select with sockets Error condition functions.
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+#ifdef XP_BEOS
+#include <stdio.h>
+int main()
+{
+    printf( "This test is not ported to the BeOS\n" );
+    return 0;
+}
+#else
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "primpl.h"
+#include "pprio.h"
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *badFD;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    PR_fd_set readFdSet;
+    char buf[128];
+    PRInt32 retVal;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Select with sockets.  Error\n");
+		printf("reporting operations are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the fd set */
+    PR_FD_ZERO(&readFdSet);
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+
+    /* Testing bad fd */
+    if (debug_mode) printf("PR_Select should detect a bad file descriptor\n");
+    if ((badFD = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    PR_FD_SET(badFD, &readFdSet);
+    /*
+     * Make the fd invalid
+     */
+#if defined(XP_UNIX)
+    close(PR_FileDesc2NativeHandle(badFD));
+#elif defined(XP_OS2)
+    soclose(PR_FileDesc2NativeHandle(badFD));
+#elif defined(WIN32) || defined(WIN16)
+    closesocket(PR_FileDesc2NativeHandle(badFD));
+#else
+#error "Unknown architecture"
+#endif
+
+    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+	    PR_INTERVAL_NO_TIMEOUT);
+    if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) {
+	fprintf(stderr, "Failed to detect the bad fd: "
+		"PR_Select returns %d\n", retVal);
+	if (retVal == -1) {
+	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
+		    PR_GetOSError());
+		failed_already=1;
+	}
+	goto exit_now;
+    }
+    if (debug_mode) printf("PR_Select detected a bad fd.  Test passed.\n\n");
+	PR_FD_CLR(badFD, &readFdSet);
+
+	PR_Cleanup();
+	goto exit_now;
+exit_now:
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+
+}
+
+#endif /* XP_BEOS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_nm.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_nm.c
new file mode 100644
index 0000000..62927c9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_nm.c
@@ -0,0 +1,316 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1997 - Netscape Communications Corporation
+**
+** Name: prselect_norm.c
+**
+** Description: tests PR_Select with sockets - Normal operations.
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prerror.h"
+#include "prnetdb.h"
+
+#include "obsolete/probslet.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static void
+clientThreadFunc(void *arg)
+{
+    PRUintn port = (PRUintn) arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[128];
+    int i;
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons((PRUint16)port);
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port);
+
+    for (i = 0; i < 5; i++) {
+	sock = PR_NewTCPSocket();
+        PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+	PR_Write(sock, buf, sizeof(buf));
+	PR_Close(sock);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds;
+    PRIntn nfds;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    PR_fd_set readFdSet;
+    char buf[128];
+    PRThread *clientThread;
+    PRInt32 retVal;
+    PRIntn i, j;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Select with sockets.  \n");
+		printf(" Normal operation are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+failed_already=1;
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort1,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort2,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if (debug_mode) {
+		printf("Two client threads are created.  Each of them will\n");
+		printf("send data to one of the two ports the server is listening on.\n");
+		printf("The data they send is the port number.  Each of them send\n");
+		printf("the data five times, so you should see ten lines below,\n");
+		printf("interleaved in an arbitrary order.\n");
+	}
+    /* set up the fd array */
+    fds = fds0;
+    other_fds = fds1;
+    fds[0] = listenSock1;
+    fds[1] = listenSock2;
+    nfds = 2;
+    /* Set up the fd set */
+    PR_FD_ZERO(&readFdSet);
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+    /* 20 events total */
+    i = 0;
+    while (i < 20) {
+	PRFileDesc **tmp;
+	int nextIndex;
+	int nEvents = 0;
+
+	retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+		PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(retVal != 0);  /* no timeout */
+	if (retVal == -1) {
+	    fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(),
+		    PR_GetOSError());
+	failed_already=1;
+	    goto exit_now;
+	}
+
+	nextIndex = 2;
+	/* the two listening sockets */
+	for (j = 0; j < 2; j++) {
+	    other_fds[j] = fds[j];
+	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
+		PRFileDesc *sock;
+
+		nEvents++;
+		sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT);
+		if (sock == NULL) {
+		    fprintf(stderr, "PR_Accept() failed\n");
+		failed_already=1;
+		    goto exit_now;
+		}
+		other_fds[nextIndex] = sock;
+		PR_FD_SET(sock, &readFdSet);
+		nextIndex++;
+	    }
+	    PR_FD_SET(fds[j], &readFdSet);
+	}
+
+	for (j = 2; j < nfds; j++) {
+	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
+		PRInt32 nBytes;
+
+		PR_FD_CLR(fds[j], &readFdSet);
+		nEvents++;
+		nBytes = PR_Read(fds[j], buf, sizeof(buf));
+		if (nBytes == -1) {
+		    fprintf(stderr, "PR_Read() failed\n");
+		failed_already=1;
+		    goto exit_now;
+		}
+		/* Just to be safe */
+		buf[127] = '\0';
+		PR_Close(fds[j]);
+		if (debug_mode) printf("The server received \"%s\" from a client\n", buf);
+	    } else {
+		PR_FD_SET(fds[j], &readFdSet);
+		other_fds[nextIndex] = fds[j];
+		nextIndex++;
+	    }
+	}
+
+	PR_ASSERT(retVal == nEvents);
+	/* swap */
+	tmp = fds;
+	fds = other_fds;
+	other_fds = tmp;
+	nfds = nextIndex;
+	i += nEvents;
+    }
+
+    if (debug_mode) printf("Test passed\n");
+
+    PR_Cleanup();
+	goto exit_now;
+exit_now:
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_to.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_to.c
new file mode 100644
index 0000000..2a58d65
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/selct_to.c
@@ -0,0 +1,204 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**  1997 - Netscape Communications Corporation
+**
+** Name: prselect_to.c
+**
+** Description: tests PR_Select with sockets. Time out functions
+**
+** Modification History:
+** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+
+#include "obsolete/probslet.h"
+
+#include "prerror.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    PR_fd_set readFdSet;
+    char buf[128];
+    PRInt32 retVal;
+
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Select with sockets.  Timeout \n");
+		printf("operations are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the fd set */
+    PR_FD_ZERO(&readFdSet);
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+    /* Testing timeout */
+    if (debug_mode) printf("PR_Select should time out in 5 seconds\n");
+    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+	    PR_SecondsToInterval(5));
+    if (retVal != 0) {
+	PR_snprintf(buf, sizeof(buf),
+		"PR_Select should time out and return 0, but it returns %ld\n",
+		retVal);
+	fprintf(stderr, "%s", buf);
+	if (retVal == -1) {
+	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
+		    PR_GetOSError());
+			failed_already=1;
+	}
+	goto exit_now;
+    }
+    if (debug_mode) printf("PR_Select timed out.  Test passed.\n\n");
+
+    PR_Cleanup();
+
+exit_now:
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/select2.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/select2.c
new file mode 100644
index 0000000..775a1e1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/select2.c
@@ -0,0 +1,354 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: select2.c
+**
+** Description: Measure PR_Select and Empty_Select performance.
+**
+** Modification History:
+** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include "prttools.h"
+#include "primpl.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(OS2)
+#include <sys/time.h>
+#endif
+
+#define PORT 8000
+#define DEFAULT_COUNT 10
+PRInt32 count;
+
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**				status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static void Test_Result (int result)
+{
+	switch (result)
+	{
+		case PASS:
+			printf ("PASS\n");
+			break;
+		case FAIL:
+			printf ("FAIL\n");
+			break;
+		default:
+			printf ("NOSTATUS\n");
+			break;
+	}
+}
+
+static void EmptyPRSelect(void)
+{
+    PRInt32 index = count;
+    PRInt32 rv;
+
+    for (; index--;)
+        rv = PR_Select(0, NULL, NULL, NULL, PR_INTERVAL_NO_WAIT);
+}
+
+static void EmptyNativeSelect(void)
+{
+    PRInt32 rv;
+    PRInt32 index = count;
+    struct timeval timeout;
+
+    timeout.tv_sec = timeout.tv_usec = 0;
+    for (; index--;)
+        rv = select(0, NULL, NULL, NULL, &timeout);
+}
+
+static void PRSelectTest(void)
+{
+    PRFileDesc *listenSocket;
+    PRNetAddr serverAddr;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+        return;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address\n");
+        PR_Close(listenSocket);
+        return;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+        PR_Close(listenSocket);
+        return;
+    }
+    if (debug_mode) printf("Listening on port %d\n", PORT);
+
+    {
+        PRFileDesc *newSock;
+        PRNetAddr rAddr;
+        PRInt32 loops = 0;
+        PR_fd_set rdset;
+        PRInt32 rv;
+        PRInt32 bytesRead;
+        char buf[11];
+
+        loops++;
+
+        if (debug_mode) printf("Going into accept\n"); 
+
+        newSock = PR_Accept(listenSocket, 
+                              &rAddr,
+                              PR_INTERVAL_NO_TIMEOUT);
+
+	if (newSock) {
+            if (debug_mode) printf("Got connection!\n");
+        } else {
+	    if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError());
+		else Test_Result (FAIL);
+        }
+
+        PR_FD_ZERO(&rdset);
+        PR_FD_SET(newSock, &rdset);
+
+        if (debug_mode) printf("Going into select \n");
+
+        rv = PR_Select(0, &rdset, 0, 0, PR_INTERVAL_NO_TIMEOUT);
+
+        if (debug_mode) printf("return from select is %d\n", rv);
+
+        if (PR_FD_ISSET(newSock, &rdset)) {
+            if (debug_mode) printf("I can't believe it- the socket is ready okay!\n");
+        } else {
+            if (debug_mode) printf("Damn; the select test failed...\n");
+			else Test_Result (FAIL);
+        }
+
+        strcpy(buf, "XXXXXXXXXX");
+        bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT);
+	buf[10] = '\0';
+
+        if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf);
+
+        PR_Close(newSock);
+    }
+
+}
+
+#if defined(XP_UNIX)
+
+static void NativeSelectTest(void)
+{
+    PRFileDesc *listenSocket;
+    PRNetAddr serverAddr;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+        return;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address\n");
+        PR_Close(listenSocket);
+        return;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+        PR_Close(listenSocket);
+        return;
+    }
+    if (debug_mode) printf("Listening on port %d\n", PORT);
+
+    {
+        PRIntn osfd;
+        char buf[11];
+        fd_set rdset;
+        PRNetAddr rAddr;
+        PRFileDesc *newSock;
+        struct timeval timeout;
+        PRInt32 bytesRead, rv, loops = 0;
+
+        loops++;
+
+        if (debug_mode) printf("Going into accept\n"); 
+
+        newSock = PR_Accept(listenSocket, &rAddr, PR_INTERVAL_NO_TIMEOUT);
+
+	if (newSock) {
+            if (debug_mode) printf("Got connection!\n");
+        } else {
+	    if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError());
+		else Test_Result (FAIL);
+        }
+
+        osfd = PR_FileDesc2NativeHandle(newSock);
+        FD_ZERO(&rdset);
+        FD_SET(osfd, &rdset);
+
+        if (debug_mode) printf("Going into select \n");
+
+
+        timeout.tv_sec = 2; timeout.tv_usec = 0;
+        rv = select(osfd + 1, &rdset, NULL, NULL, &timeout);
+
+        if (debug_mode) printf("return from select is %d\n", rv);
+
+        if (FD_ISSET(osfd, &rdset)) {
+            if (debug_mode)
+                printf("I can't believe it- the socket is ready okay!\n");
+        } else {
+            if (debug_mode) printf("Damn; the select test failed...\n");
+			else Test_Result (FAIL);
+        }
+
+        strcpy(buf, "XXXXXXXXXX");
+        bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT);
+	buf[10] = '\0';
+
+        if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf);
+
+        PR_Close(newSock);
+    }
+
+}  /* NativeSelectTest */
+
+#endif /* defined(XP_UNIX) */
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+    PRInt32 tot;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+    tot = PR_IntervalToMilliseconds(stop-start);
+
+    if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot);
+}
+
+int main(int argc, char **argv)
+{
+	
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 2) {
+	count = atoi(argv[2]);
+    } else {
+	count = DEFAULT_COUNT;
+    }
+
+#if defined(XP_UNIX)
+    Measure(NativeSelectTest, "time to call 1 element select()");
+#endif
+    Measure(EmptyPRSelect, "time to call Empty PR_select()");
+    Measure(EmptyNativeSelect, "time to call Empty select()");
+    Measure(PRSelectTest, "time to call 1 element PR_select()");
+
+	if (!debug_mode) Test_Result (NOSTATUS);
+    PR_Cleanup();
+
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/selintr.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/selintr.c
new file mode 100644
index 0000000..02a63a8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/selintr.c
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Test whether classic NSPR's select() wrapper properly blocks
+ * the periodic SIGALRM clocks.  On some platforms (such as
+ * HP-UX and SINIX) an interrupted select() system call is
+ * restarted with the originally specified timeout, ignoring
+ * the time that has elapsed.  If a select() call is interrupted
+ * repeatedly, it will never time out.  (See Bugzilla bug #39674.)
+ */
+
+#if !defined(XP_UNIX)
+
+/*
+ * This test is applicable to Unix only.
+ */
+
+int main()
+{
+    return 0;
+}
+
+#else /* XP_UNIX */
+
+#include "nspr.h"
+
+#include <sys/time.h>
+#include <stdio.h>
+#ifdef SYMBIAN
+#include <sys/select.h>
+#endif
+
+int main(int argc, char **argv)
+{
+    struct timeval timeout;
+    int rv;
+
+    PR_SetError(0, 0);  /* force NSPR to initialize */
+    PR_EnableClockInterrupts();
+
+    /* 2 seconds timeout */
+    timeout.tv_sec = 2;
+    timeout.tv_usec = 0;
+    rv = select(1, NULL, NULL, NULL, &timeout);
+    printf("select returned %d\n", rv);
+    return 0;
+}
+
+#endif /* XP_UNIX */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sem.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sem.c
new file mode 100644
index 0000000..83e872c
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sem.c
@@ -0,0 +1,241 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: sem.c
+**
+** Description: Tests Semaphonre functions.
+**
+** Modification History:
+** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "prpriv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+/* 
+	Since we don't have stdin, stdout everywhere, we will fake 
+	it with our in-memory buffers called stdin and stdout.
+*/
+
+#define SBSIZE 1024
+
+#include "obsolete/prsem.h"
+
+static char stdinBuf[SBSIZE];
+static char stdoutBuf[SBSIZE];
+
+static PRUintn stdinBufIdx = 0;
+static PRUintn stdoutBufIdx = 0;
+static PRStatus finalResult = PR_SUCCESS;
+
+
+static size_t dread (PRUintn device, char *buf, size_t bufSize)
+{
+	PRUintn	i;
+	
+	/* during first read call, initialize the stdinBuf buffer*/
+	if (stdinBufIdx == 0) {
+		for (i=0; i<SBSIZE; i++)
+			stdinBuf[i] = i;
+	}
+
+	/* now copy data from stdinBuf to the given buffer upto bufSize */
+	for (i=0; i<bufSize; i++) {
+		if (stdinBufIdx == SBSIZE)
+			break;
+		buf[i] = stdinBuf[stdinBufIdx++];
+	}
+
+	return i;
+}
+
+static size_t dwrite (PRUintn device, char *buf, size_t bufSize)
+{
+	PRUintn	i, j;
+	
+	/* copy data from the given buffer upto bufSize to stdoutBuf */
+	for (i=0; i<bufSize; i++) {
+		if (stdoutBufIdx == SBSIZE)
+			break;
+		stdoutBuf[stdoutBufIdx++] = buf[i];
+	}
+
+	/* during last write call, compare the two buffers */
+	if (stdoutBufIdx == SBSIZE)
+		for (j=0; j<SBSIZE; j++)
+			if (stdinBuf[j] != stdoutBuf[j]) {
+				if (debug_mode) printf("data mismatch for index= %d \n", j);
+				finalResult = PR_FAILURE;
+			}
+
+	return i;
+}
+
+/*------------------ Following is the real test program ---------*/
+/*
+	Program to copy standard input to standard output.  The program
+	uses two threads.  One reads the input and puts the data in a 
+	double buffer.  The other reads the buffer contents and writes 
+	it to standard output.
+*/
+
+PRSemaphore	*emptyBufs;	/* number of empty buffers */
+PRSemaphore *fullBufs;	/* number of buffers that are full */
+
+#define BSIZE	100
+
+struct {
+	char data[BSIZE];
+	PRUintn nbytes;		/* number of bytes in this buffer */
+} buf[2];
+
+static void PR_CALLBACK reader(void *arg)
+{
+	PRUintn	i = 0;
+	size_t	nbytes;
+	
+	do {
+		(void) PR_WaitSem(emptyBufs);
+		nbytes = dread(0, buf[i].data, BSIZE);
+		buf[i].nbytes = nbytes;
+		PR_PostSem(fullBufs);
+		i = (i + 1) % 2;
+	} while (nbytes > 0);
+}
+
+static void writer(void)
+{
+	PRUintn	i = 0;
+	size_t	nbytes;
+	
+	do {
+		(void) PR_WaitSem(fullBufs);
+		nbytes = buf[i].nbytes;
+		if (nbytes > 0) {
+			nbytes = dwrite(1, buf[i].data, nbytes);
+			PR_PostSem(emptyBufs);
+			i = (i + 1) % 2;
+		}
+	} while (nbytes > 0);
+}
+
+int main(int argc, char **argv)
+{
+	PRThread *r;
+
+    PR_STDIO_INIT();
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+    {
+    	/* The command line argument: -d is used to determine if the test is being run
+    	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+    	All of the printfs associated with this test has been handled with a if (debug_mode)
+    	test.
+    	Usage: test_name -d
+    	*/
+    	PLOptStatus os;
+    	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+    	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+    		if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug mode */
+    			debug_mode = 1;
+                break;
+             default:
+                break;
+            }
+        }
+    	PL_DestroyOptState(opt);
+    }        
+
+ /* main test */
+
+    emptyBufs = PR_NewSem(2);	/* two empty buffers */
+
+    fullBufs = PR_NewSem(0);	/* zero full buffers */
+
+	/* create the reader thread */
+	
+	r = PR_CreateThread(PR_USER_THREAD,
+				      reader, 0, 
+				      PR_PRIORITY_NORMAL,
+				      PR_LOCAL_THREAD,
+    				  PR_UNJOINABLE_THREAD,
+				      0);
+
+	/* Do the writer operation in this thread */
+	writer();
+
+	PR_DestroySem(emptyBufs);
+	PR_DestroySem(fullBufs);
+
+	if (finalResult == PR_SUCCESS) {
+		if (debug_mode) printf("sem Test Passed.\n");
+	}
+	else{
+		if (debug_mode) printf("sem Test Failed.\n");
+		failed_already=1;
+	}
+    PR_Cleanup();
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sema.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sema.c
new file mode 100644
index 0000000..3dff8a0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sema.c
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_NAME2 "/tmp/bar.sem"
+#define SEM_MODE  0666
+#define ITERATIONS 1000
+
+static PRBool debug_mode = PR_FALSE;
+static PRIntn iterations = ITERATIONS;
+static PRIntn counter;
+static PRSem *sem1, *sem2;
+
+/*
+ * Thread 2 waits on semaphore 2 and posts to semaphore 1.
+ */
+void ThreadFunc(void *arg)
+{
+    PRIntn i;
+
+    for (i = 0; i < iterations; i++) {
+        if (PR_WaitSemaphore(sem2) == PR_FAILURE) {
+            fprintf(stderr, "PR_WaitSemaphore failed\n");
+            exit(1);
+        }
+        if (counter == 2*i+1) {
+            if (debug_mode) printf("thread 2: counter = %d\n", counter);
+        } else {
+            fprintf(stderr, "thread 2: counter should be %d but is %d\n",
+                    2*i+1, counter);
+            exit(1);
+        }
+        counter++;
+        if (PR_PostSemaphore(sem1) == PR_FAILURE) {
+            fprintf(stderr, "PR_PostSemaphore failed\n");
+            exit(1);
+        }
+    }
+}
+
+static void Help(void)
+{
+    fprintf(stderr, "sema test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-c <count>   loop count         (%d)\n", ITERATIONS);
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRThread *thred;
+    PRIntn i;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop count */
+                iterations = atoi(opt->value);
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed semaphore %s left over "
+                "from previous run\n", SEM_NAME1);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed semaphore %s left over "
+                "from previous run\n", SEM_NAME2);
+    }
+
+    sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1);
+    if (NULL == sem1) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0);
+    if (NULL == sem2) {
+        fprintf(stderr, "PR_OpenSemaphore failed\n");
+        exit(1);
+    }
+    thred = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == thred) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+
+    /*
+     * Thread 1 waits on semaphore 1 and posts to semaphore 2.
+     */
+    for (i = 0; i < iterations; i++) {
+        if (PR_WaitSemaphore(sem1) == PR_FAILURE) {
+            fprintf(stderr, "PR_WaitSemaphore failed\n");
+            exit(1);
+        }
+        if (counter == 2*i) {
+            if (debug_mode) printf("thread 1: counter = %d\n", counter);
+        } else {
+            fprintf(stderr, "thread 1: counter should be %d but is %d\n",
+                    2*i, counter);
+            exit(1);
+        }
+        counter++;
+        if (PR_PostSemaphore(sem2) == PR_FAILURE) {
+            fprintf(stderr, "PR_PostSemaphore failed\n");
+            exit(1);
+        }
+    }
+
+    if (PR_JoinThread(thred) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+    if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+    }
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaerr.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaerr.c
new file mode 100644
index 0000000..8619c0a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaerr.c
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#ifdef SYMBIAN
+#define NO_SUCH_SEM_NAME "c:\\data\\nosuchsem.sem"
+#define SEM_NAME1 "c:\\data\\foo.sem"
+#define EXE_NAME "nspr_tests_semaerr1.exe"
+#else
+#define NO_SUCH_SEM_NAME "/tmp/nosuchsem.sem"
+#define SEM_NAME1 "/tmp/foo.sem"
+#define EXE_NAME "semaerr1"
+#endif
+#define SEM_MODE  0666
+
+static PRBool debug_mode = PR_FALSE;
+
+static void Help(void)
+{
+    fprintf(stderr, "semaerr test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dh");
+    PRSem *sem;
+    char *child_argv[32];
+    char **child_arg;
+    PRProcess *proc;
+    PRInt32 exit_code;
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    /*
+     * Open a nonexistent semaphore without the PR_SEM_CREATE
+     * flag should fail with PR_FILE_NOT_FOUND_ERROR.
+     */
+    (void) PR_DeleteSemaphore(NO_SUCH_SEM_NAME);
+    sem = PR_OpenSemaphore(NO_SUCH_SEM_NAME, 0, 0, 0);
+    if (NULL != sem) {
+        fprintf(stderr, "Opening nonexistent semaphore %s "
+                "without the PR_SEM_CREATE flag should fail "
+                "but succeeded\n", NO_SUCH_SEM_NAME);
+        exit(1);
+    }
+    if (PR_GetError() != PR_FILE_NOT_FOUND_ERROR) {
+        fprintf(stderr, "Expected error is %d but got (%d, %d)\n",
+                PR_FILE_NOT_FOUND_ERROR, PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+
+    /*
+     * Create a semaphore and let the another process
+     * try PR_SEM_CREATE and PR_SEM_CREATE|PR_SEM_EXCL.
+     */
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
+        fprintf(stderr, "warning: deleted semaphore %s from previous "
+                "run of the test\n", SEM_NAME1);
+    }
+    sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0);
+    if (sem == NULL) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    child_arg = child_argv;
+    *child_arg++ = EXE_NAME;
+    if (debug_mode) {
+        *child_arg++ = "-d";
+    }
+    *child_arg = NULL;
+    proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
+    if (proc == NULL) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+    if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exit_code != 0) {
+        fprintf(stderr, "process semaerr1 failed\n");
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+        exit(1);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaerr1.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaerr1.c
new file mode 100644
index 0000000..6164e0a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaerr1.c
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#ifdef SYMBIAN
+#define SEM_NAME1 "c:\\data\\foo.sem"
+#define SEM_NAME2 "c:\\data\\bar.sem"
+#else
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_NAME2 "/tmp/bar.sem"
+#endif
+#define SEM_MODE  0666
+
+static PRBool debug_mode = PR_FALSE;
+
+static void Help(void)
+{
+    fprintf(stderr, "semaerr1 test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dh");
+    PRSem *sem;
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    /*
+     * PR_SEM_CREATE|PR_SEM_EXCL should be able to
+     * create a nonexistent semaphore.
+     */
+    (void) PR_DeleteSemaphore(SEM_NAME2);
+    sem = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0);
+    if (sem == NULL) {
+        fprintf(stderr, "PR_OpenSemaphore failed\n");
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+        exit(1);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+        exit(1);
+    }
+    
+    /*
+     * Opening an existing semaphore with PR_SEM_CREATE|PR_SEM_EXCL.
+     * should fail with PR_FILE_EXISTS_ERROR.
+     */
+    sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0);
+    if (sem != NULL) {
+        fprintf(stderr, "PR_OpenSemaphore should fail but succeeded\n");
+        exit(1);
+    }
+    if (PR_GetError() != PR_FILE_EXISTS_ERROR) {
+        fprintf(stderr, "Expect %d but got %d\n", PR_FILE_EXISTS_ERROR,
+                PR_GetError());
+        exit(1);
+    }
+
+    /*
+     * Try again, with just PR_SEM_CREATE.  This should succeed.
+     */
+    sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0);
+    if (sem == NULL) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+        exit(1);
+    }
+
+    sem = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0);
+    if (sem == NULL) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaping.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaping.c
new file mode 100644
index 0000000..6ad6773
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/semaping.c
@@ -0,0 +1,211 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#ifdef SYMBIAN
+#define SHM_NAME "c:\\data\\counter"
+#define SEM_NAME1 "c:\\data\\foo.sem"
+#define SEM_NAME2 "c:\\data\\bar.sem"
+#define EXE_NAME "nspr_tests_semapong.exe"
+#else
+#define SHM_NAME "/tmp/counter"
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_NAME2 "/tmp/bar.sem"
+#define EXE_NAME "semapong"
+#endif
+#define SEM_MODE  0666
+#define SHM_MODE  0666
+#define ITERATIONS 1000
+
+static PRBool debug_mode = PR_FALSE;
+static PRIntn iterations = ITERATIONS;
+static PRSem *sem1, *sem2;
+
+static void Help(void)
+{
+    fprintf(stderr, "semaping test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-c <count>   loop count         (%d)\n", ITERATIONS);
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRProcess *proc;
+    PRIntn i;
+    char *child_argv[32];
+    char **child_arg;
+    char iterations_buf[32];
+    PRSharedMemory *shm;
+    PRIntn *counter_addr;
+    PRInt32 exit_code;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop count */
+                iterations = atoi(opt->value);
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (PR_DeleteSharedMemory(SHM_NAME) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed shared memory %s left over "
+                "from previous run\n", SHM_NAME);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed semaphore %s left over "
+                "from previous run\n", SEM_NAME1);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed semaphore %s left over "
+                "from previous run\n", SEM_NAME2);
+    }
+
+    shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), PR_SHM_CREATE, SHM_MODE);
+    if (NULL == shm) {
+        fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    counter_addr = PR_AttachSharedMemory(shm, 0);
+    if (NULL == counter_addr) {
+        fprintf(stderr, "PR_AttachSharedMemory failed\n");
+        exit(1);
+    }
+    *counter_addr = 0;
+    sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1);
+    if (NULL == sem1) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0);
+    if (NULL == sem2) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+
+    child_arg = &child_argv[0];
+    *child_arg++ = EXE_NAME;
+    if (debug_mode != PR_FALSE) {
+        *child_arg++ = "-d";
+    }
+    if (iterations != ITERATIONS) {
+        *child_arg++ = "-c";
+        PR_snprintf(iterations_buf, sizeof(iterations_buf), "%d", iterations);
+        *child_arg++ = iterations_buf;
+    }
+    *child_arg = NULL;
+    proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
+    if (NULL == proc) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+
+    /*
+     * Process 1 waits on semaphore 1 and posts to semaphore 2.
+     */
+    for (i = 0; i < iterations; i++) {
+        if (PR_WaitSemaphore(sem1) == PR_FAILURE) {
+            fprintf(stderr, "PR_WaitSemaphore failed\n");
+            exit(1);
+        }
+        if (*counter_addr == 2*i) {
+            if (debug_mode) printf("process 1: counter = %d\n", *counter_addr);
+        } else {
+            fprintf(stderr, "process 1: counter should be %d but is %d\n",
+                    2*i, *counter_addr);
+            exit(1);
+        }
+        (*counter_addr)++;
+        if (PR_PostSemaphore(sem2) == PR_FAILURE) {
+            fprintf(stderr, "PR_PostSemaphore failed\n");
+            exit(1);
+        }
+    }
+    if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_DetachSharedMemory failed\n");
+        exit(1);
+    }
+    if (PR_CloseSharedMemory(shm) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSharedMemory failed\n");
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+
+    if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exit_code != 0) {
+        fprintf(stderr, "process 2 failed with exit code %d\n", exit_code);
+        exit(1);
+    }
+
+    if (PR_DeleteSharedMemory(SHM_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSharedMemory failed\n");
+    }
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+    }
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/semapong.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/semapong.c
new file mode 100644
index 0000000..f74709a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/semapong.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#ifdef SYMBIAN
+#define SHM_NAME "c:\\data\\counter"
+#define SEM_NAME1 "c:\\data\\foo.sem"
+#define SEM_NAME2 "c:\\data\\bar.sem"
+#else
+#define SHM_NAME "/tmp/counter"
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_NAME2 "/tmp/bar.sem"
+#endif
+#define ITERATIONS 1000
+
+static PRBool debug_mode = PR_FALSE;
+static PRIntn iterations = ITERATIONS;
+static PRSem *sem1, *sem2;
+
+static void Help(void)
+{
+    fprintf(stderr, "semapong test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-c <count>   loop count         (%d)\n", ITERATIONS);
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRIntn i;
+    PRSharedMemory *shm;
+    PRIntn *counter_addr;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop count */
+                iterations = atoi(opt->value);
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), 0, 0666);
+    if (NULL == shm) {
+        fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    sem1 = PR_OpenSemaphore(SEM_NAME1, 0, 0, 0);
+    if (NULL == sem1) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    sem2 = PR_OpenSemaphore(SEM_NAME2, 0, 0, 0);
+    if (NULL == sem2) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+
+    counter_addr = PR_AttachSharedMemory(shm, 0);
+    if (NULL == counter_addr) {
+        fprintf(stderr, "PR_AttachSharedMemory failed\n");
+        exit(1);
+    }
+
+    /*
+     * Process 2 waits on semaphore 2 and posts to semaphore 1.
+     */
+    for (i = 0; i < iterations; i++) {
+        if (PR_WaitSemaphore(sem2) == PR_FAILURE) {
+            fprintf(stderr, "PR_WaitSemaphore failed\n");
+            exit(1);
+        }
+        if (*counter_addr == 2*i+1) {
+            if (debug_mode) printf("process 2: counter = %d\n", *counter_addr);
+        } else {
+            fprintf(stderr, "process 2: counter should be %d but is %d\n",
+                    2*i+1, *counter_addr);
+            exit(1);
+        }
+        (*counter_addr)++;
+        if (PR_PostSemaphore(sem1) == PR_FAILURE) {
+            fprintf(stderr, "PR_PostSemaphore failed\n");
+            exit(1);
+        }
+    }
+    if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_DetachSharedMemory failed\n");
+        exit(1);
+    }
+    if (PR_CloseSharedMemory(shm) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSharedMemory failed\n");
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sendzlf.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sendzlf.c
new file mode 100644
index 0000000..3d47365
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sendzlf.c
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Test: sendzlf.c 
+ *
+ * Description: send a zero-length file with PR_SendFile and
+ * PR_TransmitFile.
+ */
+
+#define ZERO_LEN_FILE_NAME "zerolen.tmp"
+#define HEADER_STR "Header"
+#define HEADER_LEN 6 /* length of HEADER_STR, not counting the null byte */
+#define TRAILER_STR "Trailer"
+#define TRAILER_LEN 7 /* length of TRAILER_STR, not counting the null byte */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void ClientThread(void *arg)
+{
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    PRUint16 port = (PRUint16) arg;
+    char buf[1024];
+    char *bufPtr;
+    PRInt32 nbytes;
+    PRInt32 ntotal;
+    PRInt32 nexpected;
+
+    sock = PR_NewTCPSocket();
+    if (NULL == sock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+        fprintf(stderr, "PR_Connect failed\n");
+        exit(1);
+    }
+    ntotal = 0;
+    bufPtr = buf;
+    while ((nbytes = PR_Read(sock, bufPtr, sizeof(buf)-ntotal)) > 0) {
+        ntotal += nbytes;
+        bufPtr += nbytes;
+    }
+    if (-1 == nbytes) {
+        fprintf(stderr, "PR_Read failed\n");
+        exit(1);
+    }
+    nexpected = HEADER_LEN+TRAILER_LEN+TRAILER_LEN+HEADER_LEN+HEADER_LEN;
+    if (ntotal != nexpected) {
+        fprintf(stderr, "total bytes read should be %d but is %d\n",
+                nexpected, ntotal);
+        exit(1);
+    }
+    if (memcmp(buf, HEADER_STR TRAILER_STR TRAILER_STR HEADER_STR HEADER_STR,
+            nexpected) != 0) {
+        fprintf(stderr, "wrong data is received\n");
+        exit(1);
+    }
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+static void ServerThread(void *arg)
+{
+    PRFileDesc *listenSock = (PRFileDesc *) arg;
+    PRFileDesc *acceptSock;
+    PRFileDesc *file;
+    PRSendFileData sfd;
+    char header[1024], trailer[1024];
+    PRInt32 nbytes;
+
+    /* Create a zero-length file */
+    file = PR_Open(ZERO_LEN_FILE_NAME,
+            PR_CREATE_FILE|PR_TRUNCATE|PR_RDWR, 0666);
+    if (NULL == file) {
+        fprintf(stderr, "PR_Open failed\n");
+        exit(1);
+    }
+    sfd.fd = file;
+    sfd.file_offset = 0;
+    sfd.file_nbytes = 0;
+    memcpy(header, HEADER_STR, HEADER_LEN);
+    memcpy(trailer, TRAILER_STR, TRAILER_LEN);
+    sfd.header = header;
+    sfd.hlen = HEADER_LEN;
+    sfd.trailer = trailer;
+    sfd.tlen = TRAILER_LEN;
+    acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == acceptSock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+    /* Send both header and trailer */
+    nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+            PR_INTERVAL_NO_TIMEOUT);
+    if (HEADER_LEN+TRAILER_LEN != nbytes) {
+        fprintf(stderr, "PR_SendFile should return %d but returned %d\n",
+                HEADER_LEN+TRAILER_LEN, nbytes);
+        exit(1);
+    }
+    /* Trailer only, no header */
+    sfd.hlen = 0;
+    nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+            PR_INTERVAL_NO_TIMEOUT);
+    if (TRAILER_LEN != nbytes) {
+        fprintf(stderr, "PR_SendFile should return %d but returned %d\n",
+                TRAILER_LEN, nbytes);
+        exit(1);
+    }
+    /* Header only, no trailer */
+    sfd.hlen = HEADER_LEN;
+    sfd.tlen = 0;
+    nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+            PR_INTERVAL_NO_TIMEOUT);
+    if (HEADER_LEN != nbytes) {
+        fprintf(stderr, "PR_SendFile should return %d but returned %d\n",
+                HEADER_LEN, nbytes);
+        exit(1);
+    }
+    /* Try PR_TransmitFile */
+    nbytes = PR_TransmitFile(acceptSock, file, header, HEADER_LEN,
+            PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT);
+    if (HEADER_LEN != nbytes) {
+        fprintf(stderr, "PR_TransmitFile should return %d but returned %d\n",
+                HEADER_LEN, nbytes);
+        exit(1);
+    }
+    if (PR_Close(acceptSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_Close(file) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_Delete(ZERO_LEN_FILE_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_Delete failed\n");
+        exit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock;
+    PRThread *clientThread;
+    PRThread *serverThread;
+    PRNetAddr addr;
+    PRThreadScope scope = PR_GLOBAL_THREAD;
+
+    listenSock = PR_NewTCPSocket();
+    if (NULL == listenSock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    /* Find out what port number we are bound to. */
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetSockName failed\n");
+        exit(1);
+    }
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
+            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == clientThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    serverThread = PR_CreateThread(PR_USER_THREAD,
+            ServerThread, listenSock,
+            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == serverThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(clientThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(serverThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    if (PR_Close(listenSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/server_test.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/server_test.c
new file mode 100644
index 0000000..9b67400
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/server_test.c
@@ -0,0 +1,642 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+#define PASS 0
+#define FAIL 1
+static int debug_mode = 0;
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#undef DEBUGPRINTS
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**				status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static void Test_Result (int result)
+{
+	switch (result)
+	{
+		case PASS:
+			printf ("PASS\n");
+			break;
+		case FAIL:
+			printf ("FAIL\n");
+			break;
+		default:
+			break;
+	}
+}
+
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+#ifdef SYMBIAN
+        if (workerThreadsBusy == workerThreads && workerThreads<1) {
+#else
+        if (workerThreadsBusy == workerThreads) {
+#endif
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        }	
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else Test_Result(FAIL);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else Test_Result(FAIL);
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else Test_Result(FAIL);
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+static void do_workUU(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workUK(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+static void do_workKU(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workKK(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+int main(int argc, char **argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+#ifndef SYMBIAN
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else 
+#endif
+	{
+
+		_iterations = 10;
+	    _clients = 1;
+		_client_data = 10;
+		_server_data = 10;
+	}
+	
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+    Measure(do_workUU, "server loop user/user");
+ #if 0 
+    Measure(do_workUK, "server loop user/kernel");
+    Measure(do_workKU, "server loop kernel/user");
+    Measure(do_workKK, "server loop kernel/kernel");
+ #endif 
+
+    PR_Cleanup();
+
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_kk.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_kk.c
new file mode 100644
index 0000000..9099a45
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_kk.c
@@ -0,0 +1,620 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+#ifdef SYMBIAN
+        if (workerThreadsBusy == workerThreads && workerThreads<1) {
+#else
+        if (workerThreadsBusy == workerThreads) {
+#endif
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        }
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRSocketOptionData sockOpt;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else failed_already=1;
+        return NULL;
+    }
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else failed_already=1;
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+static void do_workUU(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workUK(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+static void do_workKU(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workKK(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+int main(int argc, char **argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+#ifndef SYMBIAN
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else 
+#endif
+	{
+		_iterations = 7;
+		_clients = 7;
+		_client_data = 100;
+		_server_data = 100;
+	}
+
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetThreadRecycleMode(64);
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+
+    Measure(do_workKK, "server loop kernel/kernel");
+
+	PR_Cleanup();
+
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+    
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_ku.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_ku.c
new file mode 100644
index 0000000..3e58d9d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_ku.c
@@ -0,0 +1,600 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+#ifdef SYMBIAN
+        if (workerThreadsBusy == workerThreads && workerThreads<1) {
+#else
+        if (workerThreadsBusy == workerThreads) {
+#endif
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        }
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRSocketOptionData sockOpt;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else failed_already=1;
+        return NULL;
+    }
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else failed_already=1;
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+
+static void do_workKU(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+int main(int argc, char **argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+#ifndef SYMBIAN
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else 
+#endif
+	{
+		_iterations = 7;
+		_clients = 7;
+		_client_data = 100;
+		_server_data = 100;
+	}
+
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetThreadRecycleMode(64);
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+    Measure(do_workKU, "server loop kernel/user");
+
+    PR_Cleanup();
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_uk.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_uk.c
new file mode 100644
index 0000000..53bf8ed
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_uk.c
@@ -0,0 +1,602 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+#ifdef SYMBIAN
+        if (workerThreadsBusy == workerThreads && workerThreads<1) {
+#else
+        if (workerThreadsBusy == workerThreads) {
+#endif
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        }
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRSocketOptionData sockOpt;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else 
+        return NULL;
+    }
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else failed_already=1;
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+
+static void do_workUK(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+int main(int argc, char **argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+#ifndef SYMBIAN
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else 
+#endif
+	{
+		_iterations = 7;
+		_clients = 7;
+		_client_data = 100;
+		_server_data = 100;
+	}
+
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetThreadRecycleMode(64);
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+    Measure(do_workUK, "server loop user/kernel");
+
+    PR_Cleanup();
+
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_uu.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_uu.c
new file mode 100644
index 0000000..5cb41c9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/servr_uu.c
@@ -0,0 +1,601 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+#ifdef SYMBIAN
+        if (workerThreadsBusy == workerThreads && workerThreads<1) {
+#else
+        if (workerThreadsBusy == workerThreads) {
+#endif
+
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        } 
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRSocketOptionData sockOpt;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else failed_already=1;
+        return NULL;
+    }
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else failed_already=1;
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+static void do_workUU(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+int main(int argc, char **argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+#ifndef SYMBIAN
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else 
+#endif
+	{
+		_iterations = 7;
+		_clients = 7;
+		_client_data = 100;
+		_server_data = 100;
+	}
+
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetThreadRecycleMode(64);
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+    Measure(do_workUU, "server loop user/user");
+
+    PR_Cleanup();
+	
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+    
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/short_thread.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/short_thread.c
new file mode 100644
index 0000000..42a52d7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/short_thread.c
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include "nspr.h"
+#include "plgetopt.h"
+
+/*
+ * Create a thread that exits right away; useful for testing race conditions in thread
+ * creation
+ */
+
+int _debug_on = 0;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+static void housecleaning(void *cur_time);
+
+int main (int argc, char **argv)
+{
+	static PRIntervalTime thread_start_time;
+	static PRThread *housekeeping_tid = NULL;
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+	{
+		if (PL_OPT_BAD == os) continue;
+		switch (opt->option)
+		{
+			case 'd':  /* debug mode */
+				_debug_on = 1;
+				break;
+			default:
+				break;
+		}
+	}
+	PL_DestroyOptState(opt);
+
+	if (( housekeeping_tid = 
+		PR_CreateThread (PR_USER_THREAD, housecleaning,  (void*)&thread_start_time,
+						 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0)) 
+																		== NULL ) {
+		fprintf(stderr,
+			"simple_test: Error - PR_CreateThread failed: (%ld, %ld)\n",
+									  PR_GetError(), PR_GetOSError());
+		exit( 1 );
+	}
+	PR_Cleanup();
+	return(0);
+}
+
+static void
+housecleaning (void *cur_time) 
+{
+  DPRINTF(("Child Thread exiting\n"));
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sigpipe.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sigpipe.c
new file mode 100644
index 0000000..4416428
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sigpipe.c
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ *************************************************************************
+ *
+ * Test: sigpipe.c
+ *
+ *     Test the SIGPIPE handler in NSPR.  This test applies to Unix only.
+ *
+ *************************************************************************
+ */
+
+#if !defined(XP_UNIX) && !defined(XP_OS2)
+
+int main(void)
+{
+    /* This test applies to Unix and OS/2. */
+    return 0;
+}
+
+#else /* XP_UNIX && OS/2 */
+
+#include "nspr.h"
+
+#ifdef XP_OS2
+#define INCL_DOSQUEUES
+#define INCL_DOSERRORS
+#include <os2.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+static void Test(void *arg)
+{
+#ifdef XP_OS2
+    HFILE pipefd[2];
+#else
+    int pipefd[2];
+#endif
+    int rv;
+    char c = '\0';
+
+#ifdef XP_OS2
+    if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) {
+#else
+    if (pipe(pipefd) == -1) {
+#endif
+        fprintf(stderr, "cannot create pipe: %d\n", errno);
+        exit(1);
+    }
+    close(pipefd[0]);
+
+    rv = write(pipefd[1], &c, 1);
+    if (rv != -1) {
+        fprintf(stderr, "write to broken pipe should have failed with EPIPE but returned %d\n", rv);
+        exit(1);
+    }
+#ifdef SYMBIAN
+    /* Have mercy on the unknown 142 errno, it seems ok */
+    if (errno != EPIPE && errno != 142) {
+#else
+    if (errno != EPIPE) {
+#endif
+        fprintf(stderr, "write to broken pipe failed but with wrong errno: %d\n", errno);
+        exit(1);
+    }
+    close(pipefd[1]);
+    printf("write to broken pipe failed with EPIPE, as expected\n");
+}
+
+int main(int argc, char **argv)
+{
+    PRThread *thread;
+
+    /* This initializes NSPR. */
+    PR_SetError(0, 0);
+
+    thread = PR_CreateThread(PR_USER_THREAD, Test, NULL, PR_PRIORITY_NORMAL,
+            PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (thread == NULL) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(thread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    Test(NULL);
+
+    printf("PASSED\n");
+    return 0;
+}
+
+#endif /* XP_UNIX */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sleep.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sleep.c
new file mode 100644
index 0000000..3459fa6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sleep.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+
+#if defined(XP_UNIX) || defined(XP_OS2)
+
+#include <stdio.h>
+
+#ifndef XP_OS2
+#include <unistd.h>
+#endif
+#include <sys/time.h>
+
+#if defined(HAVE_SVID_GETTOD)
+#define GTOD(_a) gettimeofday(_a)
+#else
+#define GTOD(_a) gettimeofday((_a), NULL)
+#endif
+
+static PRIntn rv = 0;
+
+static void Other(void *unused)
+{
+    PRIntn didit = 0;
+    while (PR_SUCCESS == PR_Sleep(PR_MillisecondsToInterval(250)))
+    {
+        fprintf(stderr, ".");
+        didit += 1;
+    }
+    if (didit < 5) rv = 1;
+}
+
+int main(int argc, char **argv)
+{
+    PRUint32 elapsed;
+    PRThread *thread;
+	struct timeval timein, timeout;
+    PRInt32 onePercent = 3000000UL / 100UL;
+
+	fprintf (stderr, "First sleep will sleep 3 seconds.\n");
+	fprintf (stderr, "   sleep 1 begin\n");
+    (void)GTOD(&timein);
+	sleep (3);
+    (void)GTOD(&timeout);
+	fprintf (stderr, "   sleep 1 end\n");
+    elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec);
+    elapsed += (timeout.tv_usec - timein.tv_usec);
+    fprintf(stderr, "elapsed %u usecs\n", elapsed);
+    if (labs(elapsed - 3000000UL) > onePercent) rv = 1;
+
+	PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 100);
+    PR_STDIO_INIT();
+
+	fprintf (stderr, "Second sleep should do the same (does it?).\n");
+	fprintf (stderr, "   sleep 2 begin\n");
+    (void)GTOD(&timein);
+	sleep (3);
+    (void)GTOD(&timeout);
+	fprintf (stderr, "   sleep 2 end\n");
+    elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec);
+    elapsed += (timeout.tv_usec - timein.tv_usec);
+    fprintf(stderr, "elapsed %u usecs\n", elapsed);
+    if (labs(elapsed - 3000000UL) > onePercent) rv = 1;
+
+	fprintf (stderr, "What happens to other threads?\n");
+	fprintf (stderr, "You should see dots every quarter second.\n");
+	fprintf (stderr, "If you don't, you're probably running on classic NSPR.\n");
+    thread = PR_CreateThread(
+        PR_USER_THREAD, Other, NULL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+	fprintf (stderr, "   sleep 2 begin\n");
+    (void)GTOD(&timein);
+	sleep (3);
+    (void)GTOD(&timeout);
+	fprintf (stderr, "   sleep 2 end\n");
+    PR_Interrupt(thread);
+    PR_JoinThread(thread);
+    elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec);
+    elapsed += (timeout.tv_usec - timein.tv_usec);
+    fprintf(stderr, "elapsed %u usecs\n", elapsed);
+    if (labs(elapsed - 3000000UL) > onePercent) rv = 1;
+    fprintf(stderr, "%s\n", (0 == rv) ? "PASSED" : "FAILED");
+    return rv;
+}
+
+#else /* defined(XP_UNIX) */
+
+PRIntn main()
+{
+	return 2;
+}
+
+#endif /*  defined(XP_UNIX) */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/socket.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/socket.c
new file mode 100644
index 0000000..dcf8fa1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/socket.c
@@ -0,0 +1,2354 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: socket.c
+**
+** Description: Test socket functionality.
+**
+** Modification History:
+*/
+#include "primpl.h"
+
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#ifdef XP_UNIX
+#include <sys/mman.h>
+#endif
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#endif
+
+#ifdef WIN32
+#include <process.h>
+#endif
+
+static int _debug_on = 0;
+static int test_cancelio = 0;
+
+#include "obsolete/prsem.h"
+
+#ifdef XP_PC
+#define mode_t int
+#endif
+
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+#ifdef XP_PC
+char *TEST_DIR = "prdir";
+char *SMALL_FILE_NAME = "prsmallf";
+char *LARGE_FILE_NAME = "prlargef";
+#elif defined(SYMBIAN)
+char *TEST_DIR = "c:\\data\\prsocket";
+char *SMALL_FILE_NAME = "c:\\data\\prsocket\\small_file";
+char *LARGE_FILE_NAME = "c:\\data\\prsocket\\large_file";
+#else
+char *TEST_DIR = "/tmp/prsocket_test_dir";
+char *SMALL_FILE_NAME = "/tmp/prsocket_test_dir/small_file";
+char *LARGE_FILE_NAME = "/tmp/prsocket_test_dir/large_file";
+#endif
+#define SMALL_FILE_SIZE				(3 * 1024)        /* 3 KB        */
+#define SMALL_FILE_OFFSET_1			(512)
+#define SMALL_FILE_LEN_1			(1 * 1024)        /* 1 KB        */
+#define SMALL_FILE_OFFSET_2			(75)
+#define SMALL_FILE_LEN_2			(758)
+#define SMALL_FILE_OFFSET_3			(1024)
+#define SMALL_FILE_LEN_3			(SMALL_FILE_SIZE - SMALL_FILE_OFFSET_3)
+#define SMALL_FILE_HEADER_SIZE    	(64)            /* 64 bytes    */
+#define SMALL_FILE_TRAILER_SIZE   	(128)           /* 128 bytes    */
+
+#define LARGE_FILE_SIZE				(3 * 1024 * 1024)    /* 3 MB        */
+#define LARGE_FILE_OFFSET_1			(0)
+#define LARGE_FILE_LEN_1			(2 * 1024 * 1024)    /* 2 MB        */
+#define LARGE_FILE_OFFSET_2			(64)
+#define LARGE_FILE_LEN_2			(1 * 1024 * 1024 + 75)
+#define LARGE_FILE_OFFSET_3			(2 * 1024 * 1024 - 128)
+#define LARGE_FILE_LEN_3			(LARGE_FILE_SIZE - LARGE_FILE_OFFSET_3)
+#define LARGE_FILE_OFFSET_4			PR_GetPageSize()
+#define LARGE_FILE_LEN_4			769
+#define LARGE_FILE_HEADER_SIZE    	(512)
+#define LARGE_FILE_TRAILER_SIZE   	(64)
+
+#define    BUF_DATA_SIZE    (2 * 1024)
+#define TCP_MESG_SIZE    1024
+/*
+ * set UDP datagram size small enough that datagrams sent to a port on the
+ * local host will not be lost
+ */
+#define UDP_DGRAM_SIZE            128
+#define NUM_TCP_CLIENTS            5	/* for a listen queue depth of 5 */
+#define NUM_UDP_CLIENTS            10
+
+#ifdef SYMBIAN
+#define NUM_TRANSMITFILE_CLIENTS    1
+#else
+#define NUM_TRANSMITFILE_CLIENTS    4
+#endif
+
+#define NUM_TCP_CONNECTIONS_PER_CLIENT    5
+#define NUM_TCP_MESGS_PER_CONNECTION    10
+#define NUM_UDP_DATAGRAMS_PER_CLIENT    5
+#define TCP_SERVER_PORT            10000
+#define UDP_SERVER_PORT            TCP_SERVER_PORT
+#define SERVER_MAX_BIND_COUNT        100
+
+#ifdef WINCE
+#define perror(s)
+#endif
+
+static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS;
+static PRInt32 num_udp_clients = NUM_UDP_CLIENTS;
+static PRInt32 num_transmitfile_clients = NUM_TRANSMITFILE_CLIENTS;
+static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT;
+static PRInt32 tcp_mesg_size = TCP_MESG_SIZE;
+static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION;
+static PRInt32 num_udp_datagrams_per_client = NUM_UDP_DATAGRAMS_PER_CLIENT;
+static PRInt32 udp_datagram_size = UDP_DGRAM_SIZE;
+
+static PRInt32 thread_count;
+PRUint16 server_domain = PR_AF_INET, client_domain = PR_AF_INET;
+
+/* an I/O layer that uses the emulated senfile method */
+static PRDescIdentity emuSendFileIdentity;
+static PRIOMethods emuSendFileMethods;
+
+int failed_already=0;
+typedef struct buffer {
+    char    data[BUF_DATA_SIZE];
+} buffer;
+
+PRNetAddr tcp_server_addr, udp_server_addr;
+
+typedef struct Serve_Client_Param {
+    PRFileDesc *sockfd;    /* socket to read from/write to    */
+    PRInt32    datalen;    /* bytes of data transfered in each read/write */
+} Serve_Client_Param;
+
+typedef struct Server_Param {
+    PRSemaphore *addr_sem;    /* sem to post on, after setting up the address */
+    PRMonitor *exit_mon;    /* monitor to signal on exit            */
+    PRInt32 *exit_counter;    /* counter to decrement, before exit        */
+    PRInt32    datalen;    /* bytes of data transfered in each read/write    */
+} Server_Param;
+
+
+typedef struct Client_Param {
+    PRNetAddr server_addr;
+    PRMonitor *exit_mon;    /* monitor to signal on exit */
+    PRInt32 *exit_counter;    /* counter to decrement, before exit */
+    PRInt32    datalen;
+    PRInt32    udp_connect;    /* if set clients connect udp sockets */
+} Client_Param;
+
+/* the sendfile method in emuSendFileMethods */
+static PRInt32 PR_CALLBACK
+emu_SendFile(PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    return PR_EmulateSendFile(sd, sfd, flags, timeout);
+}
+
+/* the transmitfile method in emuSendFileMethods */
+static PRInt32 PR_CALLBACK
+emu_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, const void *headers,
+    PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    PRSendFileData sfd;
+
+    sfd.fd = fd;
+    sfd.file_offset = 0;
+    sfd.file_nbytes = 0;
+    sfd.header = headers;
+    sfd.hlen = hlen;
+    sfd.trailer = NULL;
+    sfd.tlen = 0;
+    return emu_SendFile(sd, &sfd, flags, timeout);
+}
+
+/*
+ * readn
+ *    read data from sockfd into buf
+ */
+static PRInt32
+readn(PRFileDesc *sockfd, char *buf, int len)
+{
+    int rem;
+    int bytes;
+    int offset = 0;
+	int err;
+	PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+
+	if (test_cancelio)
+		timeout = PR_SecondsToInterval(2);
+
+    for (rem=len; rem; offset += bytes, rem -= bytes) {
+        DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n",
+            PR_GetCurrentThread(), rem));
+retry:
+        bytes = PR_Recv(sockfd, buf + offset, rem, 0,
+            	timeout);
+        DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n",
+            PR_GetCurrentThread(), bytes));
+        if (bytes < 0) {
+#ifdef WINNT
+			printf("PR_Recv: error = %d oserr = %d\n",(err = PR_GetError()),
+									PR_GetOSError());
+			if ((test_cancelio) && (err == PR_IO_TIMEOUT_ERROR)) {
+				if (PR_NT_CancelIo(sockfd) != PR_SUCCESS)
+					printf("PR_NT_CancelIO: error = %d\n",PR_GetError());
+				timeout = PR_INTERVAL_NO_TIMEOUT;
+				goto retry;
+			}
+#endif
+			return -1;
+		}	
+    }
+    return len;
+}
+
+/*
+ * writen
+ *    write data from buf to sockfd
+ */
+static PRInt32
+writen(PRFileDesc *sockfd, char *buf, int len)
+{
+    int rem;
+    int bytes;
+    int offset = 0;
+
+    for (rem=len; rem; offset += bytes, rem -= bytes) {
+        DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n",
+            PR_GetCurrentThread(), rem));
+        bytes = PR_Send(sockfd, buf + offset, rem, 0,
+            PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n",
+            PR_GetCurrentThread(), bytes));
+        if (bytes <= 0)
+            return -1;
+    }
+    return len;
+}
+
+/*
+ * Serve_Client
+ *    Thread, started by the server, for serving a client connection.
+ *    Reads data from socket and writes it back, unmodified, and
+ *    closes the socket
+ */
+static void PR_CALLBACK
+Serve_Client(void *arg)
+{
+    Serve_Client_Param *scp = (Serve_Client_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf;
+    PRInt32 bytes, j;
+
+    sockfd = scp->sockfd;
+    bytes = scp->datalen;
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        goto exit;
+    }
+
+
+    for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
+        /*
+         * Read data from client and send it back to the client unmodified
+         */
+        if (readn(sockfd, in_buf->data, bytes) < bytes) {
+            fprintf(stderr,"prsocket_test: ERROR - Serve_Client:readn\n");
+            failed_already=1;
+            goto exit;
+        }
+        /* Shutdown only RCV will cause error on Symbian OS */
+#if !defined(SYMBIAN)
+        /*
+         * shutdown reads, after the last read
+         */
+        if (j == num_tcp_mesgs_per_connection - 1)
+            if (PR_Shutdown(sockfd, PR_SHUTDOWN_RCV) < 0) {
+                fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
+            }
+#endif
+        DPRINTF(("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n",PR_GetCurrentThread(),
+            (*((int *) in_buf->data))));
+        if (writen(sockfd, in_buf->data, bytes) < bytes) {
+            fprintf(stderr,"prsocket_test: ERROR - Serve_Client:writen\n");
+            failed_already=1;
+            goto exit;
+        }
+    }
+    /*
+     * shutdown reads and writes
+     */
+    if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
+        failed_already=1;
+    }
+
+exit:
+    PR_Close(sockfd);
+    if (in_buf) {
+        PR_DELETE(in_buf);
+    }
+}
+
+PRThread* create_new_thread(PRThreadType type,
+							void (*start)(void *arg),
+							void *arg,
+							PRThreadPriority priority,
+							PRThreadScope scope,
+							PRThreadState state,
+							PRUint32 stackSize, PRInt32 index)
+{
+PRInt32 native_thread = 0;
+
+	PR_ASSERT(state == PR_UNJOINABLE_THREAD);
+#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32)
+	switch(index %  4) {
+		case 0:
+			scope = (PR_LOCAL_THREAD);
+			break;
+		case 1:
+			scope = (PR_GLOBAL_THREAD);
+			break;
+		case 2:
+			scope = (PR_GLOBAL_BOUND_THREAD);
+			break;
+		case 3:
+			native_thread = 1;
+			break;
+		default:
+			PR_ASSERT(!"Invalid scope");
+			break;
+	}
+	if (native_thread) {
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+		pthread_t tid;
+		if (!pthread_create(&tid, NULL, (void * (*)(void *)) start, arg))
+			return((PRThread *) tid);
+		else
+			return (NULL);
+#else
+		HANDLE thandle;
+		unsigned tid;
+		
+		thandle = (HANDLE) _beginthreadex(
+						NULL,
+						stackSize,
+						(unsigned (__stdcall *)(void *))start,
+						arg,
+						0,
+						&tid);		
+		return((PRThread *) thandle);
+#endif
+	} else {
+		return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
+	}
+#else
+	return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
+#endif
+}
+
+/*
+ * TCP Server
+ *    Server Thread
+ *    Bind an address to a socket and listen for incoming connections
+ *    Start a Serve_Client thread for each incoming connection.
+ */
+static void PR_CALLBACK
+TCP_Server(void *arg)
+{
+    PRThread *t;
+    Server_Param *sp = (Server_Param *) arg;
+    Serve_Client_Param *scp;
+    PRFileDesc *sockfd, *newsockfd;
+    PRNetAddr netaddr;
+    PRInt32 i;
+    /*
+     * Create a tcp socket
+     */
+	if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
+        goto exit;
+    }
+    memset(&netaddr, 0 , sizeof(netaddr));
+	
+	if (PR_SetNetAddr(PR_IpAddrAny, server_domain, TCP_SERVER_PORT,
+									&netaddr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        goto exit;
+	}
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+    i = 0;
+	
+    while (PR_Bind(sockfd, &netaddr) < 0) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            netaddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
+        perror("PR_Bind");
+        failed_already=1;
+        goto exit;
+    }
+
+    if (PR_Listen(sockfd, 32) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
+        failed_already=1;
+        goto exit;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
+        failed_already=1;
+        goto exit;
+    }
+
+    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+	if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
+									PR_ntohs(PR_NetAddrInetPort(&netaddr)),
+									&tcp_server_addr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        goto exit;
+	}
+	if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET))
+		PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK),
+								&tcp_server_addr.ipv6.ip);
+
+    /*
+     * Wake up parent thread because server address is bound and made
+     * available in the global variable 'tcp_server_addr'
+     */
+    PR_PostSem(sp->addr_sem);
+
+    for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) {
+        /* test both null and non-null 'addr' argument to PR_Accept */
+        PRNetAddr *addrp = (i%2 ? &netaddr: NULL);
+
+    DPRINTF(("TCP_Server: Accepting connection\n"));
+        if ((newsockfd = PR_Accept(sockfd, addrp,
+            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+            fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n");
+            goto exit;
+        }
+    DPRINTF(("TCP_Server: Accepted connection\n"));
+        scp = PR_NEW(Serve_Client_Param);
+        if (scp == NULL) {
+            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+            goto exit;
+        }
+
+        /*
+         * Start a Serve_Client thread for each incoming connection
+         */
+        scp->sockfd = newsockfd;
+        scp->datalen = sp->datalen;
+
+        t = create_new_thread(PR_USER_THREAD,
+            Serve_Client, (void *)scp, 
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD,
+            0, i);
+        if (t == NULL) {
+            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+            failed_already=1;
+            goto exit;
+        }
+        DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t));
+    }
+
+exit:
+    if (sockfd) {
+        PR_Close(sockfd);
+    }
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(sp->exit_mon);
+    --(*sp->exit_counter);
+    PR_Notify(sp->exit_mon);
+    PR_ExitMonitor(sp->exit_mon);
+    DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * UDP Server
+ *    Server Thread
+ *    Bind an address to a socket, read data from clients and send data
+ *    back to clients
+ */
+static void PR_CALLBACK
+UDP_Server(void *arg)
+{
+    Server_Param *sp = (Server_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf;
+    PRNetAddr netaddr;
+    PRInt32 bytes, i, rv = 0;
+
+
+    bytes = sp->datalen;
+    /*
+     * Create a udp socket
+     */
+	if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n");
+        failed_already=1;
+        return;
+    }
+    memset(&netaddr, 0 , sizeof(netaddr));
+	if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT,
+									&netaddr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        failed_already=1;
+        return;
+	}
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+    i = 0;
+    while (PR_Bind(sockfd, &netaddr) < 0) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            netaddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
+        perror("PR_Bind");
+        failed_already=1;
+        return;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
+        failed_already=1;
+        return;
+    }
+
+    DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+    /*
+     * We can't use the IP address returned by PR_GetSockName in
+     * netaddr.inet.ip because netaddr.inet.ip is returned
+     * as 0 (= PR_INADDR_ANY).
+     */
+
+	if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
+									PR_ntohs(PR_NetAddrInetPort(&netaddr)),
+									&udp_server_addr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        failed_already=1;
+        return;
+	}
+	if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET))
+		PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK),
+								&udp_server_addr.ipv6.ip);
+		
+    /*
+     * Wake up parent thread because server address is bound and made
+     * available in the global variable 'udp_server_addr'
+     */
+    PR_PostSem(sp->addr_sem);
+
+    bytes = sp->datalen;
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    /*
+     * Receive datagrams from clients and send them back, unmodified, to the
+     * clients
+     */
+    memset(&netaddr, 0 , sizeof(netaddr));
+    for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) {
+        DPRINTF(("UDP_Server: calling PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
+            netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data,
+            in_buf->data[0]));
+
+        rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
+            PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("UDP_Server: PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
+            netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,
+            in_buf->data[0]));
+        if (rv != bytes) {
+            return;
+        }
+        rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr,
+            PR_INTERVAL_NO_TIMEOUT);
+        if (rv != bytes) {
+            return;
+        }
+    }
+
+    PR_DELETE(in_buf);
+    PR_Close(sockfd);
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+    PR_EnterMonitor(sp->exit_mon);
+    --(*sp->exit_counter);
+    PR_Notify(sp->exit_mon);
+    PR_ExitMonitor(sp->exit_mon);
+    DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * TCP_Client
+ *    Client Thread
+ *    Connect to the server at the address specified in the argument.
+ *    Fill in a buffer, write data to server, read it back and check
+ *    for data corruption.
+ *    Close the socket for server connection
+ */
+static void PR_CALLBACK
+TCP_Client(void *arg)
+{
+    Client_Param *cp = (Client_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf, *out_buf;
+    union PRNetAddr netaddr;
+    PRInt32 bytes, i, j;
+
+
+    bytes = cp->datalen;
+    out_buf = PR_NEW(buffer);
+    if (out_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    netaddr = cp->server_addr;
+
+    for (i = 0; i < num_tcp_connections_per_client; i++) {
+        if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL) {
+            fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n");
+            failed_already=1;
+            return;
+        }
+        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
+        	fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n",
+            		PR_GetError(), PR_GetOSError());
+            failed_already=1;
+            return;
+        }
+        for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
+            /*
+             * fill in random data
+             */
+            memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes);
+            /*
+             * write to server
+             */
+#ifdef WINNT
+			if (test_cancelio && (j == 0))
+				PR_Sleep(PR_SecondsToInterval(12));
+#endif
+            if (writen(sockfd, out_buf->data, bytes) < bytes) {
+                fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n");
+                failed_already=1;
+                return;
+            }
+            DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
+                PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
+            if (readn(sockfd, in_buf->data, bytes) < bytes) {
+                fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n");
+                failed_already=1;
+                return;
+            }
+            /*
+             * verify the data read
+             */
+            if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
+                fprintf(stderr,"prsocket_test: ERROR - data corruption\n");
+                failed_already=1;
+                return;
+            }
+        }
+        /*
+         * shutdown reads and writes
+         */
+        if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
+            fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
+#if defined(SYMBIAN)
+            if (EPIPE != errno)
+#endif
+            failed_already=1;
+        }
+        PR_Close(sockfd);
+    }
+
+    PR_DELETE(out_buf);
+    PR_DELETE(in_buf);
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(cp->exit_mon);
+    --(*cp->exit_counter);
+    PR_Notify(cp->exit_mon);
+    PR_ExitMonitor(cp->exit_mon);
+    DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * UDP_Client
+ *    Client Thread
+ *    Create a socket and bind an address 
+ *    Communicate with the server at the address specified in the argument.
+ *    Fill in a buffer, write data to server, read it back and check
+ *    for data corruption.
+ *    Close the socket
+ */
+static void PR_CALLBACK
+UDP_Client(void *arg)
+{
+    Client_Param *cp = (Client_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf, *out_buf;
+    union PRNetAddr netaddr;
+    PRInt32 bytes, i, rv;
+
+
+    bytes = cp->datalen;
+    out_buf = PR_NEW(buffer);
+    if (out_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n");
+        failed_already=1;
+        return;
+    }
+
+    /*
+     * bind an address for the client, let the system chose the port
+     * number
+     */
+    memset(&netaddr, 0 , sizeof(netaddr));
+	if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0,
+									&netaddr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        failed_already=1;
+        return;
+	}
+    if (PR_Bind(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
+        perror("PR_Bind");
+        return;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
+        failed_already=1;
+        return;
+    }
+
+    DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+
+    netaddr = cp->server_addr;
+
+    if (cp->udp_connect) {
+        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
+            fprintf(stderr,"prsocket_test: PR_Connect failed\n");
+            failed_already=1;
+            return;
+        }
+    }
+
+    for (i = 0; i < num_udp_datagrams_per_client; i++) {
+        /*
+         * fill in random data
+         */
+        DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n",
+            PR_GetCurrentThread(), out_buf->data, bytes));
+        memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes);
+        /*
+         * write to server
+         */
+        if (cp->udp_connect)
+            rv = PR_Send(sockfd, out_buf->data, bytes, 0,
+                PR_INTERVAL_NO_TIMEOUT);
+        else
+            rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr,
+                PR_INTERVAL_NO_TIMEOUT);
+        if (rv != bytes) {
+            return;
+        }
+        DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
+            PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
+        if (cp->udp_connect)
+            rv = PR_Recv(sockfd, in_buf->data, bytes, 0,
+                PR_INTERVAL_NO_TIMEOUT);
+        else
+            rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
+                PR_INTERVAL_NO_TIMEOUT);
+        if (rv != bytes) {
+            return;
+        }
+        DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n",
+            PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data))));
+        /*
+         * verify the data read
+         */
+        if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
+            fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n");
+            failed_already=1;
+            return;
+        }
+    }
+    PR_Close(sockfd);
+
+    PR_DELETE(in_buf);
+    PR_DELETE(out_buf);
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(cp->exit_mon);
+    --(*cp->exit_counter);
+    PR_Notify(cp->exit_mon);
+    PR_ExitMonitor(cp->exit_mon);
+    PR_DELETE(cp);
+    DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * TCP_Socket_Client_Server_Test    - concurrent server test
+ *    
+ *    One server and several clients are started
+ *    Each client connects to the server and sends a chunk of data
+ *    For each connection, server starts another thread to read the data
+ *    from the client and send it back to the client, unmodified.
+ *    Each client checks that data received from server is same as the
+ *    data it sent to the server.
+ *
+ */
+
+static PRInt32
+TCP_Socket_Client_Server_Test(void)
+{
+    int i;
+    PRThread *t;
+    PRSemaphore *server_sem;
+    Server_Param *sparamp;
+    Client_Param *cparamp;
+    PRMonitor *mon2;
+    PRInt32    datalen;
+
+
+    datalen = tcp_mesg_size;
+    thread_count = 0;
+    /*
+     * start the server thread
+     */
+    sparamp = PR_NEW(Server_Param);
+    if (sparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        return -1;
+    }
+    server_sem = PR_NewSem(0);
+    if (server_sem == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
+        failed_already=1;
+        return -1;
+    }
+    mon2 = PR_NewMonitor();
+    if (mon2 == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
+        failed_already=1;
+        return -1;
+    }
+    PR_EnterMonitor(mon2);
+
+    sparamp->addr_sem = server_sem;
+    sparamp->exit_mon = mon2;
+    sparamp->exit_counter = &thread_count;
+    sparamp->datalen = datalen;
+    t = PR_CreateThread(PR_USER_THREAD,
+        TCP_Server, (void *)sparamp, 
+        PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD,
+        PR_UNJOINABLE_THREAD,
+        0);
+    if (t == NULL) {
+        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+        failed_already=1;
+        return -1;
+    }
+    DPRINTF(("Created TCP server = 0x%lx\n", t));
+    thread_count++;
+
+    /*
+     * wait till the server address is setup
+     */
+    PR_WaitSem(server_sem);
+
+    /*
+     * Now start a bunch of client threads
+     */
+
+    cparamp = PR_NEW(Client_Param);
+    if (cparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        return -1;
+    }
+    cparamp->server_addr = tcp_server_addr;
+    cparamp->exit_mon = mon2;
+    cparamp->exit_counter = &thread_count;
+    cparamp->datalen = datalen;
+    for (i = 0; i < num_tcp_clients; i++) {
+        t = create_new_thread(PR_USER_THREAD,
+            TCP_Client, (void *) cparamp,
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD,
+            0, i);
+        if (t == NULL) {
+            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+            failed_already=1;
+            return -1;
+        }
+        DPRINTF(("Created TCP client = 0x%lx\n", t));
+        thread_count++;
+    }
+    /* Wait for server and client threads to exit */
+    while (thread_count) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("TCP Server - thread_count  = %d\n", thread_count));
+    }
+    PR_ExitMonitor(mon2);
+    printf("%30s","TCP_Socket_Client_Server_Test:");
+    printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
+        num_tcp_clients, num_tcp_connections_per_client);
+    printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
+        num_tcp_mesgs_per_connection, tcp_mesg_size);
+
+    return 0;
+}
+
+/*
+ * UDP_Socket_Client_Server_Test    - iterative server test
+ *    
+ *    One server and several clients are started
+ *    Each client connects to the server and sends a chunk of data
+ *    For each connection, server starts another thread to read the data
+ *    from the client and send it back to the client, unmodified.
+ *    Each client checks that data received from server is same as the
+ *    data it sent to the server.
+ *
+ */
+
+static PRInt32
+UDP_Socket_Client_Server_Test(void)
+{
+    int i;
+    PRThread *t;
+    PRSemaphore *server_sem;
+    Server_Param *sparamp;
+    Client_Param *cparamp;
+    PRMonitor *mon2;
+    PRInt32    datalen;
+    PRInt32    udp_connect = 1;
+
+
+    datalen = udp_datagram_size;
+    thread_count = 0;
+    /*
+     * start the server thread
+     */
+    sparamp = PR_NEW(Server_Param);
+    if (sparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        return -1;
+    }
+    server_sem = PR_NewSem(0);
+    if (server_sem == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
+        failed_already=1;
+        return -1;
+    }
+    mon2 = PR_NewMonitor();
+    if (mon2 == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
+        failed_already=1;
+        return -1;
+    }
+    PR_EnterMonitor(mon2);
+
+    sparamp->addr_sem = server_sem;
+    sparamp->exit_mon = mon2;
+    sparamp->exit_counter = &thread_count;
+    sparamp->datalen = datalen;
+    DPRINTF(("Creating UDP server"));
+    t = PR_CreateThread(PR_USER_THREAD,
+        UDP_Server, (void *)sparamp, 
+        PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD,
+        PR_UNJOINABLE_THREAD,
+        0);
+    if (t == NULL) {
+        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+        failed_already=1;
+        return -1;
+    }
+    thread_count++;
+
+    /*
+     * wait till the server address is setup
+     */
+    PR_WaitSem(server_sem);
+
+    /*
+     * Now start a bunch of client threads
+     */
+
+    for (i = 0; i < num_udp_clients; i++) {
+        cparamp = PR_NEW(Client_Param);
+        if (cparamp == NULL) {
+            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+            failed_already=1;
+            return -1;
+        }
+        cparamp->server_addr = udp_server_addr;
+        cparamp->exit_mon = mon2;
+        cparamp->exit_counter = &thread_count;
+        cparamp->datalen = datalen;
+        /*
+         * Cause every other client thread to connect udp sockets
+         */
+        cparamp->udp_connect = udp_connect;
+        if (udp_connect)
+            udp_connect = 0;
+        else
+            udp_connect = 1;
+        DPRINTF(("Creating UDP client %d\n", i));
+        t = PR_CreateThread(PR_USER_THREAD,
+            UDP_Client, (void *) cparamp,
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD,
+            0);
+        if (t == NULL) {
+            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+            failed_already=1;
+            return -1;
+        }
+        thread_count++;
+    }
+    /* Wait for server and client threads to exit */
+    while (thread_count) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("UDP Server - thread_count  = %d\n", thread_count));
+    }
+    PR_ExitMonitor(mon2);
+    printf("%30s","UDP_Socket_Client_Server_Test: ");
+    printf("%2ld Server %2ld Clients\n",1l, num_udp_clients);
+    printf("%30s %2ld datagrams_per_client %4ld bytes_per_datagram\n",":",
+        num_udp_datagrams_per_client, udp_datagram_size);
+
+    return 0;
+}
+
+static PRFileDesc *small_file_fd, *large_file_fd;
+static void *small_file_addr, *small_file_header, *large_file_addr;
+static void *small_file_trailer, *large_file_header, *large_file_trailer;
+/*
+ * TransmitFile_Client
+ *    Client Thread
+ */
+static void
+TransmitFile_Client(void *arg)
+{
+    PRFileDesc *sockfd;
+    union PRNetAddr netaddr;
+    char *small_buf, *large_buf;
+    Client_Param *cp = (Client_Param *) arg;
+	PRInt32 rlen;
+
+    small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE +
+										SMALL_FILE_TRAILER_SIZE);
+    if (small_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
+        failed_already=1;
+        return;
+    }
+    large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE + LARGE_FILE_HEADER_SIZE +
+												LARGE_FILE_TRAILER_SIZE);
+    if (large_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
+        failed_already=1;
+        return;
+    }
+    netaddr.inet.family = cp->server_addr.inet.family;
+    netaddr.inet.port = cp->server_addr.inet.port;
+    netaddr.inet.ip = cp->server_addr.inet.ip;
+
+    if ((sockfd = PR_NewTCPSocket()) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
+        failed_already=1;
+        return;
+    }
+
+    if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
+        fprintf(stderr,"prsocket_test: PR_Connect failed\n");
+        failed_already=1;
+        return;
+    }
+    /*
+     * read the small file and verify the data
+     */
+    if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)
+        != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) {
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    /* File transmission test can not be done because of large file's size */
+    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
+        SMALL_FILE_SIZE) != 0) {
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+    /*
+     * read the large file and verify the data
+     */
+    if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) {
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) {
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n");
+        failed_already=1;
+    }
+#endif
+
+
+	/*
+	 * receive data from PR_SendFile
+	 */
+	/*
+	 * case 1: small file with header and trailer
+	 */
+    rlen = SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE +
+									SMALL_FILE_TRAILER_SIZE;
+    if (readn(sockfd, small_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 1. ERROR - small file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
+        								SMALL_FILE_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 1. ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(small_file_trailer,
+				small_buf + SMALL_FILE_HEADER_SIZE + SMALL_FILE_SIZE,
+        				SMALL_FILE_TRAILER_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 1. ERROR - small file trailer corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 2: partial large file at zero offset, file with header and trailer
+	 */
+    rlen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE +
+									LARGE_FILE_TRAILER_SIZE;
+    if (readn(sockfd, large_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(large_file_addr, large_buf + LARGE_FILE_HEADER_SIZE,
+        								LARGE_FILE_LEN_1) != 0) {
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(large_file_trailer,
+				large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_1,
+        				LARGE_FILE_TRAILER_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file trailer corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 3: partial small file at non-zero offset, with header
+	 */
+    rlen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE;
+    if (readn(sockfd, small_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 3. ERROR - small file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_1,
+				small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_1) != 0) {
+        fprintf(stderr,
+            "SendFile 3. ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 4: partial small file at non-zero offset, with trailer
+	 */
+    rlen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE;
+    if (readn(sockfd, small_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_2, small_buf,
+        								SMALL_FILE_LEN_2) != 0) {
+        fprintf(stderr,
+            "SendFile 4. ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(small_file_trailer, small_buf + SMALL_FILE_LEN_2,
+        				SMALL_FILE_TRAILER_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 4. ERROR - small file trailer corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 5: partial large file at non-zero offset, file with header
+	 */
+    rlen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE;
+    if (readn(sockfd, large_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 5. ERROR - large file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_2,
+					large_buf + LARGE_FILE_HEADER_SIZE,
+        								LARGE_FILE_LEN_2) != 0) {
+        fprintf(stderr,
+            "SendFile 5. ERROR - large file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 6: partial small file at non-zero offset, with header
+	 */
+    rlen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE;
+    if (readn(sockfd, small_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 6. ERROR - small file header corruption\n");
+        return;
+    }
+    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_3,
+				small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_3) != 0) {
+#if 0
+		char *i, *j;
+		int k;
+
+		i = (char *) small_file_addr + SMALL_FILE_OFFSET_3;
+		j = small_buf + SMALL_FILE_HEADER_SIZE;
+		k = SMALL_FILE_LEN_3;
+		while (k-- > 0) {
+			if (*i++ != *j++)
+			printf("i = %d j = %d\n",
+				(int) (i - ((char *) small_file_addr + SMALL_FILE_OFFSET_3)),
+				(int) (j - (small_buf + SMALL_FILE_HEADER_SIZE)));
+		}
+#endif
+        fprintf(stderr,
+            "SendFile 6. ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 7: partial large file at non-zero offset, with header
+	 */
+    rlen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE;
+    if (readn(sockfd, large_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 7. ERROR - large file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_3,
+					large_buf + LARGE_FILE_HEADER_SIZE,
+        								LARGE_FILE_LEN_3) != 0) {
+        fprintf(stderr,
+            "SendFile 7. ERROR - large file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 8: partial large file at non-zero, page-aligned offset, with
+	 * header and trailer
+	 */
+    rlen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE +
+									LARGE_FILE_TRAILER_SIZE;
+    if (readn(sockfd, large_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_4,
+				large_buf + LARGE_FILE_HEADER_SIZE,
+        								LARGE_FILE_LEN_4) != 0) {
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(large_file_trailer,
+				large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_4,
+        				LARGE_FILE_TRAILER_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file trailer corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+    PR_DELETE(small_buf);
+    PR_DELETE(large_buf);
+    PR_Close(sockfd);
+
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(cp->exit_mon);
+    --(*cp->exit_counter);
+    PR_Notify(cp->exit_mon);
+    PR_ExitMonitor(cp->exit_mon);
+    DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * Serve_TransmitFile_Client
+ *    Thread, started by the server, for serving a client connection.
+ *    Trasmits a small file, with a header, and a large file, without
+ *    a header
+ */
+static void
+Serve_TransmitFile_Client(void *arg)
+{
+    Serve_Client_Param *scp = (Serve_Client_Param *) arg;
+    PRFileDesc *sockfd;
+    PRInt32 bytes;
+    PRFileDesc *local_small_file_fd=NULL;
+    PRFileDesc *local_large_file_fd=NULL;
+	PRSendFileData sfd;
+	PRInt32 slen;
+
+    sockfd = scp->sockfd;
+    local_small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDONLY,0);
+
+    if (local_small_file_fd == NULL) {
+        fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n",
+            SMALL_FILE_NAME);
+        failed_already=1;
+        goto done;
+    }
+    local_large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDONLY,0);
+
+    if (local_large_file_fd == NULL) {
+        fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n",
+            LARGE_FILE_NAME);
+        failed_already=1;
+        goto done;
+    }
+    bytes = PR_TransmitFile(sockfd, local_small_file_fd, small_file_header,
+        SMALL_FILE_HEADER_SIZE, PR_TRANSMITFILE_KEEP_OPEN,
+        PR_INTERVAL_NO_TIMEOUT);
+    if (bytes != (SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE)) {
+        fprintf(stderr,
+            "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+    bytes = PR_TransmitFile(sockfd, local_large_file_fd, NULL, 0,
+        PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT);
+    if (bytes != LARGE_FILE_SIZE) {
+        fprintf(stderr,
+            "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+
+	/*
+	 * PR_SendFile test cases
+	 */
+
+	/*
+	 * case 1: small file with header and trailer
+	 */
+	sfd.fd = local_small_file_fd;
+	sfd.file_offset = 0;
+	sfd.file_nbytes = 0;
+	sfd.header = small_file_header;
+	sfd.hlen = SMALL_FILE_HEADER_SIZE;
+	sfd.trailer = small_file_trailer;
+	sfd.tlen = SMALL_FILE_TRAILER_SIZE;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE +
+						SMALL_FILE_TRAILER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 1. PR_SendFile  send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+
+	/*
+	 * case 2: partial large file at zero offset, file with header and trailer
+	 */
+	sfd.fd = local_large_file_fd;
+	sfd.file_offset = 0;
+	sfd.file_nbytes = LARGE_FILE_LEN_1;
+	sfd.header = large_file_header;
+	sfd.hlen = LARGE_FILE_HEADER_SIZE;
+	sfd.trailer = large_file_trailer;
+	sfd.tlen = LARGE_FILE_TRAILER_SIZE;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE +
+						LARGE_FILE_TRAILER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 3: partial small file at non-zero offset, with header
+	 */
+	sfd.fd = local_small_file_fd;
+	sfd.file_offset = SMALL_FILE_OFFSET_1;
+	sfd.file_nbytes = SMALL_FILE_LEN_1;
+	sfd.header = small_file_header;
+	sfd.hlen = SMALL_FILE_HEADER_SIZE;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 4: partial small file at non-zero offset, with trailer
+	 */
+	sfd.fd = local_small_file_fd;
+	sfd.file_offset = SMALL_FILE_OFFSET_2;
+	sfd.file_nbytes = SMALL_FILE_LEN_2;
+	sfd.header = NULL;
+	sfd.hlen = 0;
+	sfd.trailer = small_file_trailer;
+	sfd.tlen = SMALL_FILE_TRAILER_SIZE;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 5: partial large file at non-zero offset, file with header
+	 */
+	sfd.fd = local_large_file_fd;
+	sfd.file_offset = LARGE_FILE_OFFSET_2;
+	sfd.file_nbytes = LARGE_FILE_LEN_2;
+	sfd.header = large_file_header;
+	sfd.hlen = LARGE_FILE_HEADER_SIZE;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 6: partial small file from non-zero offset till end of file, with header
+	 */
+	sfd.fd = local_small_file_fd;
+	sfd.file_offset = SMALL_FILE_OFFSET_3;
+	sfd.file_nbytes = 0;				/* data from offset to end-of-file */
+	sfd.header = small_file_header;
+	sfd.hlen = SMALL_FILE_HEADER_SIZE;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 7: partial large file at non-zero offset till end-of-file, with header
+	 */
+	sfd.fd = local_large_file_fd;
+	sfd.file_offset = LARGE_FILE_OFFSET_3;
+	sfd.file_nbytes = 0;				/* data until end-of-file */
+	sfd.header = large_file_header;
+	sfd.hlen = LARGE_FILE_HEADER_SIZE;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        									PR_INTERVAL_NO_TIMEOUT);
+    slen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 8: partial large file at non-zero page-aligned offset,
+	 * with header and trailer
+	 */
+	sfd.fd = local_large_file_fd;
+	sfd.file_offset = LARGE_FILE_OFFSET_4;
+	sfd.file_nbytes = LARGE_FILE_LEN_4;
+	sfd.header = large_file_header;
+	sfd.hlen = LARGE_FILE_HEADER_SIZE;
+	sfd.trailer = large_file_trailer;
+	sfd.tlen = LARGE_FILE_TRAILER_SIZE;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_CLOSE_SOCKET,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE +
+						LARGE_FILE_TRAILER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+done:
+    if (local_small_file_fd != NULL)
+        PR_Close(local_small_file_fd);
+    if (local_large_file_fd != NULL)
+        PR_Close(local_large_file_fd);
+}
+
+/*
+ * TransmitFile Server
+ *    Server Thread
+ *    Bind an address to a socket and listen for incoming connections
+ *    Create worker threads to service clients
+ */
+static void
+TransmitFile_Server(void *arg)
+{
+    PRThread **t = NULL;  /* an array of PRThread pointers */
+    Server_Param *sp = (Server_Param *) arg;
+    Serve_Client_Param *scp;
+    PRFileDesc *sockfd = NULL, *newsockfd;
+    PRNetAddr netaddr;
+    PRInt32 i;
+
+    t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *));
+    if (t == NULL) {
+        fprintf(stderr, "prsocket_test: run out of memory\n");
+        failed_already=1;
+        goto exit;
+    }
+    /*
+     * Create a tcp socket
+     */
+    if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n");
+        failed_already=1;
+        goto exit;
+    }
+    memset(&netaddr, 0 , sizeof(netaddr));
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
+    netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+    i = 0;
+    while (PR_Bind(sockfd, &netaddr) < 0) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            netaddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
+        failed_already=1;
+        perror("PR_Bind");
+        goto exit;
+    }
+
+    if (PR_Listen(sockfd, 32) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
+        failed_already=1;
+        goto exit;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,
+            "prsocket_test: ERROR - PR_GetSockName failed\n");
+        failed_already=1;
+        goto exit;
+    }
+
+    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+    tcp_server_addr.inet.family = netaddr.inet.family;
+    tcp_server_addr.inet.port = netaddr.inet.port;
+    tcp_server_addr.inet.ip = netaddr.inet.ip;
+
+    /*
+     * Wake up parent thread because server address is bound and made
+     * available in the global variable 'tcp_server_addr'
+     */
+    PR_PostSem(sp->addr_sem);
+
+    for (i = 0; i < num_transmitfile_clients ; i++) {
+        /* test both null and non-null 'addr' argument to PR_Accept */
+        PRNetAddr *addrp = (i%2 ? &netaddr: NULL);
+
+        if ((newsockfd = PR_Accept(sockfd, addrp,
+            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+            fprintf(stderr,
+                "prsocket_test: ERROR - PR_Accept failed\n");
+            failed_already=1;
+            goto exit;
+        }
+        /* test both regular and emulated PR_SendFile */
+        if (i%2) {
+            PRFileDesc *layer = PR_CreateIOLayerStub(
+                emuSendFileIdentity, &emuSendFileMethods);
+            if (layer == NULL) {
+                fprintf(stderr,
+                    "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n");
+                failed_already=1;
+                goto exit;
+            }
+            if (PR_PushIOLayer(newsockfd, PR_TOP_IO_LAYER, layer)
+                    == PR_FAILURE) {
+                fprintf(stderr,
+                    "prsocket_test: ERROR - PR_PushIOLayer failed\n");
+                failed_already=1;
+                goto exit;
+            }
+        }
+        scp = PR_NEW(Serve_Client_Param);
+        if (scp == NULL) {
+            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+            failed_already=1;
+            goto exit;
+        }
+
+        /*
+         * Start a Serve_Client thread for each incoming connection
+         */
+        scp->sockfd = newsockfd;
+        scp->datalen = sp->datalen;
+
+        t[i] = PR_CreateThread(PR_USER_THREAD,
+            Serve_TransmitFile_Client, (void *)scp, 
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_JOINABLE_THREAD,
+            0);
+        if (t[i] == NULL) {
+            fprintf(stderr,
+                "prsocket_test: PR_CreateThread failed\n");
+            failed_already=1;
+            goto exit;
+        }
+        DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t));
+    }
+
+    /*
+     * Wait for all the worker threads to end, so that we know
+     * they are no longer using the small and large file fd's.
+     */
+
+    for (i = 0; i < num_transmitfile_clients; i++) {
+        PR_JoinThread(t[i]);
+    }
+
+exit:
+    if (t) {
+        PR_DELETE(t);
+    }
+    if (sockfd) {
+        PR_Close(sockfd);
+    }
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(sp->exit_mon);
+    --(*sp->exit_counter);
+    PR_Notify(sp->exit_mon);
+    PR_ExitMonitor(sp->exit_mon);
+    DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * Socket_Misc_Test    - test miscellaneous functions 
+ *    
+ */
+static PRInt32
+Socket_Misc_Test(void)
+{
+    PRIntn i, rv = 0, bytes, count, len;
+    PRThread *t;
+    PRSemaphore *server_sem;
+    Server_Param *sparamp;
+    Client_Param *cparamp;
+    PRMonitor *mon2;
+    PRInt32    datalen;
+
+    /*
+ * We deliberately pick a buffer size that is not a nice multiple
+ * of 1024.
+ */
+#define TRANSMITFILE_BUF_SIZE    (4 * 1024 - 11)
+
+    typedef struct {
+        char    data[TRANSMITFILE_BUF_SIZE];
+    } file_buf;
+    file_buf *buf = NULL;
+
+    /*
+     * create file(s) to be transmitted
+     */
+    if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
+        printf("prsocket_test failed to create dir %s\n",TEST_DIR);
+        failed_already=1;
+        return -1;
+    }
+
+    small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);
+
+    if (small_file_fd == NULL) {
+        fprintf(stderr,"prsocket_test failed to create/open file %s\n",
+            SMALL_FILE_NAME);
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    buf = PR_NEW(file_buf);
+    if (buf == NULL) {
+        fprintf(stderr,"prsocket_test failed to allocate buffer\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    /*
+     * fill in random data
+     */
+    for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
+        buf->data[i] = i;
+    }
+    count = 0;
+    do {
+        len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
+            TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count);
+        bytes = PR_Write(small_file_fd, buf->data, len);
+        if (bytes <= 0) {
+            fprintf(stderr,
+                "prsocket_test failed to write to file %s\n",
+                SMALL_FILE_NAME);
+            failed_already=1;
+            rv = -1;
+            goto done;
+        }
+        count += bytes;
+    } while (count < SMALL_FILE_SIZE);
+#ifdef XP_UNIX
+    /*
+     * map the small file; used in checking for data corruption
+     */
+    small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ,
+        MAP_SHARED, small_file_fd->secret->md.osfd, 0);
+    if (small_file_addr == (void *) -1) {
+        fprintf(stderr,"prsocket_test failed to mmap file %s\n",
+            SMALL_FILE_NAME);
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+#endif
+    /*
+     * header for small file
+     */
+    small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE);
+    if (small_file_header == NULL) {
+        fprintf(stderr,"prsocket_test failed to malloc header file\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    memset(small_file_header, (int) PR_IntervalNow(),
+        SMALL_FILE_HEADER_SIZE);
+    /*
+     * trailer for small file
+     */
+    small_file_trailer = PR_MALLOC(SMALL_FILE_TRAILER_SIZE);
+    if (small_file_trailer == NULL) {
+        fprintf(stderr,"prsocket_test failed to malloc header trailer\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    memset(small_file_trailer, (int) PR_IntervalNow(),
+        SMALL_FILE_TRAILER_SIZE);
+    /*
+     * setup large file
+     */
+    large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);
+
+    if (large_file_fd == NULL) {
+        fprintf(stderr,"prsocket_test failed to create/open file %s\n",
+            LARGE_FILE_NAME);
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    /*
+     * fill in random data
+     */
+    for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
+        buf->data[i] = i;
+    }
+    count = 0;
+    do {
+        len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
+            TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count);
+        bytes = PR_Write(large_file_fd, buf->data, len);
+        if (bytes <= 0) {
+            fprintf(stderr,
+                "prsocket_test failed to write to file %s: (%ld, %ld)\n",
+                LARGE_FILE_NAME,
+                PR_GetError(), PR_GetOSError());
+            failed_already=1;
+            rv = -1;
+            goto done;
+        }
+        count += bytes;
+    } while (count < LARGE_FILE_SIZE);
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    /*
+     * map the large file; used in checking for data corruption
+     */
+    large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ,
+        MAP_SHARED, large_file_fd->secret->md.osfd, 0);
+    if (large_file_addr == (void *) -1) {
+        fprintf(stderr,"prsocket_test failed to mmap file %s\n",
+            LARGE_FILE_NAME);
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+#endif
+    /*
+     * header for large file
+     */
+    large_file_header = PR_MALLOC(LARGE_FILE_HEADER_SIZE);
+    if (large_file_header == NULL) {
+        fprintf(stderr,"prsocket_test failed to malloc header file\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    memset(large_file_header, (int) PR_IntervalNow(),
+        LARGE_FILE_HEADER_SIZE);
+    /*
+     * trailer for large file
+     */
+    large_file_trailer = PR_MALLOC(LARGE_FILE_TRAILER_SIZE);
+    if (large_file_trailer == NULL) {
+        fprintf(stderr,"prsocket_test failed to malloc header trailer\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    memset(large_file_trailer, (int) PR_IntervalNow(),
+        LARGE_FILE_TRAILER_SIZE);
+
+    datalen = tcp_mesg_size;
+    thread_count = 0;
+    /*
+     * start the server thread
+     */
+    sparamp = PR_NEW(Server_Param);
+    if (sparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    server_sem = PR_NewSem(0);
+    if (server_sem == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    mon2 = PR_NewMonitor();
+    if (mon2 == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    PR_EnterMonitor(mon2);
+
+    sparamp->addr_sem = server_sem;
+    sparamp->exit_mon = mon2;
+    sparamp->exit_counter = &thread_count;
+    sparamp->datalen = datalen;
+    t = PR_CreateThread(PR_USER_THREAD,
+        TransmitFile_Server, (void *)sparamp, 
+        PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD,
+        PR_UNJOINABLE_THREAD,
+        0);
+    if (t == NULL) {
+        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    DPRINTF(("Created TCP server = 0x%x\n", t));
+    thread_count++;
+
+    /*
+     * wait till the server address is setup
+     */
+    PR_WaitSem(server_sem);
+
+    /*
+     * Now start a bunch of client threads
+     */
+
+    cparamp = PR_NEW(Client_Param);
+    if (cparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    cparamp->server_addr = tcp_server_addr;
+    cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    cparamp->exit_mon = mon2;
+    cparamp->exit_counter = &thread_count;
+    cparamp->datalen = datalen;
+    for (i = 0; i < num_transmitfile_clients; i++) {
+        t = create_new_thread(PR_USER_THREAD,
+            TransmitFile_Client, (void *) cparamp,
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD,
+            0, i);
+        if (t == NULL) {
+            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+            rv = -1;
+            failed_already=1;
+            goto done;
+        }
+        DPRINTF(("Created TransmitFile client = 0x%lx\n", t));
+        thread_count++;
+    }
+    /* Wait for server and client threads to exit */
+    while (thread_count) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("Socket_Misc_Test - thread_count  = %d\n", thread_count));
+    }
+    PR_ExitMonitor(mon2);
+done:
+    if (buf) {
+        PR_DELETE(buf);
+    }
+#if defined(XP_UNIX) && !defined(SYMBIAN)
+    munmap((char*)small_file_addr, SMALL_FILE_SIZE);
+    munmap((char*)large_file_addr, LARGE_FILE_SIZE);
+#endif
+    PR_Close(small_file_fd);
+    PR_Close(large_file_fd);
+    if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
+            SMALL_FILE_NAME);
+        failed_already=1;
+    }
+    if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
+            LARGE_FILE_NAME);
+        failed_already=1;
+    }
+    if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n",
+            TEST_DIR, PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+
+    printf("%-29s%s","Socket_Misc_Test",":");
+    printf("%2d Server %2d Clients\n",1, num_transmitfile_clients);
+    printf("%30s Sizes of Transmitted Files  - %4d KB, %2d MB \n",":",
+        SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024));
+
+
+    return rv;
+}
+/************************************************************************/
+
+/*
+ * Test Socket NSPR APIs
+ */
+
+int main(int argc, char **argv)
+{
+    /*
+     * -d           debug mode
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetConcurrency(4);
+
+    emuSendFileIdentity = PR_GetUniqueIdentity("Emulated SendFile");
+    emuSendFileMethods = *PR_GetDefaultIOMethods();
+    emuSendFileMethods.transmitfile = emu_TransmitFile;
+    emuSendFileMethods.sendfile = emu_SendFile;
+
+    /*
+     * run client-server test with TCP, Ipv4-Ipv4
+     */
+	printf("TCP Client/Server Test - IPv4/Ipv4\n");
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+    /*
+     * client-server test, Ipv6-Ipv4
+     */
+	client_domain = PR_AF_INET6;
+	printf("TCP Client/Server Test - IPv6/Ipv4\n");
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+    /*
+     * client-server test, Ipv4-Ipv6
+     */
+	client_domain = PR_AF_INET;
+	server_domain = PR_AF_INET6;
+	printf("TCP Client/Server Test - IPv4/Ipv6\n");
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+    /*
+     * client-server test, Ipv6-Ipv6
+     */
+	client_domain = PR_AF_INET6;
+	server_domain = PR_AF_INET6;
+	printf("TCP Client/Server Test - IPv6/Ipv6\n");
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+	test_cancelio = 0;
+	
+#if defined(SYMBIAN) && !defined(__WINSCW__)
+	/* UDP tests only run on Symbian devices but not emulator */
+    /*
+     * run client-server test with UDP, IPv4/IPv4
+     */
+	printf("UDP Client/Server Test - IPv4/Ipv4\n");
+	client_domain = PR_AF_INET;
+	server_domain = PR_AF_INET;
+    if (UDP_Socket_Client_Server_Test() < 0) {
+        printf("UDP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("UDP_Socket_Client_Server_Test Passed\n");
+    /*
+     * run client-server test with UDP, IPv6/IPv4
+     */
+	printf("UDP Client/Server Test - IPv6/Ipv4\n");
+	client_domain = PR_AF_INET6;
+	server_domain = PR_AF_INET;
+    if (UDP_Socket_Client_Server_Test() < 0) {
+        printf("UDP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("UDP_Socket_Client_Server_Test Passed\n");
+    /*
+     * run client-server test with UDP,IPv4-IPv6
+     */
+	printf("UDP Client/Server Test - IPv4/Ipv6\n");
+	client_domain = PR_AF_INET;
+	server_domain = PR_AF_INET6;
+    if (UDP_Socket_Client_Server_Test() < 0) {
+        printf("UDP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("UDP_Socket_Client_Server_Test Passed\n");
+    /*
+     * run client-server test with UDP,IPv6-IPv6
+     */
+	printf("UDP Client/Server Test - IPv6/Ipv6\n");
+	client_domain = PR_AF_INET6;
+	server_domain = PR_AF_INET6;
+    if (UDP_Socket_Client_Server_Test() < 0) {
+        printf("UDP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("UDP_Socket_Client_Server_Test Passed\n");
+#endif
+    
+    /*
+     * Misc socket tests - including transmitfile, etc.
+     */
+
+    /* File transmission test can not be done in Symbian OS because of 
+     * large file's size and the incomplete mmap() implementation. */
+#if !defined(WIN16) && !defined(SYMBIAN)
+    /*
+** The 'transmit file' test does not run because
+** transmit file is not implemented in NSPR yet.
+**
+*/
+    if (Socket_Misc_Test() < 0) {
+        printf("Socket_Misc_Test failed\n");
+        failed_already=1;
+        goto done;
+    } else
+        printf("Socket_Misc_Test passed\n");
+
+    /*
+     * run client-server test with TCP again to test
+     * recycling used sockets from PR_TransmitFile().
+     */
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+#endif
+
+done:
+    PR_Cleanup();
+    if (failed_already) return 1;
+    else return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockopt.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockopt.c
new file mode 100644
index 0000000..5c7a899
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockopt.c
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "prio.h"
+#include "prinit.h"
+#include "prprf.h"
+#include "obsolete/probslet.h"
+
+#include "plerror.h"
+
+static PRFileDesc *err = NULL;
+static PRBool failed = PR_FALSE;
+
+static void Failed(const char *msg1, const char *msg2)
+{
+    if (NULL != msg1) PR_fprintf(err, "%s ", msg1);
+    PL_FPrintError(err, msg2);
+    failed = PR_TRUE;
+}  /* Failed */
+
+static PRSockOption Incr(PRSockOption *option)
+{
+    PRIntn val = ((PRIntn)*option) + 1;
+    *option = (PRSockOption)val;
+    return (PRSockOption)val;
+}  /* Incr */
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+    PRFileDesc *udp = PR_NewUDPSocket();
+    PRFileDesc *tcp = PR_NewTCPSocket();
+    const char *tag[] =
+    {
+        "PR_SockOpt_Nonblocking",     /* nonblocking io */
+        "PR_SockOpt_Linger",          /* linger on close if data present */
+        "PR_SockOpt_Reuseaddr",       /* allow local address reuse */
+        "PR_SockOpt_Keepalive",       /* keep connections alive */
+        "PR_SockOpt_RecvBufferSize",  /* send buffer size */
+        "PR_SockOpt_SendBufferSize",  /* receive buffer size */
+
+        "PR_SockOpt_IpTimeToLive",    /* time to live */
+        "PR_SockOpt_IpTypeOfService", /* type of service and precedence */
+
+        "PR_SockOpt_AddMember",       /* add an IP group membership */
+        "PR_SockOpt_DropMember",      /* drop an IP group membership */
+        "PR_SockOpt_McastInterface",  /* multicast interface address */
+        "PR_SockOpt_McastTimeToLive", /* multicast timetolive */
+        "PR_SockOpt_McastLoopback",   /* multicast loopback */
+
+        "PR_SockOpt_NoDelay",         /* don't delay send to coalesce packets */
+        "PR_SockOpt_MaxSegment",      /* maximum segment size */
+        "PR_SockOpt_Broadcast",       /* Enable broadcast */
+        "PR_SockOpt_Last"
+    };
+
+    err = PR_GetSpecialFD(PR_StandardError);
+    PR_STDIO_INIT();
+
+    if (NULL == udp) Failed("PR_NewUDPSocket()", NULL);
+    else if (NULL == tcp) Failed("PR_NewTCPSocket()", NULL);
+    else
+    {
+        PRSockOption option;
+        PRUint32 segment = 1024;
+        PRNetAddr addr;
+
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr);
+        if (PR_FAILURE == rv) Failed("PR_InitializeNetAddr()", NULL);
+        rv = PR_Bind(udp, &addr);
+        if (PR_FAILURE == rv) Failed("PR_Bind()", NULL);
+        for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option))
+        {
+            PRSocketOptionData data;
+            PRFileDesc *fd = tcp;
+            data.option = option;
+            switch (option)
+            {
+                case PR_SockOpt_Nonblocking:
+                    data.value.non_blocking = PR_TRUE;
+                    break;    
+#ifndef SYMBIAN
+                case PR_SockOpt_Linger:
+                    data.value.linger.polarity = PR_TRUE;
+                    data.value.linger.linger = PR_SecondsToInterval(2);          
+                    break;    
+#endif
+                case PR_SockOpt_Reuseaddr:
+                    data.value.reuse_addr = PR_TRUE;      
+                    break;    
+                case PR_SockOpt_Keepalive:       
+                    data.value.keep_alive = PR_TRUE;      
+                    break;    
+                case PR_SockOpt_RecvBufferSize:
+                    data.value.recv_buffer_size = segment;  
+                    break;    
+                case PR_SockOpt_SendBufferSize:  
+                    data.value.send_buffer_size = segment;  
+                    break;    
+#ifndef SYMBIAN
+                case PR_SockOpt_IpTimeToLive:
+                    data.value.ip_ttl = 64;  
+                    break;    
+                case PR_SockOpt_IpTypeOfService:
+                    data.value.tos = 0; 
+                    break;    
+                case PR_SockOpt_McastTimeToLive:
+                    fd = udp; 
+                    data.value.mcast_ttl = 4; 
+                    break;    
+                case PR_SockOpt_McastLoopback:
+                    fd = udp; 
+                    data.value.mcast_loopback = PR_TRUE; 
+                    break;    
+#endif
+                case PR_SockOpt_NoDelay:
+                    data.value.no_delay = PR_TRUE;         
+                    break;    
+#ifndef WIN32
+                case PR_SockOpt_MaxSegment:
+                    data.value.max_segment = segment;      
+                    break;    
+#endif
+#ifndef SYMBIAN
+                case PR_SockOpt_Broadcast:
+                    fd = udp; 
+                    data.value.broadcast = PR_TRUE;         
+                    break;    
+#endif
+                default: continue;
+            }
+
+			/*
+			 * TCP_MAXSEG can only be read, not set
+			 */
+            if (option != PR_SockOpt_MaxSegment) {
+#ifdef WIN32
+            	if (option != PR_SockOpt_McastLoopback)
+#endif
+				{
+            		rv = PR_SetSocketOption(fd, &data);
+            		if (PR_FAILURE == rv)
+							Failed("PR_SetSocketOption()", tag[option]);
+				}
+			}
+
+            rv = PR_GetSocketOption(fd, &data);
+            if (PR_FAILURE == rv) Failed("PR_GetSocketOption()", tag[option]);
+        }
+        PR_Close(udp);
+        PR_Close(tcp);
+    }
+    PR_fprintf(err, "%s\n", (failed) ? "FAILED" : "PASSED");
+    return (failed) ? 1 : 0;
+}  /* main */
+
+/* sockopt.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockping.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockping.c
new file mode 100644
index 0000000..998ffad
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockping.c
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: sockping.c
+ *
+ * Description:
+ * This test runs in conjunction with the sockpong test.
+ * This test creates a socket pair and passes one socket
+ * to the sockpong test.  Then this test writes "ping" to
+ * to the sockpong test and the sockpong test writes "pong"
+ * back.  To run this pair of tests, just invoke sockping.
+ *
+ * Tested areas: process creation, socket pairs, file
+ * descriptor inheritance.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+#include "prproces.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+static char *child_argv[] = { "sockpong", NULL };
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *sock[2];
+    PRStatus status;
+    PRProcess *process;
+    PRProcessAttr *attr;
+    char buf[1024];
+    PRInt32 nBytes;
+    PRInt32 exitCode;
+    int idx;
+
+    status = PR_NewTCPSocketPair(sock);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_NewTCPSocketPair failed\n");
+        exit(1);
+    }
+
+    status = PR_SetFDInheritable(sock[0], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    status = PR_SetFDInheritable(sock[1], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+
+    attr = PR_NewProcessAttr();
+    if (attr == NULL) {
+        fprintf(stderr, "PR_NewProcessAttr failed\n");
+        exit(1);
+    }
+
+    status = PR_ProcessAttrSetInheritableFD(attr, sock[1], "SOCKET");
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n");
+        exit(1);
+    }
+
+    process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
+    if (process == NULL) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+    PR_DestroyProcessAttr(attr);
+    status = PR_Close(sock[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        strcpy(buf, "ping");
+        printf("ping process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(sock[0], buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(sock[0], buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        printf("ping process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "pong") != 0) {
+            fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
+    status = PR_Close(sock[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_WaitProcess(process, &exitCode);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exitCode == 0) {
+        printf("PASS\n");
+        return 0;
+    } else {
+        printf("FAIL\n");
+        return 1;
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockpong.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockpong.c
new file mode 100644
index 0000000..5c25ab8
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sockpong.c
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: sockpong.c
+ *
+ * Description:
+ * This test runs in conjunction with the sockping test.
+ * The sockping test creates a socket pair and passes one
+ * socket to this test.  Then the sockping test writes
+ * "ping" to this test and this test writes "pong" back.
+ * To run this pair of tests, just invoke sockping.
+ *
+ * Tested areas: process creation, socket pairs, file
+ * descriptor inheritance.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *sock;
+    PRStatus status;
+    char buf[1024];
+    PRInt32 nBytes;
+    int idx;
+
+    sock = PR_GetInheritedFD("SOCKET");
+    if (sock == NULL) {
+        fprintf(stderr, "PR_GetInheritedFD failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(sock, PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(sock, buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        printf("pong process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "ping") != 0) {
+            fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+
+        strcpy(buf, "pong");
+        printf("pong process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(sock, buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed\n");
+            exit(1);
+        }
+    }
+
+    status = PR_Close(sock);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sprintf.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sprintf.c
new file mode 100644
index 0000000..7fe2ac1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sprintf.c
@@ -0,0 +1,454 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:	sprintf.c
+ * Description:
+ *     This is a test program for the PR_snprintf() functions defined
+ *     in prprf.c.  This test program is based on ns/nspr/tests/sprintf.c,
+ *     revision 1.10.
+ * Modification History:
+ *	20-May-1997 AGarcia replaced printf statment to return PASS\n. This is to be used by the
+ *				regress tool parsing routine.
+ ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+ *			recognize the return code from tha main program.
+ */
+
+#include "prinit.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prlong.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define countof(a) (sizeof(a)/sizeof(a[0]))
+
+static char sbuf[20000];
+
+
+/*
+** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
+** Make sure the results are identical
+*/
+static void test_i(char *pattern, int i)
+{
+    char *s;
+    char buf[200];
+    int n;
+
+    /* try all three routines */
+    s = PR_smprintf(pattern, i);
+    PR_ASSERT(s != 0);
+    n = PR_snprintf(buf, sizeof(buf), pattern, i);
+    PR_ASSERT(n <= sizeof(buf));
+    sprintf(sbuf, pattern, i);
+
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0) ||
+	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
+	fprintf(stderr,
+	   "pattern='%s' i=%d\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	   pattern, i, s, buf, sbuf);
+	   PR_smprintf_free(s);
+	exit(-1);
+    }
+	PR_smprintf_free(s);
+}
+
+static void TestI(void)
+{
+    static int nums[] = {
+	0, 1, -1, 10, -10,
+	32767, -32768,
+    };
+    static char *signs[] = {
+	"",
+	"0",	"-",	"+", " ",
+	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
+	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
+	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
+	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
+	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
+	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
+	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
+	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
+	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
+	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
+    };
+    static char *precs[] = {
+	"", "3", "5", "43",
+	"7.3", "7.5", "7.11", "7.43",
+    };
+    static char *formats[] = {
+	"d", "o", "x", "u",
+	"hd", "ho", "hx", "hu"
+    };
+    int f, s, n, p;
+    char fmt[20];
+
+    for (f = 0; f < countof(formats); f++) {
+	for (s = 0; s < countof(signs); s++) {
+	    for (p = 0; p < countof(precs); p++) {
+		fmt[0] = '%';
+		fmt[1] = 0;
+		if (signs[s]) strcat(fmt, signs[s]);
+		if (precs[p]) strcat(fmt, precs[p]);
+		if (formats[f]) strcat(fmt, formats[f]);
+		for (n = 0; n < countof(nums); n++) {
+		    test_i(fmt, nums[n]);
+		}
+	    }
+	}
+    }
+}
+
+/************************************************************************/
+
+/*
+** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
+** Make sure the results are identical
+*/
+static void test_l(char *pattern, char *spattern, PRInt32 l)
+{
+    char *s;
+    char buf[200];
+    int n;
+
+    /* try all three routines */
+    s = PR_smprintf(pattern, l);
+    PR_ASSERT(s != 0);
+    n = PR_snprintf(buf, sizeof(buf), pattern, l);
+    PR_ASSERT(n <= sizeof(buf));
+    sprintf(sbuf, spattern, l);
+
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0) ||
+	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
+	fprintf(stderr,
+	   "pattern='%s' l=%ld\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	   pattern, l, s, buf, sbuf);
+	PR_smprintf_free(s);
+	exit(-1);
+    }
+	PR_smprintf_free(s);
+}
+
+static void TestL(void)
+{
+    static PRInt32 nums[] = {
+	0,
+	1,
+	-1,
+	10,
+	-10,
+	32767,
+	-32768,
+	PR_INT32(0x7fffffff), /* 2147483647L */
+	-1 - PR_INT32(0x7fffffff)  /* -2147483648L */
+    };
+    static char *signs[] = {
+	"",
+	"0",	"-",	"+", " ",
+	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
+	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
+	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
+	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
+	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
+	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
+	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
+	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
+	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
+	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
+    };
+    static char *precs[] = {
+	"", "3", "5", "43",
+	".3", ".43",
+	"7.3", "7.5", "7.11", "7.43",
+    };
+    static char *formats[] = { "ld", "lo", "lx", "lu" };
+
+#if PR_BYTES_PER_INT == 4
+    static char *sformats[] = { "d", "o", "x", "u" };
+#elif PR_BYTES_PER_LONG == 4
+    static char *sformats[] = { "ld", "lo", "lx", "lu" };
+#else
+#error Neither int nor long is 4 bytes on this platform
+#endif
+
+    int f, s, n, p;
+    char fmt[40], sfmt[40];
+
+    for (f = 0; f < countof(formats); f++) {
+	for (s = 0; s < countof(signs); s++) {
+	    for (p = 0; p < countof(precs); p++) {
+		fmt[0] = '%';
+		fmt[1] = 0;
+		if (signs[s]) strcat(fmt, signs[s]);
+		if (precs[p]) strcat(fmt, precs[p]);
+		strcpy(sfmt, fmt);
+		if (formats[f]) strcat(fmt, formats[f]);
+		if (sformats[f]) strcat(sfmt, sformats[f]);
+		for (n = 0; n < countof(nums); n++) {
+		    test_l(fmt, sfmt, nums[n]);
+		}
+	    }
+	}
+    }
+}
+
+/************************************************************************/
+
+/*
+** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
+** Make sure the results are identical
+*/
+static void test_ll(char *pattern, char *spattern, PRInt64 l)
+{
+    char *s;
+    char buf[200];
+    int n;
+
+    /* try all three routines */
+    s = PR_smprintf(pattern, l);
+    PR_ASSERT(s != 0);
+    n = PR_snprintf(buf, sizeof(buf), pattern, l);
+    PR_ASSERT(n <= sizeof(buf));
+#if defined(HAVE_LONG_LONG)
+    sprintf(sbuf, spattern, l);
+
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0) ||
+	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
+#if PR_BYTES_PER_LONG == 8
+#define FORMAT_SPEC "%ld"
+#elif defined(WIN16)
+#define FORMAT_SPEC "%Ld"
+#elif defined(WIN32)
+#define FORMAT_SPEC "%I64d"
+#else
+#define FORMAT_SPEC "%lld"
+#endif
+	fprintf(stderr,
+	    "pattern='%s' ll=" FORMAT_SPEC "\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	    pattern, l, s, buf, sbuf);
+	printf("FAIL\n");
+	PR_smprintf_free(s);
+	exit(-1);
+    }
+	PR_smprintf_free(s);
+#else
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0)) {
+	fprintf(stderr,
+	    "pattern='%s'\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	    pattern, s, buf, sbuf);
+	printf("FAIL\n");
+	PR_smprintf_free(s);
+        exit(-1);
+    }
+	PR_smprintf_free(s);
+#endif
+}
+
+static void TestLL(void)
+{
+    static PRInt64 nums[] = {
+	LL_INIT(0, 0),
+	LL_INIT(0, 1),
+	LL_INIT(0xffffffff, 0xffffffff),  /* -1 */
+	LL_INIT(0, 10),
+	LL_INIT(0xffffffff, 0xfffffff6),  /* -10 */
+	LL_INIT(0, 32767),
+	LL_INIT(0xffffffff, 0xffff8000),  /* -32768 */
+	LL_INIT(0, 0x7fffffff),  /* 2147483647 */
+	LL_INIT(0xffffffff, 0x80000000),  /* -2147483648 */
+	LL_INIT(0x7fffffff, 0xffffffff),  /* 9223372036854775807 */
+	LL_INIT(0x80000000, 0)            /* -9223372036854775808 */
+    };
+
+    static char *signs[] = {
+	"",
+	"0",	"-",	"+", " ",
+	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
+	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
+	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
+	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
+	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
+	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
+	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
+	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
+	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
+	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
+    };
+    static char *precs[] = {
+	"", "3", "5", "43",
+	".3", ".43",
+	"7.3", "7.5", "7.11", "7.43",
+    };
+    static char *formats[] = { "lld", "llo", "llx", "llu" };
+
+#if PR_BYTES_PER_LONG == 8
+    static char *sformats[] = { "ld", "lo", "lx", "lu" };
+#elif defined(WIN16)
+    /* Watcom uses the format string "%Ld" instead of "%lld". */
+    static char *sformats[] = { "Ld", "Lo", "Lx", "Lu" };
+#elif defined(WIN32)
+    static char *sformats[] = { "I64d", "I64o", "I64x", "I64u" };
+#else
+    static char *sformats[] = { "lld", "llo", "llx", "llu" };
+#endif
+
+    int f, s, n, p;
+    char fmt[40], sfmt[40];
+
+    for (f = 0; f < countof(formats); f++) {
+	for (s = 0; s < countof(signs); s++) {
+	    for (p = 0; p < countof(precs); p++) {
+		fmt[0] = '%';
+		fmt[1] = 0;
+		if (signs[s]) strcat(fmt, signs[s]);
+		if (precs[p]) strcat(fmt, precs[p]);
+		strcpy(sfmt, fmt);
+		if (formats[f]) strcat(fmt, formats[f]);
+		if (sformats[f]) strcat(sfmt, sformats[f]);
+		for (n = 0; n < countof(nums); n++) {
+		    test_ll(fmt, sfmt, nums[n]);
+		}
+	    }
+	}
+    }
+}
+
+/************************************************************************/
+
+/*
+** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
+** Make sure the results are identical
+*/
+static void test_s(char *pattern, char *ss)
+{
+    char *s;
+    unsigned char before[8];
+    char buf[200];
+    unsigned char after[8];
+    int n;
+
+    memset(before, 0xBB, 8);
+    memset(after, 0xAA, 8);
+
+    /* try all three routines */
+    s = PR_smprintf(pattern, ss);
+    PR_ASSERT(s != 0);
+    n = PR_snprintf(buf, sizeof(buf), pattern, ss);
+    PR_ASSERT(n <= sizeof(buf));
+    sprintf(sbuf, pattern, ss);
+
+    for (n = 0; n < 8; n++) {
+	PR_ASSERT(before[n] == 0xBB);
+	PR_ASSERT(after[n] == 0xAA);
+    }
+
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0) ||
+	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
+	fprintf(stderr,
+	   "pattern='%s' ss=%.20s\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	   pattern, ss, s, buf, sbuf);
+	printf("FAIL\n");
+	PR_smprintf_free(s);
+	exit(-1);
+    }
+	PR_smprintf_free(s);
+}
+
+static void TestS(void)
+{
+    static char *strs[] = {
+	"",
+	"a",
+	"abc",
+	"abcde",
+	"abcdefABCDEF",
+	"abcdefghijklmnopqrstuvwxyz0123456789!@#$"
+	    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$"
+	    "abcdefghijklmnopqrstuvwxyz0123456789!@#$",
+    };
+    /* '0' is not relevant to printing strings */
+    static char *signs[] = {
+	"",
+	"-",	"+",	" ",
+	"-+",	"- ",	"+-",	"+ ",	" -",	" +",
+	"-+ ",	"- +",	"+- ",	"+ -",	" -+",	" +-",
+    };
+    static char *precs[] = {
+	"", "3", "5", "43",
+	".3", ".43",
+	"7.3", "7.5", "7.11", "7.43",
+    };
+    static char *formats[] = { "s" };
+    int f, s, n, p;
+    char fmt[40];
+
+    for (f = 0; f < countof(formats); f++) {
+	for (s = 0; s < countof(signs); s++) {
+	    for (p = 0; p < countof(precs); p++) {
+		fmt[0] = '%';
+		fmt[1] = 0;
+		if (signs[s]) strcat(fmt+strlen(fmt), signs[s]);
+		if (precs[p]) strcat(fmt+strlen(fmt), precs[p]);
+		if (formats[f]) strcat(fmt+strlen(fmt), formats[f]);
+		for (n = 0; n < countof(strs); n++) {
+		    test_s(fmt, strs[n]);
+		}
+	    }
+	}
+    }
+}
+
+/************************************************************************/
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+    TestI();
+    TestL();
+    TestLL();
+    TestS();
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sproc_ch.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sproc_ch.c
new file mode 100644
index 0000000..20b35ac
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sproc_ch.c
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Test sproc_ch.c
+ *
+ * The purpose of this test and the sproc_p.c test is to test the shutdown
+ * of all the IRIX sprocs in a program when one of them dies due to an error.
+ *
+ * There are three sprocs in this test: the parent, the child, and the 
+ * grandchild.  The parent and child sprocs never stop on their own.
+ * The grandchild sproc gets a segmentation fault and dies.  You should
+ * You should use "ps" to see if the parent and child sprocs are killed
+ * after the grandchild dies.
+ */
+
+#include "prinit.h"
+#include <stdio.h>
+
+#if !defined(IRIX)
+
+int main(int argc, char **argv)
+{
+    printf("This test applies to IRIX only.\n");
+    return 0;
+}
+
+#else  /* IRIX */
+
+#include "prthread.h"
+#include <sys/types.h>
+#include <unistd.h>
+
+void SegFault(void *unused)
+{
+    int *p = 0;
+
+    printf("The grandchild sproc has pid %d.\n", getpid());
+    printf("The grandchild sproc will get a segmentation fault and die.\n");
+    printf("The parent and child sprocs should be killed after the "
+            "grandchild sproc dies.\n");
+    printf("Use 'ps' to make sure this is so.\n");
+    fflush(stdout);
+    /* Force a segmentation fault */
+    *p = 0;
+}
+
+void NeverStops(void *unused)
+{
+    int i = 0;
+
+    printf("The child sproc has pid %d.\n", getpid());
+    printf("The child sproc won't stop on its own.\n");
+    fflush(stdout);
+
+    /* create the grandchild sproc */
+    PR_CreateThread(PR_USER_THREAD, SegFault, NULL,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    while (1) {
+	i++;
+    }
+}
+
+int main()
+{
+    int i= 0;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+    printf("The parent sproc has pid %d.\n", getpid());
+    printf("The parent sproc won't stop on its own.\n");
+    fflush(stdout);
+
+    /* create the child sproc */
+    PR_CreateThread(PR_USER_THREAD, NeverStops, NULL,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    while (1) {
+	i++;
+    }
+    return 0;
+}
+
+#endif  /* IRIX */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/sproc_p.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sproc_p.c
new file mode 100644
index 0000000..7cae380
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/sproc_p.c
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Test sproc_p.c
+ *
+ * The purpose of this test and the sproc_ch.c test is to test the shutdown
+ * of all the IRIX sprocs in a program when one of them dies due to an error.
+ *
+ * In this test, the parent sproc gets a segmentation fault and dies.
+ * The child sproc never stops on its own.  You should use "ps" to see if
+ * the child sproc is killed after the parent dies.
+ */
+
+#include "prinit.h"
+#include <stdio.h>
+
+#if !defined(IRIX)
+
+int main(int argc, char **argv)
+{
+    printf("This test applies to IRIX only.\n");
+    return 0;
+}
+
+#else  /* IRIX */
+
+#include "prthread.h"
+#include <sys/types.h>
+#include <unistd.h>
+
+void NeverStops(void *unused)
+{
+    int i = 0;
+
+    printf("The child sproc has pid %d.\n", getpid());
+    printf("The child sproc won't stop on its own.\n");
+    fflush(stdout);
+
+    /* I never stop */
+    while (1) {
+	i++;
+    }
+}
+
+int main()
+{
+    int *p = 0;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+    printf("The parent sproc has pid %d.\n", getpid());
+    printf("The parent sproc will first create a child sproc.\n");
+    printf("Then the parent sproc will get a segmentation fault and die.\n");
+    printf("The child sproc should be killed after the parent sproc dies.\n");
+    printf("Use 'ps' to make sure this is so.\n");
+    fflush(stdout);
+
+    PR_CreateThread(PR_USER_THREAD, NeverStops, NULL,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    /* Force a segmentation fault */
+    *p = 0;
+    return 0;
+}
+
+#endif /* IRIX */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/stack.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/stack.c
new file mode 100644
index 0000000..49c29f6
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/stack.c
@@ -0,0 +1,312 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/*
+ *
+ * Test atomic stack operations
+ *		
+ *		Two stacks are created and threads add data items (each containing
+ *		one of the first n integers) to the first stack, remove data items
+ *		from the first stack and add them to the second stack. The primordial
+ *		thread compares the sum of the first n integers to the sum of the
+ *		integers in the data items in the second stack. The test succeeds if
+ *		they are equal.
+ */
+ 
+#include "nspr.h"
+#include "plgetopt.h"
+
+typedef struct _DataRecord {
+	PRInt32	data;
+	PRStackElem	link;
+} DataRecord;
+
+#define RECORD_LINK_PTR(lp) ((DataRecord*) ((char*) (lp) - offsetof(DataRecord,link)))
+
+#define MAX_THREAD_CNT		100
+#define DEFAULT_THREAD_CNT	4
+#define DEFAULT_DATA_CNT	100
+#define DEFAULT_LOOP_CNT	10000
+
+/*
+ * sum of the first n numbers using the formula n*(n+1)/2
+ */
+#define SUM_OF_NUMBERS(n) ((n & 1) ? (((n + 1)/2) * n) : ((n/2) * (n+1)))
+
+typedef struct stack_data {
+	PRStack		*list1;
+	PRStack		*list2;
+	PRInt32		initial_data_value;
+	PRInt32		data_cnt;
+	PRInt32		loops;
+} stack_data;
+
+static void stackop(void *arg);
+
+static int _debug_on;
+
+PRFileDesc  *output;
+PRFileDesc  *errhandle;
+
+int main(int argc, char **argv)
+{
+#if !(defined(SYMBIAN) && defined(__WINS__))
+    PRInt32 rv, cnt, sum;
+	DataRecord	*Item;
+	PRStack		*list1, *list2;
+	PRStackElem	*node;
+	PRStatus rc;
+
+	PRInt32 thread_cnt = DEFAULT_THREAD_CNT;
+	PRInt32 data_cnt = DEFAULT_DATA_CNT;
+	PRInt32 loops = DEFAULT_LOOP_CNT;
+	PRThread **threads;
+	stack_data *thread_args;
+
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:l:");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 't':  /* thread count */
+            thread_cnt = atoi(opt->value);
+            break;
+        case 'c':  /* data count */
+            data_cnt = atoi(opt->value);
+            break;
+        case 'l':  /* loop count */
+            loops = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	PR_SetConcurrency(4);
+
+    output = PR_GetSpecialFD(PR_StandardOutput);
+    errhandle = PR_GetSpecialFD(PR_StandardError);
+	list1 = PR_CreateStack("Stack_1");
+	if (list1 == NULL) {
+		PR_fprintf(errhandle, "PR_CreateStack failed - error %d\n",
+								PR_GetError());
+		return 1;
+	}
+
+	list2 = PR_CreateStack("Stack_2");
+	if (list2 == NULL) {
+		PR_fprintf(errhandle, "PR_CreateStack failed - error %d\n",
+								PR_GetError());
+		return 1;
+	}
+
+
+	threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
+	thread_args = (stack_data *) PR_CALLOC(sizeof(stack_data) * thread_cnt);
+
+	if (_debug_on)
+		PR_fprintf(output,"%s: thread_cnt = %d data_cnt = %d\n", argv[0],
+							thread_cnt, data_cnt);
+	for(cnt = 0; cnt < thread_cnt; cnt++) {
+		PRThreadScope scope;
+
+		thread_args[cnt].list1 = list1;
+		thread_args[cnt].list2 = list2;
+		thread_args[cnt].loops = loops;
+		thread_args[cnt].data_cnt = data_cnt;	
+		thread_args[cnt].initial_data_value = 1 + cnt * data_cnt;
+
+		if (cnt & 1)
+			scope = PR_GLOBAL_THREAD;
+		else
+			scope = PR_LOCAL_THREAD;
+
+
+		threads[cnt] = PR_CreateThread(PR_USER_THREAD,
+						  stackop, &thread_args[cnt],
+						  PR_PRIORITY_NORMAL,
+						  scope,
+						  PR_JOINABLE_THREAD,
+						  0);
+		if (threads[cnt] == NULL) {
+			PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
+								PR_GetError());
+			PR_ProcessExit(2);
+		}
+		if (_debug_on)
+			PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0],
+										threads[cnt]);
+	}
+
+	for(cnt = 0; cnt < thread_cnt; cnt++) {
+    	rc = PR_JoinThread(threads[cnt]);
+		PR_ASSERT(rc == PR_SUCCESS);
+	}
+
+	node = PR_StackPop(list1);
+	/*
+	 * list1 should be empty
+	 */
+	if (node != NULL) {
+		PR_fprintf(errhandle, "Error - Stack 1 not empty\n");
+		PR_ASSERT(node == NULL);
+		PR_ProcessExit(4);
+	}
+
+	cnt = data_cnt * thread_cnt;
+	sum = 0;
+	while (cnt-- > 0) {
+		node = PR_StackPop(list2);
+		/*
+		 * There should be at least 'cnt' number of records
+		 */
+		if (node == NULL) {
+			PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n");
+			PR_ProcessExit(3);
+		}
+		Item = RECORD_LINK_PTR(node);
+		sum += Item->data;
+	}
+	node = PR_StackPop(list2);
+	/*
+	 * there should be exactly 'cnt' number of records
+	 */
+	if (node != NULL) {
+		PR_fprintf(errhandle, "Error - Stack 2 not empty\n");
+		PR_ASSERT(node == NULL);
+		PR_ProcessExit(4);
+	}
+	PR_DELETE(threads);
+	PR_DELETE(thread_args);
+
+	PR_DestroyStack(list1);
+	PR_DestroyStack(list2);
+
+	if (sum == SUM_OF_NUMBERS(data_cnt * thread_cnt)) {
+		PR_fprintf(output, "%s successful\n", argv[0]);
+		PR_fprintf(output, "\t\tsum = 0x%x, expected = 0x%x\n", sum,
+							SUM_OF_NUMBERS(thread_cnt * data_cnt));
+		return 0;
+	} else {
+		PR_fprintf(output, "%s failed: sum = 0x%x, expected = 0x%x\n",
+							argv[0], sum,
+								SUM_OF_NUMBERS(data_cnt * thread_cnt));
+		return 2;
+	}
+#endif
+}
+
+static void stackop(void *thread_arg)
+{
+    PRInt32 val, cnt, index, loops;
+	DataRecord	*Items, *Item;
+	PRStack		*list1, *list2;
+	PRStackElem	*node;
+	stack_data *arg = (stack_data *) thread_arg;
+
+	val = arg->initial_data_value;
+	cnt = arg->data_cnt;
+	loops = arg->loops;
+	list1 = arg->list1;
+	list2 = arg->list2;
+
+	/*
+	 * allocate memory for the data records
+	 */
+	Items = (DataRecord *) PR_CALLOC(sizeof(DataRecord) * cnt);
+	PR_ASSERT(Items != NULL);
+	index = 0;
+
+	if (_debug_on)
+		PR_fprintf(output,
+		"Thread[0x%x] init_val = %d cnt = %d data1 = 0x%x datan = 0x%x\n",
+				PR_GetCurrentThread(), val, cnt, &Items[0], &Items[cnt-1]);
+
+
+	/*
+	 * add the data records to list1
+	 */
+	while (cnt-- > 0) {
+		Items[index].data = val++;
+		PR_StackPush(list1, &Items[index].link);
+		index++;
+	}
+
+	/*
+	 * pop data records from list1 and add them back to list1
+	 * generates contention for the stack accesses
+	 */
+	while (loops-- > 0) {
+		cnt = arg->data_cnt;
+		while (cnt-- > 0) {
+			node = PR_StackPop(list1);
+			if (node == NULL) {
+				PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n");
+				PR_ASSERT(node != NULL);
+				PR_ProcessExit(3);
+			}
+			PR_StackPush(list1, node);
+		}
+	}
+	/*
+	 * remove the data records from list1 and add them to list2
+	 */
+	cnt = arg->data_cnt;
+	while (cnt-- > 0) {
+		node = PR_StackPop(list1);
+		if (node == NULL) {
+			PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n");
+			PR_ASSERT(node != NULL);
+			PR_ProcessExit(3);
+		}
+		PR_StackPush(list2, node);
+	}
+	if (_debug_on)
+		PR_fprintf(output,
+		"Thread[0x%x] init_val = %d cnt = %d exiting\n",
+				PR_GetCurrentThread(), val, cnt);
+
+}
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/stat.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/stat.c
new file mode 100644
index 0000000..b860914
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/stat.c
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Program to test different ways to get file info; right now it 
+ * only works for solaris and OS/2.
+ *
+ */
+#include "nspr.h"
+#include "prpriv.h"
+#include "prinrval.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_OS2
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#define DEFAULT_COUNT 100000
+PRInt32 count;
+
+#ifndef XP_PC
+char *filename = "/etc/passwd";
+#else
+char *filename = "..\\stat.c";
+#endif
+
+static void statPRStat(void)
+{
+    PRFileInfo finfo;
+    PRInt32 index = count;
+ 
+    for (;index--;) {
+         PR_GetFileInfo(filename, &finfo);
+    }
+}
+
+static void statStat(void)
+{
+    struct stat finfo;
+    PRInt32 index = count;
+ 
+    for (;index--;) {
+        stat(filename, &finfo);
+    }
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+    PRInt32 tot;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+    tot = PR_IntervalToMilliseconds(stop-start);
+
+    printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot);
+}
+
+int main(int argc, char **argv)
+{
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 1) {
+	count = atoi(argv[1]);
+    } else {
+	count = DEFAULT_COUNT;
+    }
+
+    Measure(statPRStat, "time to call PR_GetFileInfo()");
+    Measure(statStat, "time to call stat()");
+
+    PR_Cleanup();
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/stdio.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/stdio.c
new file mode 100644
index 0000000..d0d84e4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/stdio.c
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File:        stdio.c
+ * Description: testing the "special" fds
+ * Modification History:
+ * 20-May-1997 AGarcia - Replace Test succeeded status with PASS. This is used by the
+ *						regress tool parsing code.
+ ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+ */
+
+
+#include "prlog.h"
+#include "prinit.h"
+#include "prio.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static PRIntn PR_CALLBACK stdio(PRIntn argc, char **argv)
+{
+    PRInt32 rv;
+
+    PRFileDesc *out = PR_GetSpecialFD(PR_StandardOutput);
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+
+    rv = PR_Write(
+        out, "This to standard out\n",
+        strlen("This to standard out\n"));
+    PR_ASSERT((PRInt32)strlen("This to standard out\n") == rv);
+    rv = PR_Write(
+        err, "This to standard err\n",
+        strlen("This to standard err\n"));
+    PR_ASSERT((PRInt32)strlen("This to standard err\n") == rv);
+
+    return 0;
+
+}  /* stdio */
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+    return PR_Initialize(stdio, argc, argv, 0);
+}  /* main */
+
+
+/* stdio.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/str2addr.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/str2addr.c
new file mode 100644
index 0000000..b1d4cf4
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/str2addr.c
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: str2addr.c
+ * Description: a test for PR_StringToNetAddr
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Address string to convert */
+#define DEFAULT_IPV4_ADDR_STR "207.200.73.41"
+
+/* Expected conversion result, in network byte order */
+static unsigned char default_ipv4_addr[] = {207, 200, 73, 41};
+
+int main(int argc, char **argv)
+{
+    PRNetAddr addr;
+    const char *addrStr;
+    unsigned char *bytes;
+    int idx;
+
+    addrStr = DEFAULT_IPV4_ADDR_STR;
+    if (PR_StringToNetAddr(addrStr, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_StringToNetAddr failed\n");
+        exit(1);
+    }
+    if (addr.inet.family != PR_AF_INET) {
+        fprintf(stderr, "addr.inet.family should be %d but is %d\n",
+                PR_AF_INET, addr.inet.family);
+        exit(1);
+    }
+    bytes = (unsigned char *) &addr.inet.ip;
+    for (idx = 0; idx < 4; idx++) {
+        if (bytes[idx] != default_ipv4_addr[idx]) {
+            fprintf(stderr, "byte %d of IPv4 addr should be %d but is %d\n",
+                    idx, default_ipv4_addr[idx], bytes[idx]);
+            exit(1);
+        }
+    }
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/strod.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/strod.c
new file mode 100644
index 0000000..b2409c1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/strod.c
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prio.h"
+#include "prprf.h"
+#include "prdtoa.h"
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+static void Help(void)
+{
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PR_fprintf(err, "Usage: /.strod [-n n] [-l n] [-h]\n");
+    PR_fprintf(err, "\t-n n Number to translate    (default: 1234567890123456789)\n");
+    PR_fprintf(err, "\t-l n Times to loop the test (default: 1)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv)
+{
+    PLOptStatus os;
+    PRIntn loops = 1;
+    PRFloat64 answer;
+    const char *number = "1234567890123456789";
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hc:l:");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'n':  /* number to translate */
+            number = opt->value;
+            break;
+        case 'l':  /* number of times to run the tests */
+            loops = atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_fprintf(err, "Settings\n");
+    PR_fprintf(err, "\tNumber to translate %s\n", number);
+    PR_fprintf(err, "\tLoops to run test: %d\n", loops);
+
+    while (loops--)
+    {
+        answer = PR_strtod(number, NULL);
+        PR_fprintf(err, "Translation = %20.0f\n", answer);
+    }
+    return 0;
+}
+
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/suspend.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/suspend.c
new file mode 100644
index 0000000..58a563b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/suspend.c
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef XP_BEOS
+#include <stdio.h>
+int main()
+{
+    printf( "This test is not ported to the BeOS\n" );
+    return 0;
+}
+#else
+
+#include "nspr.h"
+#include "prpriv.h"
+#include "prinrval.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRMonitor *mon;
+PRInt32 count;
+PRInt32 alive;
+
+#define SLEEP_TIME    4    /* secs */
+
+void PR_CALLBACK
+Level_2_Thread(void *arg)
+{
+    PR_Sleep(PR_MillisecondsToInterval(4 * 1000));
+    printf("Level_2_Thread[0x%lx] exiting\n",PR_GetCurrentThread());
+    return;
+}
+
+void PR_CALLBACK
+Level_1_Thread(void *arg)
+{
+    PRUint32 tmp = (PRUint32)arg;
+    PRThreadScope scope = (PRThreadScope) tmp;
+    PRThread *thr;
+
+    thr = PR_CreateThreadGCAble(PR_USER_THREAD,
+        Level_2_Thread,
+        NULL,
+        PR_PRIORITY_HIGH,
+        scope,
+        PR_JOINABLE_THREAD,
+        0);
+
+    if (!thr) {
+        printf("Could not create thread!\n");
+    } else {
+        printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n",
+            PR_GetCurrentThread(),
+            (scope == PR_GLOBAL_THREAD) ?
+            "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
+            thr);
+        PR_JoinThread(thr);
+    }
+    PR_EnterMonitor(mon);
+    alive--;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+    printf("Thread[0x%lx] exiting\n",PR_GetCurrentThread());
+}
+
+static PRStatus PR_CALLBACK print_thread(PRThread *thread, int i, void *arg)
+{
+    PRInt32 words;
+    PRWord *registers;
+
+    printf(
+        "\nprint_thread[0x%lx]: %-20s - i = %ld\n",thread, 
+        (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ?
+        "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", i);
+    registers = PR_GetGCRegisters(thread, 0, (int *)&words);
+    printf("Regsters R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
+        registers[0],registers[1],registers[2],registers[3]);
+    printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread));
+    return PR_SUCCESS;
+}
+
+static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *thr;
+    PRThread *me = PR_GetCurrentThread();
+    int n;
+    PRInt32 words;
+    PRWord *registers;
+
+    alive = 0;
+    mon = PR_NewMonitor();
+
+    alive = count;
+    for (n=0; n<count; n++) {
+        thr = PR_CreateThreadGCAble(PR_USER_THREAD,
+            Level_1_Thread, 
+            (void *)scope2, 
+            PR_PRIORITY_NORMAL,
+            scope1,
+            PR_UNJOINABLE_THREAD,
+            0);
+        if (!thr) {
+            printf("Could not create thread!\n");
+            alive--;
+        }
+        printf("Level_0_Thread[0x%lx] created %15s thread 0x%lx\n",
+            PR_GetCurrentThread(),
+            (scope1 == PR_GLOBAL_THREAD) ?
+            "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
+            thr);
+
+        PR_Sleep(0);
+    }
+    PR_SuspendAll();
+    PR_EnumerateThreads(print_thread, NULL);
+    registers = PR_GetGCRegisters(me, 1, (int *)&words);
+    printf("My Registers: R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
+        registers[0],registers[1],registers[2],registers[3]);
+    printf("My Stack Pointer = 0x%lx\n", PR_GetSP(me));
+    PR_ResumeAll();
+
+    /* Wait for all threads to exit */
+    PR_EnterMonitor(mon);
+    while (alive) {
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    PR_ExitMonitor(mon);
+    PR_DestroyMonitor(mon);
+}
+
+static void CreateThreadsUU(void)
+{
+    Level_0_Thread(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CreateThreadsUK(void)
+{
+    Level_0_Thread(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void CreateThreadsKU(void)
+{
+    Level_0_Thread(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CreateThreadsKK(void)
+{
+    Level_0_Thread(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+
+int main(int argc, char **argv)
+{
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 1) {
+        count = atoi(argv[1]);
+    } else {
+        count = 5;
+    }
+
+    printf("\n\n%20s%30s\n\n"," ","Suspend_Resume Test");
+    CreateThreadsUU();
+    CreateThreadsUK();
+    CreateThreadsKU();
+    CreateThreadsKK();
+    PR_SetConcurrency(2);
+
+    printf("\n%20s%30s\n\n"," ","Added 2nd CPU\n");
+
+    CreateThreadsUK();
+    CreateThreadsKK();
+    CreateThreadsUU();
+    CreateThreadsKU();
+    PR_Cleanup();
+}
+
+#endif /* XP_BEOS */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/switch.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/switch.c
new file mode 100644
index 0000000..5c3211e
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/switch.c
@@ -0,0 +1,269 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:            switch.c
+** Description:     trying to time context switches
+*/
+
+#include "prinit.h"
+#include "prcvar.h"
+#include "prmem.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prthread.h"
+#include "prprf.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include "private/pprio.h"
+
+#include <stdlib.h>
+
+#define INNER_LOOPS 100
+#define DEFAULT_LOOPS 100
+#define DEFAULT_THREADS 10
+
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE;
+
+typedef struct Shared
+{
+    PRLock *ml;
+    PRCondVar *cv;
+    PRBool twiddle;
+    PRThread *thread;
+    struct Shared *next;
+} Shared;
+
+static void Help(void)
+{
+    debug_out = PR_STDOUT;
+
+    PR_fprintf(
+		debug_out, "Usage: >./switch [-c n] [-t n] [-d] [-v] [-G] [-C n]\n");
+    PR_fprintf(
+		debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
+    PR_fprintf(
+		debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
+    PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n");
+    PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
+}  /* Help */
+
+static void PR_CALLBACK Notified(void *arg)
+{
+    Shared *shared = (Shared*)arg;
+    PRStatus status = PR_SUCCESS;
+    while (PR_SUCCESS == status)
+    {
+        PR_Lock(shared->ml);
+        while (shared->twiddle && (PR_SUCCESS == status))
+            status = PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT);
+		if (verbosity) PR_fprintf(debug_out, "+");
+        shared->twiddle = PR_TRUE;
+        shared->next->twiddle = PR_FALSE;
+        PR_NotifyCondVar(shared->next->cv);
+        PR_Unlock(shared->ml);
+    }
+}  /* Notified */
+
+static Shared home;
+PRIntn PR_CALLBACK Switch(PRIntn argc, char **argv)
+{
+	PLOptStatus os;
+    PRStatus status;
+    PRBool help = PR_FALSE;
+    PRUintn concurrency = 1;
+    Shared *shared, *link;
+    PRIntervalTime timein, timeout;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRUintn thread_count, inner_count, loop_count, average;
+    PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'v':  /* verbose mode */
+			verbosity = PR_TRUE;
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+        case 'c':  /* loop counter */
+			loop_limit = atoi(opt->value);
+            break;
+        case 't':  /* thread limit */
+			thread_limit = atoi(opt->value);
+            break;
+        case 'C':  /* Concurrency limit */
+			concurrency = atoi(opt->value);
+            break;
+        case 'G':  /* global threads only */
+			thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'h':  /* help message */
+			Help();
+			help = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (help) return -1;
+
+	if (PR_TRUE == debug_mode)
+	{
+		debug_out = PR_STDOUT;
+		PR_fprintf(debug_out, "Test parameters\n");
+		PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit);
+		PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit);
+		PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
+		PR_fprintf(
+			debug_out, "\tThread type: %s\n",
+			(PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
+	}
+
+    PR_SetConcurrency(concurrency);
+
+    link = &home;
+    home.ml = PR_NewLock();
+    home.cv = PR_NewCondVar(home.ml);
+    home.twiddle = PR_FALSE;
+    home.next = NULL;
+
+    timeout = 0;
+
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        shared = PR_NEWZAP(Shared);
+
+        shared->ml = home.ml;
+        shared->cv = PR_NewCondVar(home.ml);
+        shared->twiddle = PR_TRUE;
+        shared->next = link;
+        link = shared;
+
+        shared->thread = PR_CreateThread(
+            PR_USER_THREAD, Notified, shared,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 0);
+        PR_ASSERT(shared->thread != NULL);
+        if (NULL == shared->thread)
+            failed = PR_TRUE;
+	}
+
+    for (loop_count = 1; loop_count <= loop_limit; ++loop_count)
+    {
+		timein = PR_IntervalNow();
+		for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count)
+		{
+			PR_Lock(home.ml);
+			home.twiddle = PR_TRUE;
+			shared->twiddle = PR_FALSE;
+			PR_NotifyCondVar(shared->cv);
+			while (home.twiddle)
+            {
+				status = PR_WaitCondVar(home.cv, PR_INTERVAL_NO_TIMEOUT);
+				if (PR_FAILURE == status)
+				    failed = PR_TRUE;
+            }
+			PR_Unlock(home.ml);
+		}
+		timeout += (PR_IntervalNow() - timein);
+	}
+
+	if (debug_mode)
+	{
+		average = PR_IntervalToMicroseconds(timeout)
+			/ (INNER_LOOPS * loop_limit * thread_count);
+		PR_fprintf(
+			debug_out, "Average switch times %d usecs for %d threads\n",
+            average, thread_limit);
+	}
+
+    link = shared;
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        if (&home == link) break;
+        status = PR_Interrupt(link->thread);
+		if (PR_SUCCESS != status)
+        {
+            failed = PR_TRUE;
+            if (debug_mode)
+			    PL_FPrintError(debug_out, "Failed to interrupt");
+        }
+		link = link->next; 
+    }
+
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        link = shared->next;
+        status = PR_JoinThread(shared->thread);
+		if (PR_SUCCESS != status)
+		{
+            failed = PR_TRUE;
+            if (debug_mode)
+			    PL_FPrintError(debug_out, "Failed to join");
+        }
+        PR_DestroyCondVar(shared->cv);
+        PR_DELETE(shared);
+        if (&home == link) break;
+        shared = link;
+    }
+    PR_DestroyCondVar(home.cv);
+    PR_DestroyLock(home.ml);
+
+    PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n"));
+    return ((failed) ? 1 : 0);
+}  /* Switch */
+
+int main(int argc, char **argv)
+{
+    PRIntn result;
+    PR_STDIO_INIT();
+    result = PR_Initialize(Switch, argc, argv, 0);
+    return result;
+}  /* main */
+
+/* switch.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/system.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/system.c
new file mode 100644
index 0000000..94a6907
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/system.c
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prsystem.h"
+
+#include "plerror.h"
+
+static char *tag[] =
+{
+    "PR_SI_HOSTNAME",
+    "PR_SI_SYSNAME",
+    "PR_SI_RELEASE",
+    "PR_SI_ARCHITECTURE"
+};
+
+static PRSysInfo Incr(PRSysInfo *cmd)
+{
+    PRIntn tmp = (PRIntn)*cmd + 1;
+    *cmd = (PRSysInfo)tmp;
+    return (PRSysInfo)tmp;
+}  /* Incr */
+
+int main(int argc, char **argv)
+{
+    PRStatus rv;
+    PRSysInfo cmd;
+    PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput);
+
+    char *info = (char*)PR_Calloc(SYS_INFO_BUFFER_LENGTH, 1);
+    for (cmd = PR_SI_HOSTNAME; cmd <= PR_SI_ARCHITECTURE; Incr(&cmd))
+    {
+        rv = PR_GetSystemInfo(cmd, info, SYS_INFO_BUFFER_LENGTH);
+        if (PR_SUCCESS == rv) PR_fprintf(output, "%s: %s\n", tag[cmd], info);
+        else PL_FPrintError(output, tag[cmd]);
+    }
+    PR_DELETE(info);
+
+    PR_fprintf(output, "Host page size is %d\n", PR_GetPageSize());
+    PR_fprintf(output, "Page shift is %d\n", PR_GetPageShift());
+    PR_fprintf(output, "Memory map alignment is %ld\n", PR_GetMemMapAlignment());
+    PR_fprintf(output, "Number of processors is: %d\n", PR_GetNumberOfProcessors());
+    PR_fprintf(output, "Physical memory size is: %llu\n", PR_GetPhysicalMemorySize());
+
+    return 0;
+}  /* main */
+
+/* system.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/testbit.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/testbit.c
new file mode 100644
index 0000000..bfb16e2
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/testbit.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        lazyinit.c
+** Description: Test the functions and macros declared in prbit.h
+**
+*/
+
+#include "nspr.h"
+
+#define ErrorReport(x) { printf((x)); failed = 1; }
+
+prbitmap_t myMap[512/32] = { 0 };
+
+PRInt32 rc;
+PRInt32 i;
+PRIntn  failed = 0;
+
+int main(int argc, char **argv)
+{
+    /*
+    ** Test bitmap things.
+    */
+    if ( PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 0.0: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 0.1: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 0.2: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 0.3: Failed\n");
+
+
+    PR_SET_BIT( myMap, 0 );
+    if ( !PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 1.0: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 0 );
+    if ( PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 1.0.1: Failed\n");
+
+    PR_SET_BIT( myMap, 31 );
+    if ( !PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 1.1: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 31 );
+    if ( PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 1.1.1: Failed\n");
+
+    PR_SET_BIT( myMap, 128 );
+    if ( !PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 1.2: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 128 );
+    if ( PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 1.2.1: Failed\n");
+
+    PR_SET_BIT( myMap, 129 );
+    if ( !PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 1.3: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 129 );
+    if ( PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 1.3.1: Failed\n");
+
+
+    /*
+    ** Test Ceiling and Floor functions and macros
+    */
+    if ((rc = PR_CeilingLog2(32)) != 5 )
+        ErrorReport("Test 10.0: Failed\n");
+
+    if ((rc = PR_FloorLog2(32)) != 5 )
+        ErrorReport("Test 10.1: Failed\n");
+
+
+    /*
+    ** Evaluate results and exit
+    */
+    if (failed)
+      {
+        printf("FAILED\n");
+        return(1);
+      }
+    else
+      {
+        printf("PASSED\n");
+        return(0);
+      }
+}  /* end main() */
+/* end testbit.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/testfile.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/testfile.c
new file mode 100644
index 0000000..f2fe472
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/testfile.c
@@ -0,0 +1,993 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "prpriv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef WIN32
+#include <windows.h>
+#include <process.h>
+#endif
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#endif
+#ifdef SYMBIAN
+#include <getopt.h>
+#endif
+
+#if defined(XP_OS2)
+#define INCL_DOSFILEMGR
+#include <os2.h>
+#include <getopt.h>
+#include <errno.h>
+#endif /* XP_OS2 */
+
+static int _debug_on = 0;
+
+#ifdef WINCE
+#define setbuf(x,y)
+#endif
+
+#ifdef XP_WIN
+#define mode_t int
+#endif
+
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+PRLock *lock;
+PRMonitor *mon;
+PRInt32 count;
+int thread_count;
+
+#ifdef WIN16
+#define	BUF_DATA_SIZE	256 * 120
+#else
+#define	BUF_DATA_SIZE	256 * 1024
+#endif
+
+#define NUM_RDWR_THREADS	10
+#define NUM_DIRTEST_THREADS	4
+#define CHUNK_SIZE 512
+
+typedef struct buffer {
+	char	data[BUF_DATA_SIZE];
+} buffer;
+
+typedef struct File_Rdwr_Param {
+	char	*pathname;
+	char	*buf;
+	int	offset;
+	int	len;
+} File_Rdwr_Param;
+
+#ifdef XP_PC
+#ifdef XP_OS2
+char *TEST_DIR = "prdir";
+#else
+char *TEST_DIR = "C:\\temp\\prdir";
+#endif
+char *FILE_NAME = "pr_testfile";
+char *HIDDEN_FILE_NAME = "hidden_pr_testfile";
+#else
+#ifdef SYMBIAN
+char *TEST_DIR = "c:\\data\\testfile_dir";
+#else
+char *TEST_DIR = "/tmp/testfile_dir";
+#endif
+char *FILE_NAME = "pr_testfile";
+char *HIDDEN_FILE_NAME = ".hidden_pr_testfile";
+#endif
+buffer *in_buf, *out_buf;
+char pathname[256], renamename[256];
+#ifdef WINCE
+WCHAR wPathname[256];
+#endif
+#define TMPDIR_LEN	64
+char testdir[TMPDIR_LEN];
+static PRInt32 PR_CALLBACK DirTest(void *argunused);
+PRInt32 dirtest_failed = 0;
+
+PRThread* create_new_thread(PRThreadType type,
+							void (*start)(void *arg),
+							void *arg,
+							PRThreadPriority priority,
+							PRThreadScope scope,
+							PRThreadState state,
+							PRUint32 stackSize, PRInt32 index)
+{
+PRInt32 native_thread = 0;
+
+	PR_ASSERT(state == PR_UNJOINABLE_THREAD);
+
+#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) || defined(XP_OS2)
+
+	switch(index %  4) {
+		case 0:
+			scope = (PR_LOCAL_THREAD);
+			break;
+		case 1:
+			scope = (PR_GLOBAL_THREAD);
+			break;
+		case 2:
+			scope = (PR_GLOBAL_BOUND_THREAD);
+			break;
+		case 3:
+			native_thread = 1;
+			break;
+		default:
+			PR_ASSERT(!"Invalid scope");
+			break;
+	}
+	if (native_thread) {
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+		pthread_t tid;
+		if (!pthread_create(&tid, NULL, start, arg))
+			return((PRThread *) tid);
+		else
+			return (NULL);
+#elif defined(XP_OS2)
+        TID tid;
+
+        tid = (TID)_beginthread((void(* _Optlink)(void*))start,
+                                NULL, 32768, arg);
+        if (tid == -1) {
+          printf("_beginthread failed. errno %d\n", errno);
+          return (NULL);
+        }
+        else
+          return((PRThread *) tid);
+#else
+		HANDLE thandle;
+		unsigned tid;
+		
+		thandle = (HANDLE) _beginthreadex(
+						NULL,
+						stackSize,
+						(unsigned (__stdcall *)(void *))start,
+						arg,
+						0,
+						&tid);		
+		return((PRThread *) thandle);
+#endif
+	} else {
+		return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
+	}
+#else
+	return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
+#endif
+}
+
+static void PR_CALLBACK File_Write(void *arg)
+{
+PRFileDesc *fd_file;
+File_Rdwr_Param *fp = (File_Rdwr_Param *) arg;
+char *name, *buf;
+int offset, len;
+
+	setbuf(stdout, NULL);
+	name = fp->pathname;
+	buf = fp->buf;
+	offset = fp->offset;
+	len = fp->len;
+	
+	fd_file = PR_Open(name, PR_RDWR | PR_CREATE_FILE, 0777);
+	if (fd_file == NULL) {
+		printf("testfile failed to create/open file %s\n",name);
+		return;
+	}
+	if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) {
+		printf("testfile failed to seek in file %s\n",name);
+		return;
+	}	
+	if ((PR_Write(fd_file, buf, len)) < 0) {
+		printf("testfile failed to write to file %s\n",name);
+		return;
+	}	
+	DPRINTF(("Write out_buf[0] = 0x%x\n",(*((int *) buf))));
+	PR_Close(fd_file);
+	PR_DELETE(fp);
+
+	PR_EnterMonitor(mon);
+	--thread_count;
+	PR_Notify(mon);
+	PR_ExitMonitor(mon);
+}
+
+static void PR_CALLBACK File_Read(void *arg)
+{
+PRFileDesc *fd_file;
+File_Rdwr_Param *fp = (File_Rdwr_Param *) arg;
+char *name, *buf;
+int offset, len;
+
+	setbuf(stdout, NULL);
+	name = fp->pathname;
+	buf = fp->buf;
+	offset = fp->offset;
+	len = fp->len;
+	
+	fd_file = PR_Open(name, PR_RDONLY, 0);
+	if (fd_file == NULL) {
+		printf("testfile failed to open file %s\n",name);
+		return;
+	}
+	if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) {
+		printf("testfile failed to seek in file %s\n",name);
+		return;
+	}	
+	if ((PR_Read(fd_file, buf, len)) < 0) {
+		printf("testfile failed to read to file %s\n",name);
+		return;
+	}	
+	DPRINTF(("Read in_buf[0] = 0x%x\n",(*((int *) buf))));
+	PR_Close(fd_file);
+	PR_DELETE(fp);
+
+	PR_EnterMonitor(mon);
+	--thread_count;
+	PR_Notify(mon);
+	PR_ExitMonitor(mon);
+}
+
+
+static PRInt32 Misc_File_Tests(char *pathname)
+{
+PRFileDesc *fd_file;
+int len, rv = 0;
+PRFileInfo file_info, file_info1;
+char tmpname[1024];
+
+	setbuf(stdout, NULL);
+	/*
+	 * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access
+	 */
+
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
+
+	if (fd_file == NULL) {
+		printf("testfile failed to create/open file %s\n",pathname);
+		return -1;
+	}
+	if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
+		printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) {
+		printf("testfile PR_Access failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) {
+		printf("testfile PR_Access failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) {
+		printf("testfile PR_Access failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+
+
+	if (PR_GetFileInfo(pathname, &file_info) < 0) {
+		printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (file_info.type != PR_FILE_FILE) {
+	printf(
+	"testfile: Error - PR_GetFileInfo returned incorrect type for file %s\n",
+		pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (file_info.size != 0) {
+		printf(
+		"testfile PR_GetFileInfo returned incorrect size (%d should be 0) for file %s\n",
+		file_info.size, pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	file_info1 = file_info;
+
+	len = PR_Available(fd_file);
+	if (len < 0) {
+		printf("testfile PR_Available failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	} else if (len != 0) {
+		printf(
+		"testfile PR_Available failed: expected/returned = %d/%d bytes\n",
+			0, len);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
+		printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
+		goto cleanup;
+	}
+	if (LL_NE(file_info.creationTime , file_info1.creationTime)) {
+		printf(
+		"testfile PR_GetFileInfo returned incorrect status-change time: %s\n",
+		pathname);
+		printf("ft = %lld, ft1 = %lld\n",file_info.creationTime,
+									file_info1.creationTime);
+		rv = -1;
+		goto cleanup;
+	}
+	len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE);
+	if (len < 0) {
+		printf("testfile failed to write to file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
+		printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
+		goto cleanup;
+	}
+	if (file_info.size != CHUNK_SIZE) {
+		printf(
+		"testfile PR_GetFileInfo returned incorrect size (%d should be %d) for file %s\n",
+		file_info.size, CHUNK_SIZE, pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (LL_CMP(file_info.modifyTime, < , file_info1.modifyTime)) {
+		printf(
+		"testfile PR_GetFileInfo returned incorrect modify time: %s\n",
+		pathname);
+		printf("ft = %lld, ft1 = %lld\n",file_info.modifyTime,
+									file_info1.modifyTime);
+		rv = -1;
+		goto cleanup;
+	}
+
+	len = PR_Available(fd_file);
+	if (len < 0) {
+		printf("testfile PR_Available failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	} else if (len != 0) {
+		printf(
+		"testfile PR_Available failed: expected/returned = %d/%d bytes\n",
+			0, len);
+		rv = -1;
+		goto cleanup;
+	}
+	
+	PR_Seek(fd_file, 0, PR_SEEK_SET);
+	len = PR_Available(fd_file);
+	if (len < 0) {
+		printf("testfile PR_Available failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	} else if (len != CHUNK_SIZE) {
+		printf(
+		"testfile PR_Available failed: expected/returned = %d/%d bytes\n",
+			CHUNK_SIZE, len);
+		rv = -1;
+		goto cleanup;
+	}
+    PR_Close(fd_file);
+
+	strcpy(tmpname,pathname);
+	strcat(tmpname,".RENAMED");
+	if (PR_FAILURE == PR_Rename(pathname, tmpname)) {
+		printf("testfile failed to rename file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
+	len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE);
+    PR_Close(fd_file);
+	if (PR_SUCCESS == PR_Rename(pathname, tmpname)) {
+		printf("testfile renamed to existing file %s\n",pathname);
+	}
+
+	if ((PR_Delete(tmpname)) < 0) {
+		printf("testfile failed to unlink file %s\n",tmpname);
+		rv = -1;
+	}
+
+cleanup:
+	if ((PR_Delete(pathname)) < 0) {
+		printf("testfile failed to unlink file %s\n",pathname);
+		rv = -1;
+	}
+	return rv;
+}
+
+
+static PRInt32 PR_CALLBACK FileTest(void)
+{
+PRDir *fd_dir;
+int i, offset, len, rv = 0;
+PRThread *t;
+PRThreadScope scope = PR_GLOBAL_THREAD;
+File_Rdwr_Param *fparamp;
+
+	/*
+	 * Create Test dir
+	 */
+	if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
+		printf("testfile failed to create dir %s\n",TEST_DIR);
+		return -1;
+	}
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf("testfile failed to open dir %s\n",TEST_DIR);
+		rv =  -1;
+		goto cleanup;	
+	}
+
+    PR_CloseDir(fd_dir);
+
+	strcat(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, FILE_NAME);
+
+	in_buf = PR_NEW(buffer);
+	if (in_buf == NULL) {
+		printf(
+		"testfile failed to alloc buffer struct\n");
+		rv =  -1;
+		goto cleanup;	
+	}
+	out_buf = PR_NEW(buffer);
+	if (out_buf == NULL) {
+		printf(
+		"testfile failed to alloc buffer struct\n");
+		rv =  -1;
+		goto cleanup;	
+	}
+
+	/*
+	 * Start a bunch of writer threads
+	 */
+	offset = 0;
+	len = CHUNK_SIZE;
+	PR_EnterMonitor(mon);
+	for (i = 0; i < NUM_RDWR_THREADS; i++) {
+		fparamp = PR_NEW(File_Rdwr_Param);
+		if (fparamp == NULL) {
+			printf(
+			"testfile failed to alloc File_Rdwr_Param struct\n");
+			rv =  -1;
+			goto cleanup;	
+		}
+		fparamp->pathname = pathname;
+		fparamp->buf = out_buf->data + offset;
+		fparamp->offset = offset;
+		fparamp->len = len;
+		memset(fparamp->buf, i, len);
+
+		t = create_new_thread(PR_USER_THREAD,
+			      File_Write, (void *)fparamp, 
+			      PR_PRIORITY_NORMAL,
+			      scope,
+			      PR_UNJOINABLE_THREAD,
+			      0, i);
+		offset += len;
+	}
+	thread_count = i;
+	/* Wait for writer threads to exit */
+	while (thread_count) {
+		PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+	}
+	PR_ExitMonitor(mon);
+
+
+	/*
+	 * Start a bunch of reader threads
+	 */
+	offset = 0;
+	len = CHUNK_SIZE;
+	PR_EnterMonitor(mon);
+	for (i = 0; i < NUM_RDWR_THREADS; i++) {
+		fparamp = PR_NEW(File_Rdwr_Param);
+		if (fparamp == NULL) {
+			printf(
+			"testfile failed to alloc File_Rdwr_Param struct\n");
+			rv =  -1;
+			goto cleanup;	
+		}
+		fparamp->pathname = pathname;
+		fparamp->buf = in_buf->data + offset;
+		fparamp->offset = offset;
+		fparamp->len = len;
+
+		t = create_new_thread(PR_USER_THREAD,
+			      File_Read, (void *)fparamp, 
+			      PR_PRIORITY_NORMAL,
+			      scope,
+			      PR_UNJOINABLE_THREAD,
+			      0, i);
+		offset += len;
+		if ((offset + len) > BUF_DATA_SIZE)
+			break;
+	}
+	thread_count = i;
+
+	/* Wait for reader threads to exit */
+	while (thread_count) {
+		PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+	}
+	PR_ExitMonitor(mon);
+
+	if (memcmp(in_buf->data, out_buf->data, offset) != 0) {
+		printf("File Test failed: file data corrupted\n");
+		rv =  -1;
+		goto cleanup;	
+	}
+
+	if ((PR_Delete(pathname)) < 0) {
+		printf("testfile failed to unlink file %s\n",pathname);
+		rv =  -1;
+		goto cleanup;	
+	}
+
+	/*
+	 * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access
+	 */
+	if (Misc_File_Tests(pathname) < 0) {
+		rv = -1;
+	}
+
+cleanup:
+	if ((PR_RmDir(TEST_DIR)) < 0) {
+		printf("testfile failed to rmdir %s\n", TEST_DIR);
+		rv = -1;
+	}
+	return rv;
+}
+
+struct dirtest_arg {
+	PRMonitor	*mon;
+	PRInt32		done;
+};
+
+static PRInt32 RunDirTest(void)
+{
+int i;
+PRThread *t;
+PRMonitor *mon;
+struct dirtest_arg thrarg;
+
+	mon = PR_NewMonitor();
+	if (!mon) {
+		printf("RunDirTest: Error - failed to create monitor\n");
+		dirtest_failed = 1;
+		return -1;
+	}
+	thrarg.mon = mon;
+
+	for (i = 0; i < NUM_DIRTEST_THREADS; i++) {
+
+		thrarg.done= 0;
+		t = create_new_thread(PR_USER_THREAD,
+			      DirTest, &thrarg, 
+			      PR_PRIORITY_NORMAL,
+			      PR_LOCAL_THREAD,
+			      PR_UNJOINABLE_THREAD,
+			      0, i);
+		if (!t) {
+			printf("RunDirTest: Error - failed to create thread\n");
+			dirtest_failed = 1;
+			return -1;
+		}
+		PR_EnterMonitor(mon);
+		while (!thrarg.done)
+			PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+		PR_ExitMonitor(mon);
+
+	}
+	PR_DestroyMonitor(mon);
+	return 0;
+}
+
+static PRInt32 PR_CALLBACK DirTest(void *arg)
+{
+struct dirtest_arg *tinfo = (struct dirtest_arg *) arg;
+PRFileDesc *fd_file;
+PRDir *fd_dir;
+int i;
+int path_len;
+PRDirEntry *dirEntry;
+PRFileInfo info;
+PRInt32 num_files = 0;
+#if defined(XP_PC) && defined(WIN32)
+HANDLE hfile;
+#endif
+
+#define  FILES_IN_DIR 20
+
+	/*
+	 * Create Test dir
+	 */
+	DPRINTF(("Creating test dir %s\n",TEST_DIR));
+	if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
+		printf(
+			"testfile failed to create dir %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf(
+			"testfile failed to open dirctory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+	strcpy(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, FILE_NAME);
+	path_len = strlen(pathname);
+	
+	for (i = 0; i < FILES_IN_DIR; i++) {
+
+		sprintf(pathname + path_len,"%d%s",i,"");
+
+		DPRINTF(("Creating test file %s\n",pathname));
+
+		fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
+
+		if (fd_file == NULL) {
+			printf(
+					"testfile failed to create/open file %s [%d, %d]\n",
+					pathname, PR_GetError(), PR_GetOSError());
+			return -1;
+		}
+        PR_Close(fd_file);
+	}
+#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
+	/*
+	 * Create a hidden file - a platform-dependent operation
+	 */
+	strcpy(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, HIDDEN_FILE_NAME);
+#if defined(XP_UNIX) || defined(XP_BEOS)
+	DPRINTF(("Creating hidden test file %s\n",pathname));
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
+
+	if (fd_file == NULL) {
+		printf(
+				"testfile failed to create/open hidden file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+    PR_Close(fd_file);
+
+#elif defined(WINCE)
+	DPRINTF(("Creating hidden test file %s\n",pathname));
+    MultiByteToWideChar(CP_ACP, 0, pathname, -1, wPathname, 256); 
+	hfile = CreateFile(wPathname, GENERIC_READ,
+						FILE_SHARE_READ|FILE_SHARE_WRITE,
+						NULL,
+						CREATE_NEW,
+						FILE_ATTRIBUTE_HIDDEN,
+						NULL);
+	if (hfile == INVALID_HANDLE_VALUE) {
+		printf("testfile failed to create/open hidden file %s [0, %d]\n",
+				pathname, GetLastError());
+		return -1;
+	}
+	CloseHandle(hfile);
+						
+#elif defined(XP_PC) && defined(WIN32)
+	DPRINTF(("Creating hidden test file %s\n",pathname));
+	hfile = CreateFile(pathname, GENERIC_READ,
+						FILE_SHARE_READ|FILE_SHARE_WRITE,
+						NULL,
+						CREATE_NEW,
+						FILE_ATTRIBUTE_HIDDEN,
+						NULL);
+	if (hfile == INVALID_HANDLE_VALUE) {
+		printf("testfile failed to create/open hidden file %s [0, %d]\n",
+				pathname, GetLastError());
+		return -1;
+	}
+	CloseHandle(hfile);
+						
+#elif defined(OS2)
+	DPRINTF(("Creating hidden test file %s\n",pathname));
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, (int)FILE_HIDDEN);
+
+	if (fd_file == NULL) {
+		printf("testfile failed to create/open hidden file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	PR_Close(fd_file);
+#endif	/* XP_UNIX */
+
+#endif	/* XP_UNIX || (XP_PC && WIN32) */
+
+
+	if (PR_FAILURE == PR_CloseDir(fd_dir))
+	{
+		printf(
+			"testfile failed to close dirctory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf(
+			"testfile failed to reopen dirctory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+  
+	/*
+	 * List all files, including hidden files
+	 */
+	DPRINTF(("Listing all files in directory %s\n",TEST_DIR));
+#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
+	num_files = FILES_IN_DIR + 1;
+#else
+	num_files = FILES_IN_DIR;
+#endif
+	while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) {
+		num_files--;
+		strcpy(pathname, TEST_DIR);
+		strcat(pathname, "/");
+		strcat(pathname, dirEntry->name);
+		DPRINTF(("\t%s\n",dirEntry->name));
+
+		if ((PR_GetFileInfo(pathname, &info)) < 0) {
+			printf(
+				"testfile failed to GetFileInfo file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+			return -1;
+		}
+		
+		if (info.type != PR_FILE_FILE) {
+			printf(
+				"testfile incorrect fileinfo for file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+			return -1;
+		}
+	}
+	if (num_files != 0)
+	{
+		printf(
+			"testfile failed to find all files in directory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+    PR_CloseDir(fd_dir);
+
+#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
+
+	/*
+	 * List all files, except hidden files
+	 */
+
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf(
+			"testfile failed to reopen dirctory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+  
+	DPRINTF(("Listing non-hidden files in directory %s\n",TEST_DIR));
+	while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_HIDDEN)) != NULL) {
+		DPRINTF(("\t%s\n",dirEntry->name));
+		if (!strcmp(HIDDEN_FILE_NAME, dirEntry->name)) {
+			printf("testfile found hidden file %s\n", pathname);
+			return -1;
+		}
+
+	}
+	/*
+	 * Delete hidden file
+	 */
+	strcpy(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, HIDDEN_FILE_NAME);
+	if (PR_FAILURE == PR_Delete(pathname)) {
+		printf(
+			"testfile failed to delete hidden file %s [%d, %d]\n",
+			pathname, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+    PR_CloseDir(fd_dir);
+#endif	/* XP_UNIX || (XP_PC && WIN32) */
+
+	strcpy(renamename, TEST_DIR);
+	strcat(renamename, ".RENAMED");
+	if (PR_FAILURE == PR_Rename(TEST_DIR, renamename)) {
+		printf(
+			"testfile failed to rename directory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+    
+	if (PR_FAILURE == PR_MkDir(TEST_DIR, 0777)) {
+		printf(
+			"testfile failed to recreate dir %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	if (PR_SUCCESS == PR_Rename(renamename, TEST_DIR)) {
+		printf(
+			"testfile renamed directory to existing name %s\n",
+			renamename);
+		return -1;
+	}
+
+	if (PR_FAILURE == PR_RmDir(TEST_DIR)) {
+		printf(
+			"testfile failed to rmdir %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+	if (PR_FAILURE == PR_Rename(renamename, TEST_DIR)) {
+		printf(
+			"testfile failed to rename directory %s [%d, %d]\n",
+			renamename, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf(
+			"testfile failed to reopen directory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+	strcpy(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, FILE_NAME);
+	path_len = strlen(pathname);
+	
+	for (i = 0; i < FILES_IN_DIR; i++) {
+
+		sprintf(pathname + path_len,"%d%s",i,"");
+
+		if (PR_FAILURE == PR_Delete(pathname)) {
+			printf(
+				"testfile failed to delete file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+			return -1;
+		}
+	}
+
+    PR_CloseDir(fd_dir);
+
+	if (PR_FAILURE == PR_RmDir(TEST_DIR)) {
+		printf(
+			"testfile failed to rmdir %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	PR_EnterMonitor(tinfo->mon);
+	tinfo->done = 1;
+	PR_Notify(tinfo->mon);
+	PR_ExitMonitor(tinfo->mon);
+
+	return 0;
+}
+/************************************************************************/
+
+/*
+ * Test file and directory NSPR APIs
+ */
+
+int main(int argc, char **argv)
+{
+#ifdef WIN32
+	PRUint32 len;
+#endif
+#if defined(XP_UNIX) || defined(XP_OS2)
+        int opt;
+        extern char *optarg;
+	extern int optind;
+#endif
+#if defined(XP_UNIX) || defined(XP_OS2)
+        while ((opt = getopt(argc, argv, "d")) != EOF) {
+                switch(opt) {
+                        case 'd':
+                                _debug_on = 1;
+                                break;
+                        default:
+                                break;
+                }
+        }
+#endif
+	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+	mon = PR_NewMonitor();
+	if (mon == NULL) {
+		printf("testfile: PR_NewMonitor failed\n");
+		exit(2);
+	}
+#ifdef WIN32
+
+#ifdef WINCE
+    {
+        WCHAR tdir[TMPDIR_LEN];
+        len = GetTempPath(TMPDIR_LEN, tdir);
+        if ((len > 0) && (len < (TMPDIR_LEN - 6))) {
+            /*
+             * enough space for prdir
+             */
+            WideCharToMultiByte(CP_ACP, 0, tdir, -1, testdir, TMPDIR_LEN, 0, 0); 
+        }
+    }
+#else
+	len = GetTempPath(TMPDIR_LEN, testdir);
+#endif      /* WINCE */
+
+	if ((len > 0) && (len < (TMPDIR_LEN - 6))) {
+		/*
+		 * enough space for prdir
+		 */
+		strcpy((testdir + len),"prdir");
+		TEST_DIR = testdir;
+		printf("TEST_DIR = %s\n",TEST_DIR);
+	}
+#endif      /* WIN32 */
+
+	if (FileTest() < 0) {
+		printf("File Test failed\n");
+		exit(2);
+	}
+	printf("File Test passed\n");
+	if ((RunDirTest() < 0) || dirtest_failed) {
+		printf("Dir Test failed\n");
+		exit(2);
+	}
+	printf("Dir Test passed\n");
+
+	PR_DestroyMonitor(mon);
+	PR_Cleanup();
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/threads.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/threads.c
new file mode 100644
index 0000000..2a9df41
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/threads.c
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+#include "prinrval.h"
+#include "plgetopt.h"
+#include "pprthred.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRMonitor *mon;
+PRInt32 count, iterations, alive;
+
+PRBool debug_mode = PR_FALSE, passed = PR_TRUE;
+
+void 
+PR_CALLBACK
+ReallyDumbThread(void *arg)
+{
+    return;
+}
+
+void
+PR_CALLBACK
+DumbThread(void *arg)
+{
+    PRInt32 tmp = (PRInt32)arg;
+    PRThreadScope scope = (PRThreadScope)tmp;
+    PRThread *thr;
+
+    thr = PR_CreateThread(PR_USER_THREAD,
+                          ReallyDumbThread,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          scope,
+                          PR_JOINABLE_THREAD,
+                          0);
+
+    if (!thr) {
+        if (debug_mode) {
+            printf("Could not create really dumb thread (%d, %d)!\n",
+                    PR_GetError(), PR_GetOSError());
+        }
+        passed = PR_FALSE;
+    } else {
+        PR_JoinThread(thr);
+    }
+    PR_EnterMonitor(mon);
+    alive--;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+}
+
+static void CreateThreads(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *thr;
+    int n;
+
+    alive = 0;
+    mon = PR_NewMonitor();
+
+    alive = count;
+    for (n=0; n<count; n++) {
+        thr = PR_CreateThread(PR_USER_THREAD,
+                              DumbThread, 
+                              (void *)scope2, 
+                              PR_PRIORITY_NORMAL,
+                              scope1,
+                              PR_UNJOINABLE_THREAD,
+                              0);
+        if (!thr) {
+            if (debug_mode) {
+                printf("Could not create dumb thread (%d, %d)!\n",
+                        PR_GetError(), PR_GetOSError());
+            }
+            passed = PR_FALSE;
+            alive--;
+        }
+         
+        PR_Sleep(0);
+    }
+
+    /* Wait for all threads to exit */
+    PR_EnterMonitor(mon);
+    while (alive) {
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    PR_ExitMonitor(mon);
+	PR_DestroyMonitor(mon);
+}
+
+static void CreateThreadsUU(void)
+{
+    CreateThreads(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CreateThreadsUK(void)
+{
+    CreateThreads(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void CreateThreadsKU(void)
+{
+    CreateThreads(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CreateThreadsKK(void)
+{
+    CreateThreads(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    if (debug_mode)
+    {
+        d = (double)PR_IntervalToMicroseconds(stop - start);
+        printf("%40s: %6.2f usec\n", msg, d / count);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    int index;
+
+    PR_STDIO_INIT();
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_HIGH, 0);
+    
+    {
+    	PLOptStatus os;
+    	PLOptState *opt = PL_CreateOptState(argc, argv, "dc:i:");
+    	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+    		if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug mode */
+    			debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop counter */
+    			count = atoi(opt->value);
+                break;
+            case 'i':  /* loop counter */
+    			iterations = atoi(opt->value);
+                break;
+             default:
+                break;
+            }
+        }
+    	PL_DestroyOptState(opt);
+    }
+
+    if (0 == count) count = 50;
+    if (0 == iterations) iterations = 10;
+
+    if (debug_mode)
+    {
+    printf("\
+** Tests lots of thread creations.  \n\
+** Create %ld native threads %ld times. \n\
+** Create %ld user threads %ld times \n", iterations,count,iterations,count);
+    }
+
+    for (index=0; index<iterations; index++) {
+        Measure(CreateThreadsUU, "Create user/user threads");
+        Measure(CreateThreadsUK, "Create user/native threads");
+        Measure(CreateThreadsKU, "Create native/user threads");
+        Measure(CreateThreadsKK, "Create native/native threads");
+    }
+
+    if (debug_mode) printf("\nNow switch to recycling threads \n\n");
+    PR_SetThreadRecycleMode(1);
+
+    for (index=0; index<iterations; index++) {
+        Measure(CreateThreadsUU, "Create user/user threads");
+        Measure(CreateThreadsUK, "Create user/native threads");
+        Measure(CreateThreadsKU, "Create native/user threads");
+        Measure(CreateThreadsKK, "Create native/native threads");
+    }
+
+
+    printf("%s\n", ((passed) ? "PASS" : "FAIL"));
+
+    PR_Cleanup();
+
+    if (passed) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/thrpool_client.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/thrpool_client.c
new file mode 100644
index 0000000..706f87a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/thrpool_client.c
@@ -0,0 +1,376 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: thrpool_client.c
+**
+** Description: Test threadpool functionality.
+**
+** Modification History:
+*/
+#include "primpl.h"
+
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#ifdef XP_UNIX
+#include <sys/mman.h>
+#endif
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#endif
+
+#ifdef WIN32
+#include <process.h>
+#endif
+
+static int _debug_on = 0;
+static int server_port = -1;
+static char *program_name = NULL;
+
+#include "obsolete/prsem.h"
+
+#ifdef XP_PC
+#define mode_t int
+#endif
+
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+#define    BUF_DATA_SIZE    (2 * 1024)
+#define TCP_MESG_SIZE    1024
+#define NUM_TCP_CLIENTS            10	/* for a listen queue depth of 5 */
+
+#define NUM_TCP_CONNECTIONS_PER_CLIENT    10
+#define NUM_TCP_MESGS_PER_CONNECTION    10
+#define TCP_SERVER_PORT            10000
+
+static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS;
+static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT;
+static PRInt32 tcp_mesg_size = TCP_MESG_SIZE;
+static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION;
+
+int failed_already=0;
+
+typedef struct buffer {
+    char    data[BUF_DATA_SIZE];
+} buffer;
+
+PRNetAddr tcp_server_addr, udp_server_addr;
+
+typedef struct Client_Param {
+    PRNetAddr server_addr;
+    PRMonitor *exit_mon;    /* monitor to signal on exit */
+    PRInt32 *exit_counter;    /* counter to decrement, before exit */
+    PRInt32    datalen;
+} Client_Param;
+
+/*
+ * readn
+ *    read data from sockfd into buf
+ */
+static PRInt32
+readn(PRFileDesc *sockfd, char *buf, int len)
+{
+    int rem;
+    int bytes;
+    int offset = 0;
+	PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+
+    for (rem=len; rem; offset += bytes, rem -= bytes) {
+        DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n",
+            PR_GetCurrentThread(), rem));
+        bytes = PR_Recv(sockfd, buf + offset, rem, 0,
+            	timeout);
+        DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n",
+            PR_GetCurrentThread(), bytes));
+        if (bytes < 0) {
+			return -1;
+		}	
+    }
+    return len;
+}
+
+/*
+ * writen
+ *    write data from buf to sockfd
+ */
+static PRInt32
+writen(PRFileDesc *sockfd, char *buf, int len)
+{
+    int rem;
+    int bytes;
+    int offset = 0;
+
+    for (rem=len; rem; offset += bytes, rem -= bytes) {
+        DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n",
+            PR_GetCurrentThread(), rem));
+        bytes = PR_Send(sockfd, buf + offset, rem, 0,
+            PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n",
+            PR_GetCurrentThread(), bytes));
+        if (bytes <= 0)
+            return -1;
+    }
+    return len;
+}
+
+/*
+ * TCP_Client
+ *    Client job
+ *    Connect to the server at the address specified in the argument.
+ *    Fill in a buffer, write data to server, read it back and check
+ *    for data corruption.
+ *    Close the socket for server connection
+ */
+static void PR_CALLBACK
+TCP_Client(void *arg)
+{
+    Client_Param *cp = (Client_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf, *out_buf;
+    union PRNetAddr netaddr;
+    PRInt32 bytes, i, j;
+
+
+    DPRINTF(("TCP client started\n"));
+    bytes = cp->datalen;
+    out_buf = PR_NEW(buffer);
+    if (out_buf == NULL) {
+        fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name);
+        failed_already=1;
+        return;
+    }
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name);
+        failed_already=1;
+        return;
+    }
+    netaddr.inet.family = cp->server_addr.inet.family;
+    netaddr.inet.port = cp->server_addr.inet.port;
+    netaddr.inet.ip = cp->server_addr.inet.ip;
+
+    for (i = 0; i < num_tcp_connections_per_client; i++) {
+        if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) {
+            fprintf(stderr,"%s: PR_OpenTCPSocket failed\n", program_name);
+            failed_already=1;
+            return;
+        }
+
+        DPRINTF(("TCP client connecting to server:%d\n", server_port));
+        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
+        	fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n",
+            		PR_GetError(), PR_GetOSError());
+            failed_already=1;
+            return;
+        }
+        for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
+            /*
+             * fill in random data
+             */
+            memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes);
+            /*
+             * write to server
+             */
+            if (writen(sockfd, out_buf->data, bytes) < bytes) {
+                fprintf(stderr,"%s: ERROR - TCP_Client:writen\n", program_name);
+                failed_already=1;
+                return;
+            }
+			/*
+            DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
+                PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
+			*/
+            if (readn(sockfd, in_buf->data, bytes) < bytes) {
+                fprintf(stderr,"%s: ERROR - TCP_Client:readn\n", program_name);
+                failed_already=1;
+                return;
+            }
+            /*
+             * verify the data read
+             */
+            if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
+                fprintf(stderr,"%s: ERROR - data corruption\n", program_name);
+                failed_already=1;
+                return;
+            }
+        }
+        /*
+         * shutdown reads and writes
+         */
+        if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
+            fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name);
+            failed_already=1;
+        }
+        PR_Close(sockfd);
+    }
+
+    PR_DELETE(out_buf);
+    PR_DELETE(in_buf);
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(cp->exit_mon);
+    --(*cp->exit_counter);
+    PR_Notify(cp->exit_mon);
+    PR_ExitMonitor(cp->exit_mon);
+    DPRINTF(("TCP_Client exiting\n"));
+}
+
+/*
+ * TCP_Socket_Client_Server_Test    - concurrent server test
+ *    
+ *    Each client connects to the server and sends a chunk of data
+ *    For each connection, server reads the data
+ *    from the client and sends it back to the client, unmodified.
+ *    Each client checks that data received from server is same as the
+ *    data it sent to the server.
+ *
+ */
+
+static PRInt32
+TCP_Socket_Client_Server_Test(void)
+{
+    int i;
+    Client_Param *cparamp;
+    PRMonitor *mon2;
+    PRInt32    datalen;
+    PRInt32    connections = 0;
+	PRThread *thr;
+
+    datalen = tcp_mesg_size;
+    connections = 0;
+
+    mon2 = PR_NewMonitor();
+    if (mon2 == NULL) {
+        fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name);
+        failed_already=1;
+        return -1;
+    }
+
+    /*
+     * Start client jobs
+     */
+    cparamp = PR_NEW(Client_Param);
+    if (cparamp == NULL) {
+        fprintf(stderr,"%s: PR_NEW failed\n", program_name);
+        failed_already=1;
+        return -1;
+    }
+    cparamp->server_addr.inet.family = PR_AF_INET;
+    cparamp->server_addr.inet.port = PR_htons(server_port);
+    cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    cparamp->exit_mon = mon2;
+    cparamp->exit_counter = &connections;
+    cparamp->datalen = datalen;
+    for (i = 0; i < num_tcp_clients; i++) {
+		thr = PR_CreateThread(PR_USER_THREAD, TCP_Client, (void *)cparamp,
+        		PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+        if (NULL == thr) {
+            fprintf(stderr,"%s: PR_CreateThread failed\n", program_name);
+            failed_already=1;
+            return -1;
+        }
+    	PR_EnterMonitor(mon2);
+        connections++;
+    	PR_ExitMonitor(mon2);
+        DPRINTF(("Created TCP client = 0x%lx\n", thr));
+    }
+    /* Wait for client jobs to exit */
+    PR_EnterMonitor(mon2);
+    while (0 != connections) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("Client job count = %d\n", connections));
+    }
+    PR_ExitMonitor(mon2);
+    printf("%30s","TCP_Socket_Client_Server_Test:");
+    printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
+        num_tcp_clients, num_tcp_connections_per_client);
+    printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
+        num_tcp_mesgs_per_connection, tcp_mesg_size);
+
+    PR_DELETE(cparamp);
+    return 0;
+}
+
+/************************************************************************/
+
+int main(int argc, char **argv)
+{
+    /*
+     * -d           debug mode
+     */
+    PLOptStatus os;
+    PLOptState *opt;
+	program_name = argv[0];
+
+    opt = PL_CreateOptState(argc, argv, "dp:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        case 'p':
+            server_port = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetConcurrency(4);
+
+	TCP_Socket_Client_Server_Test();
+
+    PR_Cleanup();
+    if (failed_already)
+		return 1;
+    else
+		return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/thrpool_server.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/thrpool_server.c
new file mode 100644
index 0000000..2c64776
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/thrpool_server.c
@@ -0,0 +1,604 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: thrpool.c
+**
+** Description: Test threadpool functionality.
+**
+** Modification History:
+*/
+#include "primpl.h"
+
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#ifdef XP_UNIX
+#include <sys/mman.h>
+#endif
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#endif
+
+/* for getcwd */
+#if defined(XP_UNIX) || defined (XP_OS2) || defined(XP_BEOS)
+#include <unistd.h>
+#elif defined(XP_PC)
+#include <direct.h>
+#endif
+
+#ifdef WIN32
+#include <process.h>
+#endif
+
+static int _debug_on = 0;
+static char *program_name = NULL;
+static void serve_client_write(void *arg);
+
+#include "obsolete/prsem.h"
+
+#ifdef XP_PC
+#define mode_t int
+#endif
+
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+
+#define BUF_DATA_SIZE    (2 * 1024)
+#define TCP_MESG_SIZE    1024
+#define NUM_TCP_CLIENTS  10	/* for a listen queue depth of 5 */
+
+
+#define NUM_TCP_CONNECTIONS_PER_CLIENT  10
+#define NUM_TCP_MESGS_PER_CONNECTION    10
+#define TCP_SERVER_PORT            		10000
+#define SERVER_MAX_BIND_COUNT        	100
+
+#ifdef WINCE
+char *getcwd(char *buf, size_t size)
+{
+    wchar_t wpath[MAX_PATH];
+    _wgetcwd(wpath, MAX_PATH);
+    WideCharToMultiByte(CP_ACP, 0, wpath, -1, buf, size, 0, 0);
+}
+ 
+#define perror(s)
+#endif
+
+static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS;
+static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT;
+static PRInt32 tcp_mesg_size = TCP_MESG_SIZE;
+static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION;
+static void TCP_Server_Accept(void *arg);
+
+
+int failed_already=0;
+typedef struct buffer {
+    char    data[BUF_DATA_SIZE];
+} buffer;
+
+
+typedef struct Server_Param {
+    PRJobIoDesc iod;    /* socket to read from/write to    */
+    PRInt32    	datalen;    /* bytes of data transfered in each read/write */
+    PRNetAddr	netaddr;
+    PRMonitor	*exit_mon;    /* monitor to signal on exit            */
+    PRInt32		*job_counterp;    /* counter to decrement, before exit        */
+    PRInt32		conn_counter;    /* counter to decrement, before exit        */
+	PRThreadPool *tp;
+} Server_Param;
+
+typedef struct Serve_Client_Param {
+    PRJobIoDesc iod;    /* socket to read from/write to    */
+    PRInt32    datalen;    /* bytes of data transfered in each read/write */
+    PRMonitor *exit_mon;    /* monitor to signal on exit            */
+    PRInt32 *job_counterp;    /* counter to decrement, before exit        */
+	PRThreadPool *tp;
+} Serve_Client_Param;
+
+typedef struct Session {
+    PRJobIoDesc iod;    /* socket to read from/write to    */
+	buffer 	*in_buf;
+	PRInt32 bytes;
+	PRInt32 msg_num;
+	PRInt32 bytes_read;
+    PRMonitor *exit_mon;    /* monitor to signal on exit            */
+    PRInt32 *job_counterp;    /* counter to decrement, before exit        */
+	PRThreadPool *tp;
+} Session;
+
+static void
+serve_client_read(void *arg)
+{
+	Session *sp = (Session *) arg;
+    int rem;
+    int bytes;
+    int offset;
+	PRFileDesc *sockfd;
+	char *buf;
+	PRJob *jobp;
+
+	PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+
+	sockfd = sp->iod.socket;
+	buf = sp->in_buf->data;
+
+    PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection);
+	PR_ASSERT(sp->bytes_read < sp->bytes);
+
+	offset = sp->bytes_read;
+	rem = sp->bytes - offset;
+	bytes = PR_Recv(sockfd, buf + offset, rem, 0, timeout);
+	if (bytes < 0) {
+		return;
+	}
+	sp->bytes_read += bytes;
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	if (sp->bytes_read <  sp->bytes) {
+		jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp,
+							PR_FALSE);
+		PR_ASSERT(NULL != jobp);
+		return;
+	}
+	PR_ASSERT(sp->bytes_read == sp->bytes);
+	DPRINTF(("serve_client: read complete, msg(%d) \n", sp->msg_num));
+
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	jobp = PR_QueueJob_Write(sp->tp, &sp->iod, serve_client_write, sp,
+							PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+
+    return;
+}
+
+static void
+serve_client_write(void *arg)
+{
+	Session *sp = (Session *) arg;
+    int bytes;
+	PRFileDesc *sockfd;
+	char *buf;
+	PRJob *jobp;
+
+	sockfd = sp->iod.socket;
+	buf = sp->in_buf->data;
+
+    PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection);
+
+	bytes = PR_Send(sockfd, buf, sp->bytes, 0, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(bytes == sp->bytes);
+
+	if (bytes < 0) {
+		return;
+	}
+	DPRINTF(("serve_client: write complete, msg(%d) \n", sp->msg_num));
+    sp->msg_num++;
+    if (sp->msg_num < num_tcp_mesgs_per_connection) {
+		sp->bytes_read = 0;
+		sp->iod.timeout = PR_SecondsToInterval(60);
+		jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp,
+							PR_FALSE);
+		PR_ASSERT(NULL != jobp);
+		return;
+	}
+
+	DPRINTF(("serve_client: read/write complete, msg(%d) \n", sp->msg_num));
+    if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
+        fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name);
+    }
+
+    PR_Close(sockfd);
+    PR_EnterMonitor(sp->exit_mon);
+    --(*sp->job_counterp);
+    PR_Notify(sp->exit_mon);
+    PR_ExitMonitor(sp->exit_mon);
+
+    PR_DELETE(sp->in_buf);
+    PR_DELETE(sp);
+
+    return;
+}
+
+/*
+ * Serve_Client
+ *    Thread, started by the server, for serving a client connection.
+ *    Reads data from socket and writes it back, unmodified, and
+ *    closes the socket
+ */
+static void PR_CALLBACK
+Serve_Client(void *arg)
+{
+    Serve_Client_Param *scp = (Serve_Client_Param *) arg;
+    buffer *in_buf;
+	Session *sp;
+	PRJob *jobp;
+
+	sp = PR_NEW(Session);
+	sp->iod = scp->iod;
+
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"%s: failed to alloc buffer struct\n",program_name);
+        failed_already=1;
+        return;
+    }
+
+	sp->in_buf = in_buf;
+	sp->bytes = scp->datalen;
+	sp->msg_num = 0;
+	sp->bytes_read = 0;
+	sp->tp = scp->tp;
+   	sp->exit_mon = scp->exit_mon;
+    sp->job_counterp = scp->job_counterp;
+
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp,
+							PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+	PR_DELETE(scp);
+}
+
+static void
+print_stats(void *arg)
+{
+    Server_Param *sp = (Server_Param *) arg;
+    PRThreadPool *tp = sp->tp;
+    PRInt32 counter;
+	PRJob *jobp;
+
+	PR_EnterMonitor(sp->exit_mon);
+	counter = (*sp->job_counterp);
+	PR_ExitMonitor(sp->exit_mon);
+
+	printf("PRINT_STATS: #client connections = %d\n",counter);
+
+
+	jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(500),
+						print_stats, sp, PR_FALSE);
+
+	PR_ASSERT(NULL != jobp);
+}
+
+static int job_counter = 0;
+/*
+ * TCP Server
+ *    Server binds an address to a socket, starts a client process and
+ *	  listens for incoming connections.
+ *    Each client connects to the server and sends a chunk of data
+ *    Starts a Serve_Client job for each incoming connection, to read
+ *    the data from the client and send it back to the client, unmodified.
+ *    Each client checks that data received from server is same as the
+ *    data it sent to the server.
+ *	  Finally, the threadpool is shutdown
+ */
+static void PR_CALLBACK
+TCP_Server(void *arg)
+{
+    PRThreadPool *tp = (PRThreadPool *) arg;
+    Server_Param *sp;
+    PRFileDesc *sockfd;
+    PRNetAddr netaddr;
+	PRMonitor *sc_mon;
+	PRJob *jobp;
+	int i;
+	PRStatus rval;
+
+    /*
+     * Create a tcp socket
+     */
+    if ((sockfd = PR_NewTCPSocket()) == NULL) {
+        fprintf(stderr,"%s: PR_NewTCPSocket failed\n", program_name);
+        return;
+    }
+    memset(&netaddr, 0 , sizeof(netaddr));
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
+    netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+	i = 0;
+    while (PR_Bind(sockfd, &netaddr) < 0) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            netaddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        fprintf(stderr,"%s: ERROR - PR_Bind failed\n", program_name);
+        perror("PR_Bind");
+        failed_already=1;
+        return;
+    }
+
+    if (PR_Listen(sockfd, 32) < 0) {
+        fprintf(stderr,"%s: ERROR - PR_Listen failed\n", program_name);
+        failed_already=1;
+        return;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"%s: ERROR - PR_GetSockName failed\n", program_name);
+        failed_already=1;
+        return;
+    }
+
+    DPRINTF((
+	"TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+
+	sp = PR_NEW(Server_Param);
+	if (sp == NULL) {
+		fprintf(stderr,"%s: PR_NEW failed\n", program_name);
+		failed_already=1;
+		return;
+	}
+	sp->iod.socket = sockfd;
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	sp->datalen = tcp_mesg_size;
+	sp->exit_mon = sc_mon;
+	sp->job_counterp = &job_counter;
+	sp->conn_counter = 0;
+	sp->tp = tp;
+	sp->netaddr = netaddr;
+
+	/* create and cancel an io job */
+	jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp,
+							PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+	rval = PR_CancelJob(jobp);
+	PR_ASSERT(PR_SUCCESS == rval);
+
+	/*
+	 * create the client process
+	 */
+	{
+#define MAX_ARGS 4
+		char *argv[MAX_ARGS + 1];
+		int index = 0;
+		char port[32];
+        char path[1024 + sizeof("/thrpool_client")];
+
+        getcwd(path, sizeof(path));
+
+        (void)strcat(path, "/thrpool_client");
+#ifdef XP_PC
+        (void)strcat(path, ".exe");
+#endif
+        argv[index++] = path;
+		sprintf(port,"%d",PR_ntohs(netaddr.inet.port));
+        if (_debug_on)
+        {
+            argv[index++] = "-d";
+            argv[index++] = "-p";
+            argv[index++] = port;
+            argv[index++] = NULL;
+        } else {
+            argv[index++] = "-p";
+            argv[index++] = port;
+			argv[index++] = NULL;
+		}
+		PR_ASSERT(MAX_ARGS >= (index - 1));
+        
+        DPRINTF(("creating client process %s ...\n", path));
+        if (PR_FAILURE == PR_CreateProcessDetached(path, argv, NULL, NULL)) {
+        	fprintf(stderr,
+				"thrpool_server: ERROR - PR_CreateProcessDetached failed\n");
+        	failed_already=1;
+        	return;
+		}
+	}
+
+    sc_mon = PR_NewMonitor();
+    if (sc_mon == NULL) {
+        fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name);
+        failed_already=1;
+        return;
+    }
+
+	sp->iod.socket = sockfd;
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	sp->datalen = tcp_mesg_size;
+	sp->exit_mon = sc_mon;
+	sp->job_counterp = &job_counter;
+	sp->conn_counter = 0;
+	sp->tp = tp;
+	sp->netaddr = netaddr;
+
+	/* create and cancel a timer job */
+	jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(5000),
+						print_stats, sp, PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+	rval = PR_CancelJob(jobp);
+	PR_ASSERT(PR_SUCCESS == rval);
+
+    DPRINTF(("TCP_Server: Accepting connections \n"));
+
+	jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp,
+							PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+	return;
+}
+
+static void
+TCP_Server_Accept(void *arg)
+{
+    Server_Param *sp = (Server_Param *) arg;
+    PRThreadPool *tp = sp->tp;
+    Serve_Client_Param *scp;
+	PRFileDesc *newsockfd;
+	PRJob *jobp;
+
+	if ((newsockfd = PR_Accept(sp->iod.socket, &sp->netaddr,
+		PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+		fprintf(stderr,"%s: ERROR - PR_Accept failed\n", program_name);
+		failed_already=1;
+		goto exit;
+	}
+	scp = PR_NEW(Serve_Client_Param);
+	if (scp == NULL) {
+		fprintf(stderr,"%s: PR_NEW failed\n", program_name);
+		failed_already=1;
+		goto exit;
+	}
+
+	/*
+	 * Start a Serve_Client job for each incoming connection
+	 */
+	scp->iod.socket = newsockfd;
+	scp->iod.timeout = PR_SecondsToInterval(60);
+	scp->datalen = tcp_mesg_size;
+	scp->exit_mon = sp->exit_mon;
+	scp->job_counterp = sp->job_counterp;
+	scp->tp = sp->tp;
+
+	PR_EnterMonitor(sp->exit_mon);
+	(*sp->job_counterp)++;
+	PR_ExitMonitor(sp->exit_mon);
+	jobp = PR_QueueJob(tp, Serve_Client, scp,
+						PR_FALSE);
+
+	PR_ASSERT(NULL != jobp);
+	DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", jobp));
+
+	/*
+	 * single-threaded update; no lock needed
+	 */
+    sp->conn_counter++;
+    if (sp->conn_counter <
+			(num_tcp_clients * num_tcp_connections_per_client)) {
+		jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp,
+								PR_FALSE);
+		PR_ASSERT(NULL != jobp);
+		return;
+	}
+	jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(500),
+						print_stats, sp, PR_FALSE);
+
+	PR_ASSERT(NULL != jobp);
+	DPRINTF(("TCP_Server: Created print_stats timer job = 0x%lx\n", jobp));
+
+exit:
+	PR_EnterMonitor(sp->exit_mon);
+    /* Wait for server jobs to finish */
+    while (0 != *sp->job_counterp) {
+        PR_Wait(sp->exit_mon, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("TCP_Server: conn_counter = %d\n",
+												*sp->job_counterp));
+    }
+
+    PR_ExitMonitor(sp->exit_mon);
+    if (sp->iod.socket) {
+        PR_Close(sp->iod.socket);
+    }
+	PR_DestroyMonitor(sp->exit_mon);
+    printf("%30s","TCP_Socket_Client_Server_Test:");
+    printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
+        num_tcp_clients, num_tcp_connections_per_client);
+    printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
+        num_tcp_mesgs_per_connection, tcp_mesg_size);
+
+	DPRINTF(("%s: calling PR_ShutdownThreadPool\n", program_name));
+	PR_ShutdownThreadPool(sp->tp);
+	PR_DELETE(sp);
+}
+
+/************************************************************************/
+
+#define DEFAULT_INITIAL_THREADS		4
+#define DEFAULT_MAX_THREADS			100
+#define DEFAULT_STACKSIZE			(512 * 1024)
+
+int main(int argc, char **argv)
+{
+	PRInt32 initial_threads = DEFAULT_INITIAL_THREADS;
+	PRInt32 max_threads = DEFAULT_MAX_THREADS;
+	PRInt32 stacksize = DEFAULT_STACKSIZE;
+	PRThreadPool *tp = NULL;
+	PRStatus rv;
+	PRJob *jobp;
+
+    /*
+     * -d           debug mode
+     */
+    PLOptStatus os;
+    PLOptState *opt;
+
+	program_name = argv[0];
+    opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetConcurrency(4);
+
+	tp = PR_CreateThreadPool(initial_threads, max_threads, stacksize);
+    if (NULL == tp) {
+        printf("PR_CreateThreadPool failed\n");
+        failed_already=1;
+        goto done;
+	}
+	jobp = PR_QueueJob(tp, TCP_Server, tp, PR_TRUE);
+	rv = PR_JoinJob(jobp);		
+	PR_ASSERT(PR_SUCCESS == rv);
+
+	DPRINTF(("%s: calling PR_JoinThreadPool\n", program_name));
+	rv = PR_JoinThreadPool(tp);
+	PR_ASSERT(PR_SUCCESS == rv);
+	DPRINTF(("%s: returning from PR_JoinThreadPool\n", program_name));
+
+done:
+    PR_Cleanup();
+    if (failed_already) return 1;
+    else return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/thruput.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/thruput.c
new file mode 100644
index 0000000..6c9c123
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/thruput.c
@@ -0,0 +1,410 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        thruput.c
+** Description: Test server's throughput capability comparing various
+**              implmentation strategies.
+**
+** Note:        Requires a server machine and an aribitrary number of
+**              clients to bang on it. Trust the numbers on the server
+**              more than those being displayed by the various clients.
+*/
+
+#include "prerror.h"
+#include "prinrval.h"
+#include "prinit.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prmem.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prthread.h"
+#include "pprio.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#define ADDR_BUFFER 100
+#define PORT_NUMBER 51877
+#define SAMPLING_INTERVAL 10
+#define BUFFER_SIZE (32 * 1024)
+
+static PRInt32 domain = PR_AF_INET;
+static PRInt32 protocol = 6;  /* TCP */
+static PRFileDesc *err = NULL;
+static PRIntn concurrency = 1;
+static PRInt32 xport_buffer = -1;
+static PRUint32 initial_streams = 1;
+static PRInt32 buffer_size = BUFFER_SIZE;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+typedef struct Shared
+{
+    PRLock *ml;
+    PRUint32 sampled;
+    PRUint32 threads;
+    PRIntervalTime timein;
+    PRNetAddr server_address;
+} Shared;
+
+static Shared *shared = NULL;
+
+static PRStatus PrintAddress(const PRNetAddr* address)
+{
+    char buffer[ADDR_BUFFER];
+    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
+    if (PR_SUCCESS == rv)
+        PR_fprintf(err, "%s:%u\n", buffer, PR_ntohs(address->inet.port));
+    else PL_FPrintError(err, "PR_NetAddrToString");
+    return rv;
+}  /* PrintAddress */
+
+
+static void PR_CALLBACK Clientel(void *arg)
+{
+    PRStatus rv;
+    PRFileDesc *xport;
+    PRInt32 bytes, sampled;
+    PRIntervalTime now, interval;
+    PRBool do_display = PR_FALSE;
+    Shared *shared = (Shared*)arg;
+    char *buffer = (char*)PR_Malloc(buffer_size);
+    PRNetAddr *server_address = &shared->server_address;
+    PRIntervalTime connect_timeout = PR_SecondsToInterval(5);
+    PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);
+
+    PR_fprintf(err, "Client connecting to ");
+    (void)PrintAddress(server_address);
+
+    do
+    {
+        xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
+        if (NULL == xport)
+        {
+            PL_FPrintError(err, "PR_Socket");
+            return;
+        }
+
+        if (xport_buffer != -1)
+        {
+            PRSocketOptionData data;
+            data.option = PR_SockOpt_RecvBufferSize;
+            data.value.recv_buffer_size = (PRSize)xport_buffer;
+            rv = PR_SetSocketOption(xport, &data);
+            if (PR_FAILURE == rv)
+                PL_FPrintError(err, "PR_SetSocketOption - ignored");
+            data.option = PR_SockOpt_SendBufferSize;
+            data.value.send_buffer_size = (PRSize)xport_buffer;
+            rv = PR_SetSocketOption(xport, &data);
+            if (PR_FAILURE == rv)
+                PL_FPrintError(err, "PR_SetSocketOption - ignored");
+        }
+
+        rv = PR_Connect(xport, server_address, connect_timeout);
+        if (PR_FAILURE == rv)
+        {
+            PL_FPrintError(err, "PR_Connect");
+            if (PR_IO_TIMEOUT_ERROR != PR_GetError())
+                PR_Sleep(connect_timeout);
+            PR_Close(xport);  /* delete it and start over */
+        }
+    } while (PR_FAILURE == rv);
+
+    do
+    {
+        bytes = PR_Recv(
+            xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);
+        PR_Lock(shared->ml);
+        now = PR_IntervalNow();
+        shared->sampled += bytes;
+        interval = now - shared->timein;
+        if (interval > sampling_interval)
+        {
+            sampled = shared->sampled;
+            shared->timein = now;
+            shared->sampled = 0;
+            do_display = PR_TRUE;
+        }
+        PR_Unlock(shared->ml);
+
+        if (do_display)
+        {
+            PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
+            PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
+            do_display = PR_FALSE;
+        }
+
+    } while (bytes > 0);
+}  /* Clientel */
+
+static void Client(const char *server_name)
+{
+    PRStatus rv;
+    PRHostEnt host;
+    char buffer[PR_NETDB_BUF_SIZE];
+    PRIntervalTime dally = PR_SecondsToInterval(60);
+    PR_fprintf(err, "Translating the name %s\n", server_name);
+    rv = PR_GetHostByName(server_name, buffer, sizeof(buffer), &host);
+    if (PR_FAILURE == rv)
+        PL_FPrintError(err, "PR_GetHostByName");
+    else
+    {
+        if (PR_EnumerateHostEnt(
+            0, &host, PORT_NUMBER, &shared->server_address) < 0)
+            PL_FPrintError(err, "PR_EnumerateHostEnt");
+        else
+        {
+            do
+            {
+                shared->threads += 1;
+                (void)PR_CreateThread(
+                    PR_USER_THREAD, Clientel, shared,
+                    PR_PRIORITY_NORMAL, thread_scope,
+                    PR_UNJOINABLE_THREAD, 8 * 1024);
+                if (shared->threads == initial_streams)
+                {
+                    PR_Sleep(dally);
+                    initial_streams += 1;
+                }
+            } while (PR_TRUE);
+        }
+    }
+}
+
+static void PR_CALLBACK Servette(void *arg)
+{
+    PRInt32 bytes, sampled;
+    PRIntervalTime now, interval;
+    PRBool do_display = PR_FALSE;
+    PRFileDesc *client = (PRFileDesc*)arg;
+    char *buffer = (char*)PR_Malloc(buffer_size);
+    PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);
+
+    if (xport_buffer != -1)
+    {
+        PRStatus rv;
+        PRSocketOptionData data;
+        data.option = PR_SockOpt_RecvBufferSize;
+        data.value.recv_buffer_size = (PRSize)xport_buffer;
+        rv = PR_SetSocketOption(client, &data);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err, "PR_SetSocketOption - ignored");
+        data.option = PR_SockOpt_SendBufferSize;
+        data.value.send_buffer_size = (PRSize)xport_buffer;
+        rv = PR_SetSocketOption(client, &data);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err, "PR_SetSocketOption - ignored");
+    }
+
+    do
+    {
+        bytes = PR_Send(
+            client, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);
+
+        PR_Lock(shared->ml);
+        now = PR_IntervalNow();
+        shared->sampled += bytes;
+        interval = now - shared->timein;
+        if (interval > sampling_interval)
+        {
+            sampled = shared->sampled;
+            shared->timein = now;
+            shared->sampled = 0;
+            do_display = PR_TRUE;
+        }
+        PR_Unlock(shared->ml);
+
+        if (do_display)
+        {
+            PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
+            PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
+            do_display = PR_FALSE;
+        }
+    } while (bytes > 0);
+}  /* Servette */
+
+static void Server(void)
+{
+    PRStatus rv;
+    PRNetAddr server_address, client_address;
+    PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
+
+    if (NULL == xport)
+    {
+        PL_FPrintError(err, "PR_Socket");
+        return;
+    }
+
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER, &server_address);
+    if (PR_FAILURE == rv) PL_FPrintError(err, "PR_InitializeNetAddr");
+    else
+    {
+        rv = PR_Bind(xport, &server_address);
+        if (PR_FAILURE == rv) PL_FPrintError(err, "PR_Bind");
+        else
+        {
+            PRFileDesc *client;
+            rv = PR_Listen(xport, 10);
+            PR_fprintf(err, "Server listening on ");
+            (void)PrintAddress(&server_address);
+            do
+            {
+                client = PR_Accept(
+                    xport, &client_address, PR_INTERVAL_NO_TIMEOUT);
+                if (NULL == client) PL_FPrintError(err, "PR_Accept");
+                else
+                {
+                    PR_fprintf(err, "Server accepting from ");
+                    (void)PrintAddress(&client_address);
+                    shared->threads += 1;
+                    (void)PR_CreateThread(
+                        PR_USER_THREAD, Servette, client,
+                        PR_PRIORITY_NORMAL, thread_scope,
+                        PR_UNJOINABLE_THREAD, 8 * 1024);
+                }
+            } while (PR_TRUE);
+
+        }
+    }
+}  /* Server */
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-h] [<server>]\n");
+    PR_fprintf(err, "\t-s <n>   Initial # of connections        (default: 1)\n");
+    PR_fprintf(err, "\t-C <n>   Set 'concurrency'               (default: 1)\n");
+    PR_fprintf(err, "\t-b <nK>  Client buffer size              (default: 32k)\n");
+    PR_fprintf(err, "\t-B <nK>  Transport recv/send buffer size (default: sys)\n");
+    PR_fprintf(err, "\t-G       Use GLOBAL threads              (default: LOCAL)\n");
+    PR_fprintf(err, "\t-X       Use XTP transport               (default: TCP)\n");
+    PR_fprintf(err, "\t-6       Use IPv6                        (default: IPv4)\n");
+    PR_fprintf(err, "\t-h       This message and nothing else\n");
+    PR_fprintf(err, "\t<server> DNS name of server\n");
+    PR_fprintf(err, "\t\tIf <server> is not specified, this host will be\n");
+    PR_fprintf(err, "\t\tthe server and not act as a client.\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    const char *server_name = NULL;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hGX6C:b:s:B:");
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:  /* Name of server */
+            server_name = opt->value;
+            break;
+        case 'G':  /* Globular threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'X':  /* Use XTP as the transport */
+            protocol = 36;
+            break;
+        case '6':  /* Use IPv6 */
+            domain = PR_AF_INET6;
+            break;
+        case 's':  /* initial_streams */
+            initial_streams = atoi(opt->value);
+            break;
+        case 'C':  /* concurrency */
+            concurrency = atoi(opt->value);
+            break;
+        case 'b':  /* buffer size */
+            buffer_size = 1024 * atoi(opt->value);
+            break;
+        case 'B':  /* buffer size */
+            xport_buffer = 1024 * atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+        default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    shared = PR_NEWZAP(Shared);
+    shared->ml = PR_NewLock();
+
+    PR_fprintf(err,
+        "This machine is %s\n",
+        (NULL == server_name) ? "the SERVER" : "a CLIENT");
+
+    PR_fprintf(err,
+        "Transport being used is %s\n",
+        (6 == protocol) ? "TCP" : "XTP");
+
+    if (PR_GLOBAL_THREAD == thread_scope)
+    {
+        if (1 != concurrency)
+        {
+            PR_fprintf(err, "  **Concurrency > 1 and GLOBAL threads!?!?\n");
+            PR_fprintf(err, "  **Ignoring concurrency\n");
+            concurrency = 1;
+        }
+    }
+
+    if (1 != concurrency)
+    {
+        PR_SetConcurrency(concurrency);
+        PR_fprintf(err, "Concurrency set to %u\n", concurrency);
+    }
+
+    PR_fprintf(err,
+        "All threads will be %s\n",
+        (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
+
+    PR_fprintf(err, "Client buffer size will be %u\n", buffer_size);
+   
+    if (-1 != xport_buffer)
+    PR_fprintf(
+        err, "Transport send & receive buffer size will be %u\n", xport_buffer);
+    
+
+    if (NULL == server_name) Server();
+    else Client(server_name);
+
+}  /* main */
+
+/* thruput.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/time.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/time.c
new file mode 100644
index 0000000..3321678
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/time.c
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Program to test different ways to get the time; right now it is tuned
+ * only for solaris.
+ *   solaris results (100000 iterations):
+ *          time to get time with time():   4.63 usec avg, 463 msec total
+ *     time to get time with gethrtime():   2.17 usec avg, 217 msec total
+ *  time to get time with gettimeofday():   1.25 usec avg, 125 msec total
+ *
+ *
+ */
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "prpriv.h"
+#include "prinrval.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#define DEFAULT_COUNT 100000
+PRInt32 count;
+
+time_t itime;
+hrtime_t ihrtime;
+
+void
+ftime_init()
+{
+   itime = time(NULL);
+   ihrtime = gethrtime();
+}
+
+time_t
+ftime()
+{
+        hrtime_t now = gethrtime();
+
+        return itime + ((now - ihrtime) / 1000000000ll);
+}
+
+static void timeTime(void)
+{
+    PRInt32 index = count;
+    time_t rv;
+ 
+    for (;index--;)
+        rv = time(NULL);
+}
+
+static void timeGethrtime(void)
+{
+    PRInt32 index = count;
+    time_t rv;
+ 
+    for (;index--;)
+        rv = ftime();
+}
+
+static void timeGettimeofday(void)
+{
+    PRInt32 index = count;
+    time_t rv;
+    struct timeval tp;
+ 
+    for (;index--;)
+        rv = gettimeofday(&tp, NULL);
+}
+
+static void timePRTime32(void)
+{
+    PRInt32 index = count;
+    PRInt32 rv32;
+    PRTime q;
+    PRTime rv;
+
+    LL_I2L(q, 1000000);
+ 
+    for (;index--;) {
+        rv = PR_Now();
+        LL_DIV(rv, rv, q);
+        LL_L2I(rv32, rv);
+    }
+}
+
+static void timePRTime64(void)
+{
+    PRInt32 index = count;
+    PRTime rv;
+ 
+    for (;index--;)
+        rv = PR_Now();
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+    PRInt32 tot;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+    tot = PR_IntervalToMilliseconds(stop-start);
+
+    if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot);
+}
+
+int main(int argc, char **argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 1) {
+	count = atoi(argv[1]);
+    } else {
+	count = DEFAULT_COUNT;
+    }
+
+    ftime_init();
+
+    Measure(timeTime, "time to get time with time()");
+    Measure(timeGethrtime, "time to get time with gethrtime()");
+    Measure(timeGettimeofday, "time to get time with gettimeofday()");
+    Measure(timePRTime32, "time to get time with PR_Time() (32bit)");
+    Measure(timePRTime64, "time to get time with PR_Time() (64bit)");
+
+	PR_Cleanup();
+	return 0;
+}
+
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/timemac.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/timemac.c
new file mode 100644
index 0000000..fd98a37
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/timemac.c
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * file: timemac.c
+ * description: test time and date routines on the Mac
+ */
+#include <stdio.h>
+#include "prinit.h"
+#include "prtime.h"
+
+
+static char *dayOfWeek[] =
+	{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
+static char *month[] =
+	{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
+
+static void printExplodedTime(const PRExplodedTime *et) {
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    printf( "%s %s %ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
+	    et->tm_hour, et->tm_min, et->tm_sec);
+
+    /* Print time zone */
+    totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	printf("UTC ");
+    } else {
+        sign = "";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
+    }
+
+    /* Print year */
+    printf("%d", et->tm_year);
+}
+
+int main(int argc, char** argv)
+{
+    PR_STDIO_INIT();
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+ 
+   /*
+     *************************************************************
+     **
+     **  Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime
+     **  on the current time
+     **
+     *************************************************************
+     */
+
+    {
+	PRTime t1, t2;
+	PRExplodedTime et;
+
+	printf("*********************************************\n");
+	printf("**                                         **\n");
+        printf("** Testing PR_Now(), PR_ExplodeTime, and   **\n");
+	printf("** PR_ImplodeTime on the current time      **\n");
+	printf("**                                         **\n");
+	printf("*********************************************\n\n");
+        t1 = PR_Now();
+
+        /* First try converting to UTC */
+
+        PR_ExplodeTime(t1, PR_GMTParameters, &et);
+        if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) {
+	    printf("ERROR: UTC has nonzero gmt or dst offset.\n");
+	    return 1;
+        }
+        printf("Current UTC is ");
+	printExplodedTime(&et);
+	printf("\n");
+
+        t2 = PR_ImplodeTime(&et);
+        if (LL_NE(t1, t2)) {
+	    printf("ERROR: Explode and implode are NOT inverse.\n");
+	    return 1;
+        }
+
+        /* Next, try converting to local (US Pacific) time */
+
+        PR_ExplodeTime(t1, PR_LocalTimeParameters, &et);
+        printf("Current local time is ");
+	printExplodedTime(&et);
+	printf("\n");
+	printf("GMT offset is %ld, DST offset is %ld\n",
+		et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset);
+        t2 = PR_ImplodeTime(&et);
+        if (LL_NE(t1, t2)) {
+	    printf("ERROR: Explode and implode are NOT inverse.\n");
+	    return 1;
+	}
+    }
+
+    printf("Please examine the results\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/timetest.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/timetest.c
new file mode 100644
index 0000000..d55a41b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/timetest.c
@@ -0,0 +1,771 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * file: timetest.c
+ * description: test time and date routines
+ */
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prtime.h"
+#include "prprf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int failed_already=0;
+PRBool debug_mode = PR_FALSE;
+
+static char *dayOfWeek[] =
+	{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
+static char *month[] =
+	{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
+
+static void PrintExplodedTime(const PRExplodedTime *et) {
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
+	    et->tm_hour, et->tm_min, et->tm_sec);
+
+    /* Print time zone */
+    totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	if (debug_mode) printf("UTC ");
+    } else {
+        sign = "+";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        if (debug_mode) 
+            printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
+    }
+
+    /* Print year */
+    if (debug_mode) printf("%hd", et->tm_year);
+}
+
+static int ExplodedTimeIsEqual(const PRExplodedTime *et1,
+	const PRExplodedTime *et2)
+{
+    if (et1->tm_usec == et2->tm_usec &&
+	    et1->tm_sec == et2->tm_sec &&
+	    et1->tm_min == et2->tm_min &&
+	    et1->tm_hour == et2->tm_hour &&
+	    et1->tm_mday == et2->tm_mday &&
+	    et1->tm_month == et2->tm_month &&
+	    et1->tm_year == et2->tm_year &&
+	    et1->tm_wday == et2->tm_wday &&
+	    et1->tm_yday == et2->tm_yday &&
+	    et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset &&
+	    et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) {
+        return 1;
+    } else {
+	return 0;
+    }
+}
+
+static void
+testParseTimeString(PRTime t)
+{
+    PRExplodedTime et;
+    PRTime t2;
+    char timeString[128];
+    char buf[128];
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+    PRInt64 usec_per_sec;
+
+    /* Truncate the microsecond part of PRTime */
+    LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
+    LL_DIV(t, t, usec_per_sec);
+    LL_MUL(t, t, usec_per_sec);
+
+    PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday,
+	    et.tm_hour, et.tm_min, et.tm_sec);
+    /* Print time zone */
+    totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	strcat(timeString, "GMT ");  /* I wanted to use "UTC" here, but
+                                      * PR_ParseTimeString doesn't 
+                                      * understand "UTC".  */
+    } else {
+        sign = "+";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset);
+	strcat(timeString, buf);
+    }
+    /* Print year */
+    PR_snprintf(buf, 128, "%hd", et.tm_year);
+    strcat(timeString, buf);
+
+    if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) {
+	fprintf(stderr, "PR_ParseTimeString() failed\n");
+	exit(1);
+    }
+    if (LL_NE(t, t2)) {
+	fprintf(stderr, "PR_ParseTimeString() incorrect\n");
+	PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n",
+                t, t2, timeString);
+	fprintf(stderr, "%s\n", buf);
+	exit(1);
+    }
+}
+
+int main(int argc, char** argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt;
+    
+    PR_STDIO_INIT();
+	opt = PL_CreateOptState(argc, argv, "d");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+    /* Testing zero PRTime (the epoch) */
+    {
+	PRTime t;
+	PRExplodedTime et;
+
+	LL_I2L(t, 0);
+	if (debug_mode) printf("The NSPR epoch is:\n");
+        PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
+	PrintExplodedTime(&et);
+	if (debug_mode) printf("\n");
+	PR_ExplodeTime(t, PR_GMTParameters, &et);
+	PrintExplodedTime(&et);
+	if (debug_mode) printf("\n\n");
+	testParseTimeString(t);
+    }
+
+    /*
+     *************************************************************
+     **
+     **  Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime
+     **  on the current time
+     **
+     *************************************************************
+     */
+
+    {
+	PRTime t1, t2;
+	PRExplodedTime et;
+
+	if (debug_mode) {
+	printf("*********************************************\n");
+	printf("**                                         **\n");
+    printf("** Testing PR_Now(), PR_ExplodeTime, and   **\n");
+	printf("** PR_ImplodeTime on the current time      **\n");
+	printf("**                                         **\n");
+	printf("*********************************************\n\n");
+	}
+	t1 = PR_Now();
+
+        /* First try converting to UTC */
+
+        PR_ExplodeTime(t1, PR_GMTParameters, &et);
+        if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) {
+	    if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n");
+		else failed_already=1;
+	    return 1;
+        }
+        if (debug_mode) printf("Current UTC is ");
+	PrintExplodedTime(&et);
+	if (debug_mode) printf("\n");
+
+        t2 = PR_ImplodeTime(&et);
+        if (LL_NE(t1, t2)) {
+	    if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
+		else printf("FAIL\n");
+	    return 1;
+        }
+
+        /* Next, try converting to local (US Pacific) time */
+
+        PR_ExplodeTime(t1, PR_LocalTimeParameters, &et);
+        if (debug_mode) printf("Current local time is ");
+	PrintExplodedTime(&et);
+	if (debug_mode) printf("\n");
+	if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n",
+		et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset);
+        t2 = PR_ImplodeTime(&et);
+        if (LL_NE(t1, t2)) {
+	    if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
+	    return 1;
+	}
+
+	if (debug_mode) printf("Please examine the results\n");
+	testParseTimeString(t1);
+    }
+
+
+    /*
+     *******************************************
+     **
+     ** Testing PR_NormalizeTime()
+     **
+     *******************************************
+     */
+
+    /* July 4, 2001 is Wednesday */
+    {
+	PRExplodedTime et;
+
+	if (debug_mode)  {
+	printf("\n");
+	printf("**********************************\n");
+	printf("**                              **\n");
+	printf("** Testing PR_NormalizeTime()   **\n");
+	printf("**                              **\n");
+	printf("**********************************\n\n");
+	}
+        et.tm_year    = 2001;
+        et.tm_month   = 7 - 1;
+        et.tm_mday    = 4;
+        et.tm_hour    = 0;
+        et.tm_min     = 0;
+        et.tm_sec     = 0;
+	et.tm_usec    = 0;
+        et.tm_params  = PR_GMTParameters(&et);
+
+	PR_NormalizeTime(&et, PR_GMTParameters);
+
+	if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]);
+	if (et.tm_wday == 3) {
+	    if (debug_mode) printf("PASS\n");
+        } else {
+            if (debug_mode) printf("ERROR: It should be Wednesday\n");
+			else failed_already=1;
+	    return 1;
+	}
+	testParseTimeString(PR_ImplodeTime(&et));
+
+        /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */
+        et.tm_year    = 1997;
+        et.tm_month   = 6 - 1;
+        et.tm_mday    = 12;
+        et.tm_hour    = 23;
+        et.tm_min     = 0;
+        et.tm_sec     = 0;
+	et.tm_usec    = 0;
+        et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 0;
+
+	PR_NormalizeTime(&et, PR_USPacificTimeParameters);
+
+	if (debug_mode) {
+	    printf("Thu Jun 12, 1997 23:00:00 PST is ");
+	}
+	PrintExplodedTime(&et);
+	if (debug_mode) printf(".\n");
+	if (et.tm_wday == 5) {
+	    if (debug_mode) printf("PASS\n");
+        } else {
+            if (debug_mode) printf("ERROR: It should be Friday\n");
+			else failed_already=1;
+	    return 1;
+	}
+	testParseTimeString(PR_ImplodeTime(&et));
+
+        /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */
+        et.tm_year    = 1997;
+        et.tm_month   = 2 - 1;
+        et.tm_mday    = 14;
+        et.tm_hour    = 0;
+        et.tm_min     = 0;
+        et.tm_sec     = 0;
+	et.tm_usec    = 0;
+        et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 3600;
+
+	PR_NormalizeTime(&et, PR_USPacificTimeParameters);
+
+	if (debug_mode) {
+	    printf("Fri Feb 14, 1997 00:00:00 PDT is ");
+	}
+	PrintExplodedTime(&et);
+	if (debug_mode) printf(".\n");
+	if (et.tm_wday == 4) {
+	    if (debug_mode) printf("PASS\n");
+        } else {
+            if (debug_mode) printf("ERROR: It should be Thursday\n");
+			else failed_already=1;
+	    return 1;
+	}
+	testParseTimeString(PR_ImplodeTime(&et));
+
+        /* What time is Nov. 7, 1996, 18:29:23 PDT? */
+        et.tm_year    = 1996;
+        et.tm_month   = 11 - 1;
+        et.tm_mday    = 7;
+        et.tm_hour    = 18;
+        et.tm_min     = 29;
+        et.tm_sec     = 23;
+	et.tm_usec    = 0;
+        et.tm_params.tp_gmt_offset = -8 * 3600;  /* PDT */
+	et.tm_params.tp_dst_offset = 3600; 
+
+	PR_NormalizeTime(&et, PR_LocalTimeParameters);
+        if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is ");
+	PrintExplodedTime(&et);
+	if (debug_mode) printf(".\n");
+	testParseTimeString(PR_ImplodeTime(&et));
+
+        /* What time is Oct. 7, 1995, 18:29:23 PST? */
+        et.tm_year    = 1995;
+        et.tm_month   = 10 - 1;
+        et.tm_mday    = 7;
+        et.tm_hour    = 18;
+        et.tm_min     = 29;
+        et.tm_sec     = 23;
+        et.tm_params.tp_gmt_offset = -8 * 3600;  /* PST */
+	et.tm_params.tp_dst_offset = 0;
+
+	PR_NormalizeTime(&et, PR_LocalTimeParameters);
+        if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is ");
+	PrintExplodedTime(&et);
+	if (debug_mode) printf(".\n");
+	testParseTimeString(PR_ImplodeTime(&et));
+
+	if (debug_mode) printf("Please examine the results\n");
+    }
+
+    /*
+     **************************************************************
+     **
+     ** Testing range of years
+     **
+     **************************************************************
+     */
+
+    {
+	PRExplodedTime et1, et2;
+    PRTime  ttt;
+	PRTime secs;
+
+	if (debug_mode) {
+	printf("\n");
+	printf("***************************************\n");
+	printf("**                                   **\n");
+	printf("**  Testing range of years           **\n");
+	printf("**                                   **\n");
+	printf("***************************************\n\n");
+	}
+	/* April 4, 1917 GMT */
+	et1.tm_usec = 0;
+	et1.tm_sec = 0;
+	et1.tm_min = 0;
+	et1.tm_hour = 0;
+	et1.tm_mday = 4;
+	et1.tm_month = 4 - 1;
+	et1.tm_year = 1917;
+	et1.tm_params = PR_GMTParameters(&et1);
+	PR_NormalizeTime(&et1, PR_LocalTimeParameters);
+	secs = PR_ImplodeTime(&et1);
+	if (LL_GE_ZERO(secs)) {
+	    if (debug_mode)
+		printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n");
+		failed_already = 1;
+	    return 1;
+        }
+	PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
+	if (!ExplodedTimeIsEqual(&et1, &et2)) {
+		if (debug_mode)
+		printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n");
+		failed_already=1;
+	    return 1;
+        }
+    ttt = PR_ImplodeTime(&et1);
+	testParseTimeString( ttt );
+
+	if (debug_mode) printf("Test passed for April 4, 1917\n");
+
+	/* July 4, 2050 */
+	et1.tm_usec = 0;
+	et1.tm_sec = 0;
+	et1.tm_min = 0;
+	et1.tm_hour = 0;
+	et1.tm_mday = 4;
+	et1.tm_month = 7 - 1;
+	et1.tm_year = 2050;
+	et1.tm_params = PR_GMTParameters(&et1);
+	PR_NormalizeTime(&et1, PR_LocalTimeParameters);
+	secs = PR_ImplodeTime(&et1);
+	if (!LL_GE_ZERO(secs)) {
+	    if (debug_mode)
+			printf("ERROR: July 4, 2050 GMT returns a negative second count\n");
+		failed_already = 1;
+	    return 1;
+        }
+	PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
+	if (!ExplodedTimeIsEqual(&et1, &et2)) {
+	    if (debug_mode)
+		printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n");
+		failed_already=1;
+	    return 1;
+        }
+	testParseTimeString(PR_ImplodeTime(&et1));
+
+	if (debug_mode) printf("Test passed for July 4, 2050\n");
+
+    }
+
+    /*
+     **************************************************************
+     **
+     **  Stress test
+     *
+     **      Go through four years, starting from
+     **      00:00:00 PST Jan. 1, 2005, incrementing
+     **      every 10 minutes.
+     **
+     **************************************************************
+     */
+
+    {
+	PRExplodedTime et, et1, et2;
+	PRInt64 usecPer10Min;
+	int day, hour, min;
+	PRTime usecs;
+	int dstInEffect = 0;
+
+	if (debug_mode) {
+	printf("\n");
+	printf("*******************************************************\n");
+	printf("**                                                   **\n");
+	printf("**        Stress test  Pacific Time                  **\n");
+	printf("**  Starting from midnight Jan. 1, 2005 PST,         **\n");
+	printf("**  going through four years in 10-minute increment  **\n");
+	printf("**                                                   **\n");
+	printf("*******************************************************\n\n");
+	}
+	LL_I2L(usecPer10Min, 600000000L);
+
+	/* 00:00:00 PST Jan. 1, 2005 */
+	et.tm_usec = 0;
+	et.tm_sec = 0;
+	et.tm_min = 0;
+	et.tm_hour = 0;
+	et.tm_mday = 1;
+	et.tm_month = 0;
+	et.tm_year = 2005;
+	et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 0;
+	usecs = PR_ImplodeTime(&et);
+
+        for (day = 0; day < 4 * 365 + 1; day++) {
+	    for (hour = 0; hour < 24; hour++) {
+		for (min = 0; min < 60; min += 10) {
+	            LL_ADD(usecs, usecs, usecPer10Min);
+		    PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1);
+
+		    et2 = et;
+		    et2.tm_usec += 600000000L;
+		    PR_NormalizeTime(&et2, PR_USPacificTimeParameters);
+
+		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
+			printf("ERROR: componentwise comparison failed\n");
+			PrintExplodedTime(&et1);
+			printf("\n");
+			PrintExplodedTime(&et2);
+			printf("\n");
+			failed_already=1;
+		        return 1;
+		    }
+
+		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) { 
+			printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
+			PrintExplodedTime(&et1);
+			printf("\n");
+			failed_already=1;
+		        return 1;
+		    }
+		    testParseTimeString(usecs);
+
+		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 1;
+		        if (debug_mode) {
+			    printf("DST changeover from ");
+			    PrintExplodedTime(&et);
+			    printf(" to ");
+			    PrintExplodedTime(&et1);
+			    printf(".\n");
+		    	}
+                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 0;
+			if (debug_mode) {
+			    printf("DST changeover from ");
+			    PrintExplodedTime(&et);
+			    printf(" to ");
+			    PrintExplodedTime(&et1);
+			    printf(".\n");
+			}
+                    }
+
+		    et = et1;
+		}
+	    }
+        }
+	if (debug_mode) printf("Test passed\n");
+    }
+
+
+    /* Same stress test, but with PR_LocalTimeParameters */
+
+    {
+	PRExplodedTime et, et1, et2;
+	PRInt64 usecPer10Min;
+	int day, hour, min;
+	PRTime usecs;
+	int dstInEffect = 0;
+
+	if (debug_mode) {
+	printf("\n");
+	printf("*******************************************************\n");
+	printf("**                                                   **\n");
+	printf("**         Stress test    Local Time                 **\n");
+	printf("**  Starting from midnight Jan. 1, 2005 PST,         **\n");
+	printf("**  going through four years in 10-minute increment  **\n");
+	printf("**                                                   **\n");
+	printf("*******************************************************\n\n");
+	}
+	
+	LL_I2L(usecPer10Min, 600000000L);
+
+	/* 00:00:00 PST Jan. 1, 2005 */
+	et.tm_usec = 0;
+	et.tm_sec = 0;
+	et.tm_min = 0;
+	et.tm_hour = 0;
+	et.tm_mday = 1;
+	et.tm_month = 0;
+	et.tm_year = 2005;
+	et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 0;
+	usecs = PR_ImplodeTime(&et);
+
+        for (day = 0; day < 4 * 365 + 1; day++) {
+	    for (hour = 0; hour < 24; hour++) {
+		for (min = 0; min < 60; min += 10) {
+	            LL_ADD(usecs, usecs, usecPer10Min);
+		    PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
+
+		    et2 = et;
+		    et2.tm_usec += 600000000L;
+		    PR_NormalizeTime(&et2, PR_LocalTimeParameters);
+
+		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
+			printf("ERROR: componentwise comparison failed\n");
+			PrintExplodedTime(&et1);
+			printf("\n");
+			PrintExplodedTime(&et2);
+			printf("\n");
+		        return 1;
+		    }
+
+		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
+                        printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
+			PrintExplodedTime(&et1);
+			printf("\n");
+			failed_already=1;
+		        return 1;
+		    }
+		    testParseTimeString(usecs);
+
+		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 1;
+		        if (debug_mode) {
+			    printf("DST changeover from ");
+			    PrintExplodedTime(&et);
+			    printf(" to ");
+			    PrintExplodedTime(&et1);
+			    printf(".\n");
+			}
+                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 0;
+			if (debug_mode) {
+			    printf("DST changeover from ");
+			    PrintExplodedTime(&et);
+			    printf(" to ");
+			    PrintExplodedTime(&et1);
+			    printf(".\n");
+			}
+                    }
+
+		    et = et1;
+		}
+	    }
+        }
+	if (debug_mode) printf("Test passed\n");
+    }
+
+    /* Same stress test, but with PR_LocalTimeParameters and going backward */
+
+    {
+	PRExplodedTime et, et1, et2;
+	PRInt64 usecPer10Min;
+	int day, hour, min;
+	PRTime usecs;
+	int dstInEffect = 0;
+
+	if (debug_mode) {
+	printf("\n");
+	printf("*******************************************************\n");
+	printf("**                                                   **\n");
+	printf("**           Stress test    Local Time               **\n");
+	printf("**  Starting from midnight Jan. 1, 2009 PST,         **\n");
+	printf("**  going back four years in 10-minute increment     **\n");
+	printf("**                                                   **\n");
+	printf("*******************************************************\n\n");
+	}
+
+	LL_I2L(usecPer10Min, 600000000L);
+
+	/* 00:00:00 PST Jan. 1, 2009 */
+	et.tm_usec = 0;
+	et.tm_sec = 0;
+	et.tm_min = 0;
+	et.tm_hour = 0;
+	et.tm_mday = 1;
+	et.tm_month = 0;
+	et.tm_year = 2009;
+	et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 0;
+	usecs = PR_ImplodeTime(&et);
+
+        for (day = 0; day < 4 * 365 + 1; day++) {
+	    for (hour = 0; hour < 24; hour++) {
+		for (min = 0; min < 60; min += 10) {
+	            LL_SUB(usecs, usecs, usecPer10Min);
+		    PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
+
+		    et2 = et;
+		    et2.tm_usec -= 600000000L;
+		    PR_NormalizeTime(&et2, PR_LocalTimeParameters);
+
+		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
+		        printf("ERROR: componentwise comparison failed\n");
+			PrintExplodedTime(&et1);
+			printf("\n");
+			PrintExplodedTime(&et2);
+			printf("\n");
+		        return 1;
+		    }
+
+		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
+			printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
+			PrintExplodedTime(&et1);
+			printf("\n");
+			failed_already=1;
+		        return 1;
+		    }
+		    testParseTimeString(usecs);
+
+		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 1;
+		        if (debug_mode) {
+			    printf("DST changeover from ");
+			    PrintExplodedTime(&et);
+			    printf(" to ");
+			    PrintExplodedTime(&et1);
+			    printf(".\n");
+			}
+                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 0;
+			if (debug_mode) {
+			    printf("DST changeover from ");
+			    PrintExplodedTime(&et);
+			    printf(" to ");
+			    PrintExplodedTime(&et1);
+			    printf(".\n");
+			}
+                    }
+
+		    et = et1;
+		}
+	    }
+        }
+    }
+
+	if (failed_already) return 1;
+	else return 0;
+
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/tmoacc.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/tmoacc.c
new file mode 100644
index 0000000..7ea6f0a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/tmoacc.c
@@ -0,0 +1,328 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#define BASE_PORT 9867
+#define DEFAULT_THREADS 1
+#define DEFAULT_BACKLOG 10
+#define DEFAULT_TIMEOUT 10
+#define RANDOM_RANGE 100  /* should be significantly smaller than RAND_MAX */
+
+typedef enum {running, stopped} Status;
+
+typedef struct Shared
+{
+    PRLock *ml;
+    PRCondVar *cv;
+    PRBool passed;
+    PRBool random;
+    PRFileDesc *debug;
+    PRIntervalTime timeout;
+    PRFileDesc *listenSock;
+    Status status;
+} Shared;
+
+static PRIntervalTime Timeout(const Shared *shared)
+{
+    PRIntervalTime timeout = shared->timeout;
+    if (shared->random)
+    {
+        PRIntervalTime half = timeout >> 1;  /* one half of the interval */
+        PRIntervalTime quarter = half >> 1;  /* one quarter of the interval */
+        /* something in [0..timeout / 2) */
+        PRUint32 random = (rand() % RANDOM_RANGE) * half / RANDOM_RANGE;
+        timeout = (3 * quarter) + random;  /* [75..125)% */
+    }
+    return timeout;
+}  /* Timeout */
+
+static void Accept(void *arg)
+{
+    PRStatus rv;
+    char *buffer = NULL;
+    PRNetAddr clientAddr;
+    Shared *shared = (Shared*)arg;
+    PRInt32 recv_length = 0, flags = 0;
+    PRFileDesc *clientSock;
+    PRIntn toread, byte, bytes, loop = 0;
+    struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor;
+
+    do
+    {
+        PRUint32 checksum = 0;
+        if (NULL != shared->debug)
+            PR_fprintf(shared->debug, "[%d]accepting ... ", loop++);
+        clientSock = PR_Accept(
+            shared->listenSock, &clientAddr, Timeout(shared));
+        if (clientSock != NULL)
+        {
+            if (NULL != shared->debug)
+                PR_fprintf(shared->debug, "reading length ... ");
+            bytes = PR_Recv(
+                clientSock, &descriptor, sizeof(descriptor),
+                flags, Timeout(shared));
+            if (sizeof(descriptor) == bytes)
+            {
+                /* and, before doing something stupid ... */
+                descriptor.length = PR_ntohl(descriptor.length);
+                descriptor.checksum = PR_ntohl(descriptor.checksum);
+                if (NULL != shared->debug)
+                    PR_fprintf(shared->debug, "%d bytes ... ", descriptor.length);
+                toread = descriptor.length;
+                if (recv_length < descriptor.length)
+                {
+                    if (NULL != buffer) PR_DELETE(buffer);
+                    buffer = (char*)PR_MALLOC(descriptor.length);
+                    recv_length = descriptor.length;
+                }
+                for (toread = descriptor.length; toread > 0; toread -= bytes)
+                {
+                    bytes = PR_Recv(
+                        clientSock, &buffer[descriptor.length - toread],
+                        toread, flags, Timeout(shared));
+                    if (-1 == bytes)
+                    {
+                        if (NULL != shared->debug)
+                            PR_fprintf(shared->debug, "read data failed...");
+                        bytes = 0;
+                    }
+                }
+            }
+            else if (NULL != shared->debug)
+            {
+                PR_fprintf(shared->debug, "read desciptor failed...");
+                descriptor.length = -1;
+            }
+            if (NULL != shared->debug)
+                PR_fprintf(shared->debug, "closing");
+            rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH);
+            if ((PR_FAILURE == rv) && (NULL != shared->debug))
+            {
+                PR_fprintf(shared->debug, " failed");
+                shared->passed = PR_FALSE;
+            }
+            rv = PR_Close(clientSock);
+            if (PR_FAILURE == rv) if (NULL != shared->debug)
+            {
+                PR_fprintf(shared->debug, " failed");
+                shared->passed = PR_FALSE;
+            }
+            if (descriptor.length > 0)
+            {
+                for (byte = 0; byte < descriptor.length; ++byte)
+                {
+                    PRUint32 overflow = checksum & 0x80000000;
+                    checksum = (checksum << 1);
+                    if (0x00000000 != overflow) checksum += 1;
+                    checksum += buffer[byte];
+                }
+                if ((descriptor.checksum != checksum) && (NULL != shared->debug))
+                {
+                    PR_fprintf(shared->debug, " ... data mismatch");
+                    shared->passed = PR_FALSE;
+                }
+            }
+            else if (0 == descriptor.length)
+            {
+                PR_Lock(shared->ml);
+                shared->status = stopped;
+                PR_NotifyCondVar(shared->cv);
+                PR_Unlock(shared->ml);
+            }
+            if (NULL != shared->debug)
+                PR_fprintf(shared->debug, "\n");
+        }
+        else
+        {
+            if (PR_PENDING_INTERRUPT_ERROR != PR_GetError())
+            {
+                if (NULL != shared->debug) PL_PrintError("Accept");
+                shared->passed = PR_FALSE;
+            }
+        }        
+    } while (running == shared->status);
+    if (NULL != buffer) PR_DELETE(buffer);
+}  /* Accept */
+
+PRIntn Tmoacc(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PRIntn exitStatus;
+    PRIntn index;
+	Shared *shared;
+	PLOptStatus os;
+	PRThread **thread;
+    PRNetAddr listenAddr;
+    PRSocketOptionData sockOpt;
+    PRIntn timeout = DEFAULT_TIMEOUT;
+    PRIntn threads = DEFAULT_THREADS;
+    PRIntn backlog = DEFAULT_BACKLOG;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dGb:t:T:R");
+
+    shared = PR_NEWZAP(Shared);
+
+    shared->debug = NULL;
+    shared->passed = PR_TRUE;
+    shared->random = PR_TRUE;
+    shared->status = running;
+    shared->ml = PR_NewLock();
+    shared->cv = PR_NewCondVar(shared->ml);
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            shared->debug = PR_GetSpecialFD(PR_StandardError);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'b':  /* size of listen backlog */
+            backlog = atoi(opt->value);
+            break;
+        case 't':  /* number of threads doing accept */
+            threads = atoi(opt->value);
+            break;
+        case 'T':  /* timeout used for network operations */
+            timeout = atoi(opt->value);
+            break;
+        case 'R':  /* randomize the timeout values */
+            shared->random = PR_TRUE;
+            break;
+        default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+    if (0 == threads) threads = DEFAULT_THREADS;
+    if (0 == backlog) backlog = DEFAULT_BACKLOG;
+    if (0 == timeout) timeout = DEFAULT_TIMEOUT;
+    
+    PR_STDIO_INIT();
+    memset(&listenAddr, 0, sizeof(listenAddr));
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    shared->timeout = PR_SecondsToInterval(timeout);
+
+    /* First bind to the socket */
+    shared->listenSock = PR_NewTCPSocket();
+    if (shared->listenSock)
+    {
+        sockOpt.option = PR_SockOpt_Reuseaddr;
+        sockOpt.value.reuse_addr = PR_TRUE;
+        rv = PR_SetSocketOption(shared->listenSock, &sockOpt);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(shared->listenSock, &listenAddr);
+        if (rv != PR_FAILURE)
+        {
+            rv = PR_Listen(shared->listenSock, threads + backlog);
+            if (PR_SUCCESS == rv)
+            {
+                thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*));
+                for (index = 0; index < threads; ++index)
+                {
+                    thread[index] = PR_CreateThread(
+                        PR_USER_THREAD, Accept, shared,
+                        PR_PRIORITY_NORMAL, thread_scope,
+                        PR_JOINABLE_THREAD, 0);
+                    PR_ASSERT(NULL != thread[index]);
+                }
+
+                PR_Lock(shared->ml);
+                while (shared->status == running)
+                    PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT);
+                PR_Unlock(shared->ml);
+                for (index = 0; index < threads; ++index)
+                {
+                    rv = PR_Interrupt(thread[index]);
+                    PR_ASSERT(PR_SUCCESS== rv);
+                    rv = PR_JoinThread(thread[index]);
+                    PR_ASSERT(PR_SUCCESS== rv);
+                }
+                PR_DELETE(thread);
+            }
+            else
+            {
+                if (shared->debug) PL_PrintError("Listen");
+                shared->passed = PR_FALSE;
+            }
+        }
+        else
+        {
+            if (shared->debug) PL_PrintError("Bind");
+            shared->passed = PR_FALSE;
+        }
+
+        PR_Close(shared->listenSock);
+    }
+    else
+    {
+        if (shared->debug) PL_PrintError("Create");
+        shared->passed = PR_FALSE;
+    }
+
+    PR_DestroyCondVar(shared->cv);
+    PR_DestroyLock(shared->ml);
+
+    PR_fprintf(
+        PR_GetSpecialFD(PR_StandardError), "%s\n",
+        ((shared->passed) ? "PASSED" : "FAILED"));
+
+    exitStatus = (shared->passed) ? 0 : 1;
+    PR_DELETE(shared);
+    return exitStatus;
+}
+
+int main(int argc, char **argv)
+{
+    return (PR_VersionCheck(PR_VERSION)) ?
+        PR_Initialize(Tmoacc, argc, argv, 4) : -1;
+}  /* main */
+
+/* tmoacc */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/tmocon.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/tmocon.c
new file mode 100644
index 0000000..454adcb
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/tmocon.c
@@ -0,0 +1,410 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+**
+** Name: tmocon.c
+**
+** Description: test client socket connection.
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+**	         The debug mode will print all of the printfs associated with this test.
+**			 The regress mode will be the default mode. Since the regress tool limits
+**           the output to a one line status:PASS or FAIL,all of the printf statements
+**			 have been handled with an if (debug_mode) statement. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprio.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* for getcwd */
+#if defined(XP_UNIX) || defined (XP_OS2) || defined(XP_BEOS)
+#include <unistd.h>
+#elif defined(XP_PC)
+#include <direct.h>
+#endif
+
+#ifdef WINCE
+#include <windows.h>
+char *getcwd(char *buf, size_t size)
+{
+    wchar_t wpath[MAX_PATH];
+    _wgetcwd(wpath, MAX_PATH);
+    WideCharToMultiByte(CP_ACP, 0, wpath, -1, buf, size, 0, 0);
+}
+#endif
+
+#define BASE_PORT 9867
+
+#define DEFAULT_DALLY 1
+#define DEFAULT_THREADS 1
+#define DEFAULT_TIMEOUT 10
+#define DEFAULT_MESSAGES 100
+#define DEFAULT_MESSAGESIZE 100
+
+static PRFileDesc *debug_out = NULL;
+
+typedef struct Shared
+{
+    PRBool random;
+    PRBool failed;
+    PRBool intermittant;
+    PRIntn debug;
+    PRInt32 messages;
+    PRIntervalTime dally;
+    PRIntervalTime timeout;
+    PRInt32 message_length;
+    PRNetAddr serverAddress;
+} Shared;
+
+static PRIntervalTime Timeout(const Shared *shared)
+{
+    PRIntervalTime timeout = shared->timeout;
+    if (shared->random)
+    {
+        PRIntervalTime quarter = timeout >> 2;  /* one quarter of the interval */
+        PRUint32 random = rand() % quarter;  /* something in[0..timeout / 4) */
+        timeout = (((3 * quarter) + random) >> 2) + quarter;  /* [75..125)% */
+    }
+    return timeout;
+}  /* Timeout */
+
+static void CauseTimeout(const Shared *shared)
+{
+    if (shared->intermittant) PR_Sleep(Timeout(shared));
+}  /* CauseTimeout */
+
+static PRStatus MakeReceiver(Shared *shared)
+{
+    PRStatus rv = PR_FAILURE;
+    if (PR_IsNetAddrType(&shared->serverAddress, PR_IpAddrLoopback))
+    {
+        char *argv[3];
+        char path[1024 + sizeof("/tmoacc")];
+
+        getcwd(path, sizeof(path));
+
+        (void)strcat(path, "/tmoacc");
+#ifdef XP_PC
+        (void)strcat(path, ".exe");
+#endif
+        argv[0] = path;
+        if (shared->debug > 0)
+        {
+            argv[1] = "-d";
+            argv[2] = NULL;
+        }
+        else argv[1] = NULL;
+        if (shared->debug > 1)
+            PR_fprintf(debug_out, " creating accept process %s ...", path);
+        fflush(stdout);
+        rv = PR_CreateProcessDetached(path, argv, NULL, NULL);
+        if (PR_SUCCESS == rv)
+        {
+            if (shared->debug > 1)
+                PR_fprintf(debug_out, " wait 5 seconds");
+            if (shared->debug > 1)
+                PR_fprintf(debug_out, " before connecting to accept process ...");
+            fflush(stdout);
+            PR_Sleep(PR_SecondsToInterval(5));
+            return rv;
+        }
+        shared->failed = PR_TRUE;
+        if (shared->debug > 0)
+            PL_FPrintError(debug_out, "PR_CreateProcessDetached failed");
+    }
+    return rv;
+}  /* MakeReceiver */
+
+static void Connect(void *arg)
+{
+    PRStatus rv;
+    char *buffer = NULL;
+    PRFileDesc *clientSock;
+    Shared *shared = (Shared*)arg;
+    PRInt32 loop, bytes, flags = 0;
+    struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor;
+    debug_out = (0 == shared->debug) ? NULL : PR_GetSpecialFD(PR_StandardError);
+
+    buffer = (char*)PR_MALLOC(shared->message_length);
+
+    for (bytes = 0; bytes < shared->message_length; ++bytes)
+        buffer[bytes] = (char)bytes;
+
+    descriptor.checksum = 0;
+    for (bytes = 0; bytes < shared->message_length; ++bytes)
+    {
+        PRUint32 overflow = descriptor.checksum & 0x80000000;
+        descriptor.checksum = (descriptor.checksum << 1);
+        if (0x00000000 != overflow) descriptor.checksum += 1;
+        descriptor.checksum += buffer[bytes];
+    }
+    descriptor.checksum = PR_htonl(descriptor.checksum);
+
+    for (loop = 0; loop < shared->messages; ++loop)
+    {
+        if (shared->debug > 1)
+            PR_fprintf(debug_out, "[%d]socket ... ", loop);
+        clientSock = PR_NewTCPSocket();
+        if (clientSock)
+        {
+            /*
+             * We need to slow down the rate of generating connect requests,
+             * otherwise the listen backlog queue on the accept side may
+             * become full and we will get connection refused or timeout
+             * error.
+             */
+
+            PR_Sleep(shared->dally);
+            if (shared->debug > 1)
+            {
+                char buf[128];
+                PR_NetAddrToString(&shared->serverAddress, buf, sizeof(buf));
+                PR_fprintf(debug_out, "connecting to %s ... ", buf);
+            }
+            rv = PR_Connect(
+                clientSock, &shared->serverAddress, Timeout(shared));
+            if (PR_SUCCESS == rv)
+            {
+                PRInt32 descriptor_length = (loop < (shared->messages - 1)) ?
+                    shared->message_length : 0;
+                descriptor.length = PR_htonl(descriptor_length);
+                if (shared->debug > 1)
+                    PR_fprintf(
+                        debug_out, "sending %d bytes ... ", descriptor_length);
+                CauseTimeout(shared);  /* might cause server to timeout */
+                bytes = PR_Send(
+                    clientSock, &descriptor, sizeof(descriptor),
+                    flags, Timeout(shared));
+                if (bytes != sizeof(descriptor))
+                {
+                    shared->failed = PR_TRUE;
+                    if (shared->debug > 0)
+                        PL_FPrintError(debug_out, "PR_Send failed");
+                }
+                if (0 != descriptor_length)
+                {
+                    CauseTimeout(shared);
+                    bytes = PR_Send(
+                        clientSock, buffer, descriptor_length,
+                        flags, Timeout(shared));
+                    if (bytes != descriptor_length)
+                    {
+                        shared->failed = PR_TRUE;
+                        if (shared->debug > 0)
+                            PL_FPrintError(debug_out, "PR_Send failed");
+                    }
+                }
+                if (shared->debug > 1) PR_fprintf(debug_out, "closing ... ");
+                rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH);
+                rv = PR_Close(clientSock);
+                if (shared->debug > 1)
+                {
+                    if (PR_SUCCESS == rv) PR_fprintf(debug_out, "\n");
+                    else PL_FPrintError(debug_out, "shutdown failed");
+                }
+            }
+            else
+            {
+                if (shared->debug > 1) PL_FPrintError(debug_out, "connect failed");
+                PR_Close(clientSock);
+                if ((loop == 0) && (PR_GetError() == PR_CONNECT_REFUSED_ERROR))
+                {
+                    if (MakeReceiver(shared) == PR_FAILURE) break;
+                }
+                else
+                {
+                    if (shared->debug > 1) PR_fprintf(debug_out, " exiting\n");
+                    break;
+                }
+            }
+        }
+        else
+        {
+            shared->failed = PR_TRUE;
+            if (shared->debug > 0) PL_FPrintError(debug_out, "create socket");
+            break;
+        }
+    }
+
+    PR_DELETE(buffer);
+}  /* Connect */
+
+int Tmocon(int argc, char **argv)
+{
+    /*
+     * USAGE
+     * -d       turn on debugging output                (default = off)
+     * -v       turn on verbose output                  (default = off)
+     * -h <n>   dns name of host serving the connection (default = self)
+     * -i       dally intermittantly to cause timeouts  (default = off)
+     * -m <n>   number of messages to send              (default = 100)
+     * -s <n>   size of each message                    (default = 100)
+     * -t <n>   number of threads sending               (default = 1)
+     * -G       use global threads                      (default = local)
+     * -T <n>   timeout on I/O operations (seconds)     (default = 10)
+     * -D <n>   dally between connect requests (seconds)(default = 0)
+     * -R       randomize the dally types around 'T'    (default = no)
+     */
+
+    PRStatus rv;
+    int exitStatus;
+    PLOptStatus os;
+    Shared *shared = NULL;
+    PRThread **thread = NULL;
+    PRIntn index, threads = DEFAULT_THREADS;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRInt32 dally = DEFAULT_DALLY, timeout = DEFAULT_TIMEOUT;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "divGRh:m:s:t:T:D:");
+
+    shared = PR_NEWZAP(Shared);
+
+    shared->debug = 0;
+    shared->failed = PR_FALSE;
+    shared->random = PR_FALSE;
+    shared->messages = DEFAULT_MESSAGES;
+    shared->message_length = DEFAULT_MESSAGESIZE;
+
+    PR_STDIO_INIT();
+    memset(&shared->serverAddress, 0, sizeof(shared->serverAddress));
+    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &shared->serverAddress);
+    PR_ASSERT(PR_SUCCESS == rv);
+    
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':
+            if (0 == shared->debug) shared->debug = 1;
+            break;
+        case 'v':
+            if (0 == shared->debug) shared->debug = 2;
+            break;
+        case 'i':
+            shared->intermittant = PR_TRUE;
+            break;
+        case 'R':
+            shared->random = PR_TRUE;
+            break;
+        case 'G':
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'h':  /* the value for backlock */
+            {
+                PRIntn es = 0;
+                PRHostEnt host;
+                char buffer[1024];
+                (void)PR_GetHostByName(
+                    opt->value, buffer, sizeof(buffer), &host);
+                es = PR_EnumerateHostEnt(
+                    es, &host, BASE_PORT, &shared->serverAddress);
+                PR_ASSERT(es > 0);
+            }
+            break;
+        case 'm':  /* number of messages to send */
+            shared->messages = atoi(opt->value);
+            break;
+        case 't':  /* number of threads sending */
+            threads = atoi(opt->value);
+            break;
+        case 'D':  /* dally time between transmissions */
+            dally = atoi(opt->value);
+            break;
+        case 'T':  /* timeout on I/O operations */
+            timeout = atoi(opt->value);
+            break;
+        case 's':  /* total size of each message */
+            shared->message_length = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+        PL_DestroyOptState(opt);
+
+    if (0 == timeout) timeout = DEFAULT_TIMEOUT;
+    if (0 == threads) threads = DEFAULT_THREADS;
+    if (0 == shared->messages) shared->messages = DEFAULT_MESSAGES;
+    if (0 == shared->message_length) shared->message_length = DEFAULT_MESSAGESIZE;
+
+    shared->dally = PR_SecondsToInterval(dally);
+    shared->timeout = PR_SecondsToInterval(timeout);
+
+    thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*));
+
+    for (index = 0; index < threads; ++index)
+        thread[index] = PR_CreateThread(
+            PR_USER_THREAD, Connect, shared,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 0);
+    for (index = 0; index < threads; ++index)
+        rv = PR_JoinThread(thread[index]);
+
+    PR_DELETE(thread);
+
+    PR_fprintf(
+        PR_GetSpecialFD(PR_StandardError), "%s\n",
+        ((shared->failed) ? "FAILED" : "PASSED"));
+    exitStatus = (shared->failed) ? 1 : 0;
+    PR_DELETE(shared);
+    return exitStatus;
+}
+
+int main(int argc, char **argv)
+{
+    return (PR_VersionCheck(PR_VERSION)) ?
+        PR_Initialize(Tmocon, argc, argv, 4) : -1;
+}  /* main */
+
+/* tmocon.c */
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/tpd.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/tpd.c
new file mode 100644
index 0000000..4cbce5a
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/tpd.c
@@ -0,0 +1,330 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:        tpd.c
+** Description: Exercising the thread private data bailywick.
+*/
+
+#include "prmem.h"
+#include "prinit.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#include "private/pprio.h"
+
+#include "plgetopt.h"
+
+static PRUintn key[128];
+static PRIntn debug = 0;
+static PRBool failed = PR_FALSE;
+static PRBool should = PR_TRUE;
+static PRBool did = PR_TRUE;
+static PRFileDesc *fout = NULL;
+
+static void PrintProgress(PRIntn line)
+{
+    failed = failed || (should && !did);
+    failed = failed || (!should && did);
+    if (debug > 0)
+    {
+#if defined(WIN16)
+        printf(
+            "@ line %d destructor should%s have been called and was%s\n",
+            line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
+#else    
+        PR_fprintf(
+            fout, "@ line %d destructor should%s have been called and was%s\n",
+            line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
+#endif
+    }
+}  /* PrintProgress */
+
+static void MyAssert(const char *expr, const char *file, PRIntn line)
+{
+    if (debug > 0)
+        (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
+}  /* MyAssert */
+
+#define MY_ASSERT(_expr) \
+    ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__))
+
+
+static void PR_CALLBACK Destructor(void *data)
+{
+    MY_ASSERT(NULL != data);
+    if (should) did = PR_TRUE;
+    else failed = PR_TRUE;
+    /*
+     * We don't actually free the storage since it's actually allocated
+     * on the stack. Normally, this would not be the case and this is
+     * the opportunity to free whatever.
+    PR_Free(data);
+     */
+}  /* Destructor */
+
+static void PR_CALLBACK Thread(void *null)
+{
+    void *pd;
+    PRStatus rv;
+    PRUintn keys;
+    char *key_string[] = {
+        "Key #0", "Key #1", "Key #2", "Key #3",
+        "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
+    
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 8; ++keys)
+    {
+        pd = PR_GetThreadPrivate(key[keys]);
+        MY_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 4; keys < 8; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_FAILURE == rv);
+    }
+    PrintProgress(__LINE__);
+    
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], "EXTENSION");
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+
+    /* put in keys and leave them there for thread exit */
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+    did = PR_FALSE; should = PR_TRUE;
+
+}  /* Thread */
+
+static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv)
+{
+    void *pd;
+    PRStatus rv;
+    PRUintn keys;
+    PRThread *thread;
+    char *key_string[] = {
+        "Key #0", "Key #1", "Key #2", "Key #3",
+        "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
+    
+    fout = PR_STDOUT;
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_NewThreadPrivateIndex(&key[keys], Destructor);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 8; ++keys)
+    {
+        pd = PR_GetThreadPrivate(key[keys]);
+        MY_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    for (keys = 4; keys < 8; ++keys)
+		key[keys] = 4096;		/* set to invalid value */
+    did = should = PR_FALSE;
+    for (keys = 4; keys < 8; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_FAILURE == rv);
+    }
+    PrintProgress(__LINE__);
+    
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_NewThreadPrivateIndex(&key[keys], Destructor);
+        MY_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetThreadPrivate(key[keys], "EXTENSION");
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+
+    thread = PR_CreateThread(
+        PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    (void)PR_JoinThread(thread);
+
+    PrintProgress(__LINE__);
+
+#if defined(WIN16)
+    printf(
+        "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
+#else
+    (void)PR_fprintf(
+        fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
+#endif    
+
+    return 0;
+
+}  /* Tpd */
+
+int main(int argc, char **argv)
+{
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dl:r:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+    return PR_Initialize(Tpd, argc, argv, 0);
+}  /* main */
+
+/* tpd.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/udpsrv.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/udpsrv.c
new file mode 100644
index 0000000..bf497a9
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/udpsrv.c
@@ -0,0 +1,562 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*******************************************************************
+** udpsrc.c -- Test basic function of UDP server
+**
+** udpsrv operates on the same machine with program udpclt.
+** udpsrv is the server side of a udp sockets application.
+** udpclt is the client side of a udp sockets application.
+**
+** The test is designed to assist developers in porting/debugging
+** the UDP socket functions of NSPR.
+**
+** This test is not a stress test.
+**
+** main() starts two threads: UDP_Server() and UDP_Client();
+** main() uses PR_JoinThread() to wait for the threads to complete.
+**
+** UDP_Server() does repeated recvfrom()s from a socket.
+** He detects an EOF condition set by UDP_Client(). For each
+** packet received by UDP_Server(), he checks its content for
+** expected content, then sends the packet back to UDP_Client().
+** 
+** UDP_Client() sends packets to UDP_Server() using sendto()
+** he recieves packets back from the server via recvfrom().
+** After he sends enough packets containing UDP_AMOUNT_TO_WRITE
+** bytes of data, he sends an EOF message.
+** 
+** The test issues a pass/fail message at end.
+** 
+** Notes:
+** The variable "_debug_on" can be set to 1 to cause diagnostic
+** messages related to client/server synchronization. Useful when
+** the test hangs.
+** 
+** Error messages are written to stdout.
+** 
+********************************************************************
+*/
+/* --- include files --- */
+#include "nspr.h"
+#include "prpriv.h"
+
+#include "plgetopt.h"
+#include "prttools.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef XP_PC
+#define mode_t int
+#endif
+
+#define UDP_BUF_SIZE            4096
+#define UDP_DGRAM_SIZE          128
+#define UDP_AMOUNT_TO_WRITE     (PRInt32)((UDP_DGRAM_SIZE * 1000l) +1)
+#define NUM_UDP_CLIENTS         1
+#define NUM_UDP_DATAGRAMS_PER_CLIENT    5
+#define UDP_SERVER_PORT         9050
+#define UDP_CLIENT_PORT         9053
+#define MY_INADDR               PR_INADDR_ANY
+#define PEER_INADDR             PR_INADDR_LOOPBACK
+
+#define UDP_TIMEOUT             400000
+/* #define UDP_TIMEOUT             PR_INTERVAL_NO_TIMEOUT */
+
+/* --- static data --- */
+static PRIntn _debug_on      = 0;
+static PRBool passed         = PR_TRUE;
+static PRUint32 cltBytesRead = 0;
+static PRUint32 srvBytesRead = 0;
+static PRFileDesc *output    = NULL;
+
+/* --- static function declarations --- */
+#define DPRINTF(arg) if (_debug_on) PR_fprintf(output, arg)
+
+
+
+/*******************************************************************
+** ListNetAddr() -- Display the Net Address on stdout
+**
+** Description: displays the component parts of a PRNetAddr struct
+**
+** Arguments:   address of PRNetAddr structure to display
+**
+** Returns: void
+**
+** Notes:
+**
+********************************************************************
+*/
+void ListNetAddr( char *msg, PRNetAddr *na )
+{
+    char    mbuf[256];
+    
+    sprintf( mbuf, "ListNetAddr: %s family: %d, port: %d, ip: %8.8X\n",
+            msg, na->inet.family, PR_ntohs( na->inet.port), PR_ntohl(na->inet.ip) );
+#if 0            
+    DPRINTF( mbuf );            
+#endif
+} /* --- end ListNetAddr() --- */
+
+/********************************************************************
+** UDP_Server() -- Test a UDP server application
+**
+** Description: The Server side of a UDP Client/Server application.
+**
+** Arguments: none
+**
+** Returns: void
+**
+** Notes:
+**
+**
+********************************************************************
+*/
+static void PR_CALLBACK UDP_Server( void *arg )
+{
+    static char     svrBuf[UDP_BUF_SIZE];
+    PRFileDesc      *svrSock;
+    PRInt32         rv;
+    PRNetAddr       netaddr;
+    PRBool          bound = PR_FALSE;
+    PRBool          endOfInput = PR_FALSE;
+    PRInt32         numBytes = UDP_DGRAM_SIZE;
+    
+    DPRINTF("udpsrv: UDP_Server(): starting\n" );
+
+    /* --- Create the socket --- */
+    DPRINTF("udpsrv: UDP_Server(): Creating UDP Socket\n" );
+    svrSock = PR_NewUDPSocket();
+    if ( svrSock == NULL )
+    {
+        passed = PR_FALSE;
+        if (debug_mode)
+            PR_fprintf(output,
+                "udpsrv: UDP_Server(): PR_NewUDPSocket() returned NULL\n" );
+        return;
+    }
+    
+    /* --- Initialize the sockaddr_in structure --- */
+    memset( &netaddr, 0, sizeof( netaddr )); 
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.port   = PR_htons( UDP_SERVER_PORT );
+    netaddr.inet.ip     = PR_htonl( MY_INADDR );
+    
+    /* --- Bind the socket --- */
+    while ( !bound )
+    {
+        DPRINTF("udpsrv: UDP_Server(): Binding socket\n" );
+        rv = PR_Bind( svrSock, &netaddr );
+        if ( rv < 0 )
+        {
+            if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
+            {
+                if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \
+						PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
+                PR_Sleep( PR_MillisecondsToInterval( 2000 ));
+                continue;
+            }
+            else
+            {
+                passed = PR_FALSE;
+                if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \
+						PR_Bind(): failed: %ld with error: %ld\n",
+                        rv, PR_GetError() );
+                PR_Close( svrSock );
+                return;
+            }
+        }
+        else
+            bound = PR_TRUE;
+    }
+    ListNetAddr( "UDP_Server: after bind", &netaddr );
+    
+    /* --- Recv the socket --- */
+    while( !endOfInput )
+    {
+        DPRINTF("udpsrv: UDP_Server(): RecvFrom() socket\n" );
+        rv = PR_RecvFrom( svrSock, svrBuf, numBytes, 0, &netaddr, UDP_TIMEOUT );
+        if ( rv == -1 )
+        {
+            passed = PR_FALSE;
+            if (debug_mode)
+                PR_fprintf(output,
+                    "udpsrv: UDP_Server(): PR_RecvFrom(): failed with error: %ld\n",
+                    PR_GetError() );
+            PR_Close( svrSock );
+            return;
+        }
+        ListNetAddr( "UDP_Server after RecvFrom", &netaddr );
+        
+        srvBytesRead += rv;
+        
+        if ( svrBuf[0] == 'E' )
+        {
+            DPRINTF("udpsrv: UDP_Server(): EOF on input detected\n" );
+            endOfInput = PR_TRUE;
+        }
+            
+        /* --- Send the socket --- */
+        DPRINTF("udpsrv: UDP_Server(): SendTo(): socket\n" );
+        rv = PR_SendTo( svrSock, svrBuf, rv, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT );
+        if ( rv == -1 )
+        {
+            passed = PR_FALSE;
+            if (debug_mode)
+                PR_fprintf(output,
+                    "udpsrv: UDP_Server(): PR_SendTo(): failed with error: %ld\n",
+                    PR_GetError() );
+            PR_Close( svrSock );
+            return;
+        }
+        ListNetAddr( "UDP_Server after SendTo", &netaddr );
+    }
+    
+    /* --- Close the socket --- */
+    DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
+    rv = PR_Close( svrSock );
+    if ( rv != PR_SUCCESS )
+    {
+        passed = PR_FALSE;
+        if (debug_mode)
+            PR_fprintf(output,
+                "udpsrv: UDP_Server(): PR_Close(): failed to close socket\n" );
+        return;
+    }
+    
+    DPRINTF("udpsrv: UDP_Server(): Normal end\n" );
+} /* --- end UDP_Server() --- */
+
+
+static char         cltBuf[UDP_BUF_SIZE];
+static char         cltBufin[UDP_BUF_SIZE];
+/********************************************************************
+** UDP_Client() -- Test a UDP client application
+**
+** Description:
+**
+** Arguments:
+**
+**
+** Returns:
+** 0 -- Successful execution
+** 1 -- Test failed.
+**
+** Notes:
+**
+**
+********************************************************************
+*/
+static void PR_CALLBACK UDP_Client( void *arg )
+{
+    PRFileDesc   *cltSock;
+    PRInt32      rv;
+    PRBool       bound = PR_FALSE;
+    PRNetAddr    netaddr;
+    PRNetAddr    netaddrx;
+    PRBool       endOfInput = PR_FALSE;
+    PRInt32      numBytes = UDP_DGRAM_SIZE;
+    PRInt32      writeThisMany = UDP_AMOUNT_TO_WRITE;
+    int          i;
+    
+    
+    DPRINTF("udpsrv: UDP_Client(): starting\n" );
+    
+    /* --- Create the socket --- */
+    cltSock = PR_NewUDPSocket();
+    if ( cltSock == NULL )
+    {
+        passed = PR_FALSE;
+        if (debug_mode)
+            PR_fprintf(output,
+                "udpsrv: UDP_Client(): PR_NewUDPSocket() returned NULL\n" );
+        return;
+    }
+    
+    /* --- Initialize the sockaddr_in structure --- */
+    memset( &netaddr, 0, sizeof( netaddr )); 
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.ip     = PR_htonl( MY_INADDR );
+    netaddr.inet.port   = PR_htons( UDP_CLIENT_PORT );
+    
+    /* --- Initialize the write buffer --- */    
+    for ( i = 0; i < UDP_BUF_SIZE ; i++ )
+        cltBuf[i] = i;
+    
+    /* --- Bind the socket --- */
+    while ( !bound )
+    {
+        DPRINTF("udpsrv: UDP_Client(): Binding socket\n" );
+        rv = PR_Bind( cltSock, &netaddr );
+        if ( rv < 0 )
+        {
+            if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
+            {
+                if (debug_mode)
+                    PR_fprintf(output,
+                        "udpsrv: UDP_Client(): PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
+                PR_Sleep( PR_MillisecondsToInterval( 2000 ));
+                continue;
+            }
+            else
+            {
+                passed = PR_FALSE;
+                if (debug_mode)
+                    PR_fprintf(output,
+                        "udpsrv: UDP_Client(): PR_Bind(): failed: %ld with error: %ld\n",
+                        rv, PR_GetError() );
+                PR_Close( cltSock );
+                return;
+            }
+        }
+        else
+            bound = PR_TRUE;
+    }
+    ListNetAddr( "UDP_Client after Bind", &netaddr );
+    
+    /* --- Initialize the sockaddr_in structure --- */
+    memset( &netaddr, 0, sizeof( netaddr )); 
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.ip     = PR_htonl( PEER_INADDR );
+    netaddr.inet.port   = PR_htons( UDP_SERVER_PORT );
+    
+    /* --- send and receive packets until no more data left */    
+    while( !endOfInput )
+    {
+        /*
+        ** Signal EOF in the data stream on the last packet
+        */        
+        if ( writeThisMany <= UDP_DGRAM_SIZE )
+        {
+            DPRINTF("udpsrv: UDP_Client(): Send EOF packet\n" );
+            cltBuf[0] = 'E';
+            endOfInput = PR_TRUE;
+        }
+        
+        /* --- SendTo the socket --- */
+        if ( writeThisMany > UDP_DGRAM_SIZE )
+            numBytes = UDP_DGRAM_SIZE;
+        else
+            numBytes = writeThisMany;
+        writeThisMany -= numBytes;
+        {
+            char   mbuf[256];
+            sprintf( mbuf, "udpsrv: UDP_Client(): write_this_many: %d, numbytes: %d\n", 
+                writeThisMany, numBytes );
+            DPRINTF( mbuf );
+        }
+        
+        DPRINTF("udpsrv: UDP_Client(): SendTo(): socket\n" );
+        rv = PR_SendTo( cltSock, cltBuf, numBytes, 0, &netaddr, UDP_TIMEOUT );
+        if ( rv == -1 )
+        {
+            passed = PR_FALSE;
+            if (debug_mode)
+                PR_fprintf(output,
+                    "udpsrv: UDP_Client(): PR_SendTo(): failed with error: %ld\n",
+                        PR_GetError() );
+            PR_Close( cltSock );
+            return;
+        }
+        ListNetAddr( "UDP_Client after SendTo", &netaddr );
+
+        /* --- RecvFrom the socket --- */
+        memset( cltBufin, 0, UDP_BUF_SIZE );
+        DPRINTF("udpsrv: UDP_Client(): RecvFrom(): socket\n" );
+        rv = PR_RecvFrom( cltSock, cltBufin, numBytes, 0, &netaddrx, UDP_TIMEOUT );
+        if ( rv == -1 )
+        {
+            passed = PR_FALSE;
+            if (debug_mode) PR_fprintf(output,
+                "udpsrv: UDP_Client(): PR_RecvFrom(): failed with error: %ld\n",
+                   PR_GetError() );
+            PR_Close( cltSock );
+            return;
+        }
+        ListNetAddr( "UDP_Client after RecvFrom()", &netaddr );
+        cltBytesRead += rv;
+        
+        /* --- verify buffer --- */
+        for ( i = 0; i < rv ; i++ )
+        {
+            if ( cltBufin[i] != i )
+            {
+                /* --- special case, end of input --- */
+                if ( endOfInput && i == 0 && cltBufin[0] == 'E' )
+                    continue;
+                passed = PR_FALSE;
+                if (debug_mode) PR_fprintf(output,
+                    "udpsrv: UDP_Client(): return data mismatch\n" );
+                PR_Close( cltSock );
+                return;
+            }
+        }
+        if (debug_mode) PR_fprintf(output, ".");
+    }
+    
+    /* --- Close the socket --- */
+    DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
+    rv = PR_Close( cltSock );
+    if ( rv != PR_SUCCESS )
+    {
+        passed = PR_FALSE;
+        if (debug_mode) PR_fprintf(output,
+            "udpsrv: UDP_Client(): PR_Close(): failed to close socket\n" );
+        return;
+    }
+    DPRINTF("udpsrv: UDP_Client(): ending\n" );
+} /* --- end UDP_Client() --- */
+
+/********************************************************************
+** main() -- udpsrv
+**
+** arguments:
+**
+** Returns:
+** 0 -- Successful execution
+** 1 -- Test failed.
+**
+** Description:
+**
+** Standard test case setup.
+**
+** Calls the function UDP_Server()
+**
+********************************************************************
+*/
+
+int main(int argc, char **argv)
+{
+    PRThread    *srv, *clt;
+/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d -v
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dv");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'v':  /* verbose mode */
+			_debug_on = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+		
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+    output = PR_STDERR;
+
+    PR_SetConcurrency(4);
+    
+    /*
+    ** Create the Server thread
+    */    
+    DPRINTF( "udpsrv: Creating Server Thread\n" );
+    srv =  PR_CreateThread( PR_USER_THREAD,
+            UDP_Server,
+            (void *) 0,
+            PR_PRIORITY_LOW,
+            PR_LOCAL_THREAD,
+            PR_JOINABLE_THREAD,
+            0 );
+    if ( srv == NULL )
+    {
+        if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" );
+        passed = PR_FALSE;
+    }
+    
+    /*
+    ** Give the Server time to Start
+    */    
+    DPRINTF( "udpsrv: Pausing to allow Server to start\n" );
+    PR_Sleep( PR_MillisecondsToInterval(200) );
+    
+    /*
+    ** Create the Client thread
+    */    
+    DPRINTF( "udpsrv: Creating Client Thread\n" );
+    clt = PR_CreateThread( PR_USER_THREAD,
+            UDP_Client,
+            (void *) 0,
+            PR_PRIORITY_LOW,
+            PR_LOCAL_THREAD,
+            PR_JOINABLE_THREAD,
+            0 );
+    if ( clt == NULL )
+    {
+        if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" );
+        passed = PR_FALSE;
+    }
+    
+    /*
+    **
+    */
+    DPRINTF("udpsrv: Waiting to join Server & Client Threads\n" );
+    PR_JoinThread( srv );
+    PR_JoinThread( clt );    
+    
+    /*
+    ** Evaluate test results
+    */
+    if (debug_mode) PR_fprintf(output, "\n\nudpsrv: main(): cltBytesRead(%ld), \
+		srvBytesRead(%ld), expected(%ld)\n",
+         cltBytesRead, srvBytesRead, UDP_AMOUNT_TO_WRITE );
+    if ( cltBytesRead != srvBytesRead || cltBytesRead != UDP_AMOUNT_TO_WRITE )
+    {
+        passed = PR_FALSE;
+    }
+    PR_Cleanup();
+    if ( passed )
+        return 0;
+    else
+		return 1;
+} /* --- end main() --- */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/ut_ttools.h b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ut_ttools.h
new file mode 100644
index 0000000..dc38f31
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/ut_ttools.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Used in Regress Tool */
+#define NOSTATUS 2
+#define PASS 1
+#define FAIL 0
+
+PRIntn debug_mode=0;
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/vercheck.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/vercheck.c
new file mode 100644
index 0000000..6e77b1d
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/vercheck.c
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * File: vercheck.c
+ *
+ * Description:
+ * This test tests the PR_VersionCheck() function.  The
+ * compatible_version and incompatible_version arrays
+ * need to be updated for each patch or release.
+ *
+ * Tested areas: library version compatibility check.
+ */
+
+#include "prinit.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * This release (4.8.6) is backward compatible with the
+ * 4.0.x, 4.1.x, 4.2.x, 4.3.x, 4.4.x, 4.5.x, 4.6.x, 4.7.x,
+ * 4.8, 4.8.1, 4.8.2, 4.8.3, 4.8.4, and 4.8.5 releases.
+ * It, of course, is compatible with itself.
+ */
+static char *compatible_version[] = {
+    "4.0", "4.0.1", "4.1", "4.1.1", "4.1.2", "4.1.3",
+    "4.2", "4.2.1", "4.2.2", "4.3", "4.4", "4.4.1",
+    "4.5", "4.5.1",
+    "4.6", "4.6.1", "4.6.2", "4.6.3", "4.6.4", "4.6.5",
+    "4.6.6", "4.6.7", "4.6.8",
+    "4.7", "4.7.1", "4.7.2", "4.7.3", "4.7.4", "4.7.5",
+    "4.7.6",
+    "4.8", "4.8.1", "4.8.2", "4.8.3", "4.8.4", "4.8.5",
+    PR_VERSION
+};
+
+/*
+ * This release is not backward compatible with the old
+ * NSPR 2.1 and 3.x releases.
+ *
+ * Any release is incompatible with future releases and
+ * patches.
+ */
+static char *incompatible_version[] = {
+    "2.1 19980529",
+    "3.0", "3.0.1",
+    "3.1", "3.1.1", "3.1.2", "3.1.3",
+    "3.5", "3.5.1",
+    "4.8.9",
+    "4.9", "4.9.1",
+    "10.0", "11.1", "12.14.20"
+};
+
+int main(int argc, char **argv)
+{
+    int idx;
+    int num_compatible = sizeof(compatible_version) / sizeof(char *);
+    int num_incompatible = sizeof(incompatible_version) / sizeof(char *);
+
+    printf("NSPR release %s:\n", PR_VERSION);
+    for (idx = 0; idx < num_compatible; idx++) {
+        if (PR_VersionCheck(compatible_version[idx]) == PR_FALSE) {
+            fprintf(stderr, "Should be compatible with version %s\n",
+                    compatible_version[idx]);
+            exit(1);
+        }
+        printf("Compatible with version %s\n", compatible_version[idx]);
+    }
+
+    for (idx = 0; idx < num_incompatible; idx++) {
+        if (PR_VersionCheck(incompatible_version[idx]) == PR_TRUE) {
+            fprintf(stderr, "Should be incompatible with version %s\n",
+                    incompatible_version[idx]);
+            exit(1);
+        }
+        printf("Incompatible with version %s\n", incompatible_version[idx]);
+    }
+
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/version.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/version.c
new file mode 100644
index 0000000..297a584
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/version.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prprf.h"
+#include "prlink.h"
+#include "prvrsion.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+PR_IMPORT(const PRVersionDescription *) libVersionPoint(void);
+
+int main(int argc, char **argv)
+{
+    PRIntn rv = 1;
+    PLOptStatus os;
+    PRIntn verbosity = 0;
+    PRLibrary *runtime = NULL;
+    const char *library_name = NULL;
+    const PRVersionDescription *version_info;
+	char buffer[100];
+	PRExplodedTime exploded;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:  /* fully qualified library name */
+            library_name = opt->value;
+            break;
+        case 'd':  /* verbodity */
+            verbosity += 1;
+            break;
+         default:
+            PR_fprintf(err, "Usage: version [-d] {fully qualified library name}\n");
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (NULL != library_name)
+    {
+        runtime = PR_LoadLibrary(library_name);
+        if (NULL == runtime) {
+			PL_FPrintError(err, "PR_LoadLibrary");
+			return 3;
+		} else {
+            versionEntryPointType versionPoint = (versionEntryPointType)
+                PR_FindSymbol(runtime, "libVersionPoint");
+            if (NULL == versionPoint) {
+				PL_FPrintError(err, "PR_FindSymbol");
+				return 4;
+			}	
+			version_info = versionPoint();
+		}
+	} else
+		version_info = libVersionPoint();	/* NSPR's version info */
+
+	(void)PR_fprintf(err, "Runtime library version information\n");
+	PR_ExplodeTime(
+		version_info->buildTime, PR_GMTParameters, &exploded);
+	(void)PR_FormatTime(
+		buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded);
+	(void)PR_fprintf(err, "  Build time: %s GMT\n", buffer);
+	(void)PR_fprintf(
+		err, "  Build time: %s\n", version_info->buildTimeString);
+	(void)PR_fprintf(
+		err, "  %s V%u.%u.%u (%s%s%s)\n",
+		version_info->description,
+		version_info->vMajor,
+		version_info->vMinor,
+		version_info->vPatch,
+		(version_info->beta ? " beta " : ""),
+		(version_info->debug ? " debug " : ""),
+		(version_info->special ? " special" : ""));
+	(void)PR_fprintf(err, "  filename: %s\n", version_info->filename);
+	(void)PR_fprintf(err, "  security: %s\n", version_info->security);
+	(void)PR_fprintf(err, "  copyright: %s\n", version_info->copyright);
+	(void)PR_fprintf(err, "  comment: %s\n", version_info->comment);
+	rv = 0;
+    return rv;
+}
+
+/* version.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/writev.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/writev.c
new file mode 100644
index 0000000..26e5248
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/writev.c
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nspr.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#ifndef IOV_MAX
+#define IOV_MAX 16
+#endif
+
+#define BASE_PORT 9867
+
+int PR_CALLBACK Writev(int argc, char **argv)
+{
+
+    PRStatus rv;
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSock, *debug = NULL;
+
+    char *buffer = NULL;
+    PRIOVec *iov = NULL;
+    PRBool passed = PR_TRUE;
+    PRIntervalTime timein, elapsed, timeout;
+    PRIntervalTime tmo_min = 0x7fffffff, tmo_max = 0, tmo_elapsed = 0;
+    PRInt32 tmo_counted = 0, iov_index, loop, bytes, number_fragments;
+    PRInt32 message_length = 100, fragment_length = 100, messages = 100;
+    struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor;
+
+    /*
+     * USAGE
+     * -h       dns name of host serving the connection (default = self)
+     * -m       number of messages to send              (default = 100)
+     * -s       size of each message                    (default = 100)
+     * -f       size of each message fragment           (default = 100)
+     */
+
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dh:m:s:f:");
+
+    PR_STDIO_INIT();
+    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddr);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'h':  /* the remote host */
+            {
+                PRIntn es = 0;
+                PRHostEnt host;
+                char buffer[1024];
+                (void)PR_GetHostByName(opt->value, buffer, sizeof(buffer), &host);
+                es = PR_EnumerateHostEnt(es, &host, BASE_PORT, &serverAddr);
+                PR_ASSERT(es > 0);
+            }
+            break;
+        case 'd':  /* debug mode */
+            debug = PR_GetSpecialFD(PR_StandardError);
+            break;
+        case 'm':  /* number of messages to send */
+            messages = atoi(opt->value);
+            break;
+        case 's':  /* total size of each message */
+            message_length = atoi(opt->value);
+            break;
+        case 'f':  /* size of each message fragment */
+            fragment_length = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    buffer = (char*)malloc(message_length);
+
+    number_fragments = (message_length + fragment_length - 1) / fragment_length + 1;
+    while (IOV_MAX < number_fragments)
+    {
+        fragment_length = message_length / (IOV_MAX - 2);
+        number_fragments = (message_length + fragment_length - 1) /
+            fragment_length + 1;
+        if (NULL != debug) PR_fprintf(debug, 
+            "Too many fragments - reset fragment length to %ld\n", fragment_length);
+    }
+    iov = (PRIOVec*)malloc(number_fragments * sizeof(PRIOVec));
+
+    iov[0].iov_base = (char*)&descriptor;
+    iov[0].iov_len = sizeof(descriptor);
+    for (iov_index = 1; iov_index < number_fragments; ++iov_index)
+    {
+        iov[iov_index].iov_base = buffer + (iov_index - 1) * fragment_length;
+        iov[iov_index].iov_len = fragment_length;
+    }
+
+    for (bytes = 0; bytes < message_length; ++bytes)
+        buffer[bytes] = (char)bytes;
+
+    timeout = PR_SecondsToInterval(1);
+
+    for (loop = 0; loop < messages; ++loop)
+    {
+        if (NULL != debug)
+            PR_fprintf(debug, "[%d]socket ... ", loop);
+        clientSock = PR_NewTCPSocket();
+        if (clientSock)
+        {
+            timein = PR_IntervalNow();
+            if (NULL != debug)
+                PR_fprintf(debug, "connecting ... ");
+            rv = PR_Connect(clientSock, &serverAddr, timeout);
+            if (PR_SUCCESS == rv)
+            {
+                descriptor.checksum = 0;
+                descriptor.length = (loop < (messages - 1)) ? message_length : 0;
+                if (0 == descriptor.length) number_fragments = 1;
+                else
+                    for (iov_index = 0; iov_index < descriptor.length; ++iov_index)
+                    {
+                        PRUint32 overflow = descriptor.checksum & 0x80000000;
+                        descriptor.checksum = (descriptor.checksum << 1);
+                        if (0x00000000 != overflow) descriptor.checksum += 1;
+                        descriptor.checksum += buffer[iov_index];
+                    }
+                if (NULL != debug) PR_fprintf(
+                    debug, "sending %d bytes ... ", descriptor.length);
+
+                /* then, at the last moment ... */
+                descriptor.length = PR_ntohl(descriptor.length);
+                descriptor.checksum = PR_ntohl(descriptor.checksum);
+
+                bytes = PR_Writev(clientSock, iov, number_fragments, timeout);
+                if (NULL != debug)
+                    PR_fprintf(debug, "closing ... ");
+                rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH);
+                rv = PR_Close(clientSock);
+                if (NULL != debug) PR_fprintf(
+                    debug, "%s\n", ((PR_SUCCESS == rv) ? "good" : "bad"));
+                elapsed = PR_IntervalNow() - timein;
+                if (elapsed < tmo_min) tmo_min = elapsed;
+                else if (elapsed > tmo_max) tmo_max = elapsed;
+                tmo_elapsed += elapsed;
+                tmo_counted += 1;
+            }
+            else
+            {
+                if (NULL != debug) PR_fprintf(
+                    debug, "failed - retrying (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+                PR_Close(clientSock);
+            }
+        }
+        else if (NULL != debug)
+        {
+            PR_fprintf(debug, "unable to create client socket\n");
+            passed = PR_FALSE;
+        }
+    }
+    if (NULL != debug) {
+        if (0 == tmo_counted) {
+            PR_fprintf(debug, "No connection made\n");
+        } else {
+        PR_fprintf(
+            debug, "\nTimings: %d [%d] %d (microseconds)\n",
+            PR_IntervalToMicroseconds(tmo_min),
+            PR_IntervalToMicroseconds(tmo_elapsed / tmo_counted),
+            PR_IntervalToMicroseconds(tmo_max));
+	}
+    }
+
+    PR_DELETE(buffer);
+    PR_DELETE(iov);
+
+    PR_fprintf(
+        PR_GetSpecialFD(PR_StandardError),
+        "%s\n", (passed) ? "PASSED" : "FAILED");
+    return (passed) ? 0 : 1;
+}
+
+int main(int argc, char **argv)
+{
+    return (PR_VersionCheck(PR_VERSION)) ?
+        PR_Initialize(Writev, argc, argv, 4) : -1;
+}  /* main */
+
+/* writev.c */
+
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/xnotify.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/xnotify.c
new file mode 100644
index 0000000..725d9ae
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/xnotify.c
@@ -0,0 +1,389 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prprf.h"
+#include "prio.h"
+#include "prcvar.h"
+#include "prmon.h"
+#include "prcmon.h"
+#include "prlock.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prthread.h"
+
+static PRLock *ml = NULL;
+static PRIntervalTime base;
+static PRFileDesc *err = NULL;
+
+typedef struct CMonShared
+{
+    PRInt32 o1, o2;
+} CMonShared;
+
+typedef struct MonShared
+{
+    PRMonitor *o1, *o2;
+} MonShared;
+
+typedef struct LockShared
+{
+    PRLock *o1, *o2;
+    PRCondVar *cv1, *cv2;
+} LockShared;
+
+static void LogNow(const char *msg, PRStatus rv)
+{
+    PRIntervalTime now = PR_IntervalNow();
+    PR_Lock(ml);
+    PR_fprintf(err, "%6ld: %s", (now - base), msg);
+    if (PR_FAILURE == rv) PL_FPrintError(err, " ");
+    else PR_fprintf(err, "\n");
+    PR_Unlock(ml);
+}  /* LogNow */
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-[d][l][m][c]] [-h]\n");
+    PR_fprintf(err, "\t-d   debug mode                  (default: FALSE)\n");
+    PR_fprintf(err, "\t-l   test with locks             (default: FALSE)\n");
+    PR_fprintf(err, "\t-m   tests with monitors         (default: FALSE)\n");
+    PR_fprintf(err, "\t-c   tests with cmonitors        (default: FALSE)\n");
+    PR_fprintf(err, "\t-h   help\n");
+}  /* Help */
+
+static void PR_CALLBACK T2CMon(void *arg)
+{
+    PRStatus rv;
+    CMonShared *shared = (CMonShared*)arg;
+
+    PR_CEnterMonitor(&shared->o1);
+    LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS);
+    rv = PR_CWait(&shared->o1, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv);
+    else LogNow("T2 wait failed on o1", rv);
+
+    rv = PR_CNotify(&shared->o1);
+    if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv);
+    else LogNow("T2 notify on o1 failed", rv);
+
+    PR_CExitMonitor(&shared->o1);
+}  /* T2CMon */
+
+static void PR_CALLBACK T3CMon(void *arg)
+{
+    PRStatus rv;
+    CMonShared *shared = (CMonShared*)arg;
+
+    PR_CEnterMonitor(&shared->o2);
+    LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS);
+    rv = PR_CWait(&shared->o2, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv);
+    else LogNow("T3 wait failed on o2", rv);
+    rv = PR_CNotify(&shared->o2);
+    LogNow("T3 notify on o2", rv);
+    PR_CExitMonitor(&shared->o2);
+
+}  /* T3CMon */
+
+static CMonShared sharedCM;
+
+static void T1CMon(void)
+{
+    PRStatus rv;
+    PRThread *t2, *t3;
+
+    PR_fprintf(err, "\n**********************************\n");
+    PR_fprintf(err, "         CACHED MONITORS\n");
+    PR_fprintf(err, "**********************************\n");
+
+    base =  PR_IntervalNow();
+
+    PR_CEnterMonitor(&sharedCM.o1);
+    LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS);
+    rv = PR_CWait(&sharedCM.o1, PR_SecondsToInterval(3));
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv);
+    else LogNow("T1 wait on o1 failed", rv);
+    PR_CExitMonitor(&sharedCM.o1);
+
+    LogNow("T1 creating T2", PR_SUCCESS);
+    t2 = PR_CreateThread(
+        PR_USER_THREAD, T2CMon, &sharedCM, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    LogNow("T1 creating T3", PR_SUCCESS);
+    t3 = PR_CreateThread(
+        PR_USER_THREAD, T3CMon, &sharedCM, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    PR_CEnterMonitor(&sharedCM.o2);
+    LogNow("T1 waiting forever on o2", PR_SUCCESS);
+    rv = PR_CWait(&sharedCM.o2, PR_INTERVAL_NO_TIMEOUT);
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv);
+    else LogNow("T1 wait on o2 failed", rv);
+    PR_CExitMonitor(&sharedCM.o2);
+
+    (void)PR_JoinThread(t2);
+    (void)PR_JoinThread(t3);
+
+}  /* T1CMon */
+
+static void PR_CALLBACK T2Mon(void *arg)
+{
+    PRStatus rv;
+    MonShared *shared = (MonShared*)arg;
+
+    PR_EnterMonitor(shared->o1);
+    LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS);
+    rv = PR_Wait(shared->o1, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv);
+    else LogNow("T2 wait failed on o1", rv);
+
+    rv = PR_Notify(shared->o1);
+    if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv);
+    else LogNow("T2 notify on o1 failed", rv);
+
+    PR_ExitMonitor(shared->o1);
+}  /* T2Mon */
+
+static void PR_CALLBACK T3Mon(void *arg)
+{
+    PRStatus rv;
+    MonShared *shared = (MonShared*)arg;
+
+    PR_EnterMonitor(shared->o2);
+    LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS);
+    rv = PR_Wait(shared->o2, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv);
+    else LogNow("T3 wait failed on o2", rv);
+    rv = PR_Notify(shared->o2);
+    LogNow("T3 notify on o2", rv);
+    PR_ExitMonitor(shared->o2);
+
+}  /* T3Mon */
+
+static MonShared sharedM;
+static void T1Mon(void)
+{
+    PRStatus rv;
+    PRThread *t2, *t3;
+
+    PR_fprintf(err, "\n**********************************\n");
+    PR_fprintf(err, "            MONITORS\n");
+    PR_fprintf(err, "**********************************\n");
+
+    sharedM.o1 = PR_NewMonitor();
+    sharedM.o2 = PR_NewMonitor();
+
+    base =  PR_IntervalNow();
+
+    PR_EnterMonitor(sharedM.o1);
+    LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS);
+    rv = PR_Wait(sharedM.o1, PR_SecondsToInterval(3));
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv);
+    else LogNow("T1 wait on o1 failed", rv);
+    PR_ExitMonitor(sharedM.o1);
+
+    LogNow("T1 creating T2", PR_SUCCESS);
+    t2 = PR_CreateThread(
+        PR_USER_THREAD, T2Mon, &sharedM, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    LogNow("T1 creating T3", PR_SUCCESS);
+    t3 = PR_CreateThread(
+        PR_USER_THREAD, T3Mon, &sharedM, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    PR_EnterMonitor(sharedM.o2);
+    LogNow("T1 waiting forever on o2", PR_SUCCESS);
+    rv = PR_Wait(sharedM.o2, PR_INTERVAL_NO_TIMEOUT);
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv);
+    else LogNow("T1 wait on o2 failed", rv);
+    PR_ExitMonitor(sharedM.o2);
+
+    (void)PR_JoinThread(t2);
+    (void)PR_JoinThread(t3);
+
+    PR_DestroyMonitor(sharedM.o1);
+    PR_DestroyMonitor(sharedM.o2);
+
+}  /* T1Mon */
+
+static void PR_CALLBACK T2Lock(void *arg)
+{
+    PRStatus rv;
+    LockShared *shared = (LockShared*)arg;
+
+    PR_Lock(shared->o1);
+    LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS);
+    rv = PR_WaitCondVar(shared->cv1, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv);
+    else LogNow("T2 wait failed on o1", rv);
+
+    rv = PR_NotifyCondVar(shared->cv1);
+    if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv);
+    else LogNow("T2 notify on o1 failed", rv);
+
+    PR_Unlock(shared->o1);
+}  /* T2Lock */
+
+static void PR_CALLBACK T3Lock(void *arg)
+{
+    PRStatus rv;
+    LockShared *shared = (LockShared*)arg;
+
+    PR_Lock(shared->o2);
+    LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS);
+    rv = PR_WaitCondVar(shared->cv2, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv);
+    else LogNow("T3 wait failed on o2", rv);
+    rv = PR_NotifyCondVar(shared->cv2);
+    LogNow("T3 notify on o2", rv);
+    PR_Unlock(shared->o2);
+
+}  /* T3Lock */
+
+/*
+** Make shared' a static variable for Win16
+*/
+static LockShared sharedL;
+
+static void T1Lock(void)
+{
+    PRStatus rv;
+    PRThread *t2, *t3;
+    sharedL.o1 = PR_NewLock();
+    sharedL.o2 = PR_NewLock();
+    sharedL.cv1 = PR_NewCondVar(sharedL.o1);
+    sharedL.cv2 = PR_NewCondVar(sharedL.o2);
+
+    PR_fprintf(err, "\n**********************************\n");
+    PR_fprintf(err, "             LOCKS\n");
+    PR_fprintf(err, "**********************************\n");
+
+    base =  PR_IntervalNow();
+
+    PR_Lock(sharedL.o1);
+    LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS);
+    rv = PR_WaitCondVar(sharedL.cv1, PR_SecondsToInterval(3));
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv);
+    else LogNow("T1 wait on o1 failed", rv);
+    PR_Unlock(sharedL.o1);
+
+    LogNow("T1 creating T2", PR_SUCCESS);
+    t2 = PR_CreateThread(
+        PR_USER_THREAD, T2Lock, &sharedL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    LogNow("T1 creating T3", PR_SUCCESS);
+    t3 = PR_CreateThread(
+        PR_USER_THREAD, T3Lock, &sharedL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    PR_Lock(sharedL.o2);
+    LogNow("T1 waiting forever on o2", PR_SUCCESS);
+    rv = PR_WaitCondVar(sharedL.cv2, PR_INTERVAL_NO_TIMEOUT);
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv);
+    else LogNow("T1 wait on o2 failed", rv);
+    PR_Unlock(sharedL.o2);
+
+    (void)PR_JoinThread(t2);
+    (void)PR_JoinThread(t3);
+
+    PR_DestroyLock(sharedL.o1);
+    PR_DestroyLock(sharedL.o2);
+    PR_DestroyCondVar(sharedL.cv1);
+    PR_DestroyCondVar(sharedL.cv2);
+}  /* T1Lock */
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	PLOptStatus os;
+  	PLOptState *opt = PL_CreateOptState(argc, argv, "dhlmc");
+	PRBool locks = PR_FALSE, monitors = PR_FALSE, cmonitors = PR_FALSE;
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode (noop) */
+            break;
+        case 'l':  /* locks */
+			locks = PR_TRUE;
+            break;
+        case 'm':  /* monitors */
+			monitors = PR_TRUE;
+            break;
+        case 'c':  /* cached monitors */
+			cmonitors = PR_TRUE;
+            break;
+        case 'h':  /* needs guidance */
+         default:
+            Help();
+            return 2;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    ml = PR_NewLock();
+    if (locks) T1Lock();
+    if (monitors) T1Mon();
+    if (cmonitors) T1CMon();
+
+    PR_DestroyLock(ml);
+
+    PR_fprintf(err, "Done!\n");    
+    return 0;
+}  /* main */
+
+
+int main(int argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
+/* xnotify.c */
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/y2k.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/y2k.c
new file mode 100644
index 0000000..68ee245
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/y2k.c
@@ -0,0 +1,818 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * file: y2k.c
+ * description: Test for y2k compliance for NSPR.
+ *
+ * Sep 1999. lth. Added "Sun" specified dates to the test data.
+ */
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prtime.h"
+#include "prprf.h"
+#include "prlog.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define PRINT_DETAILS
+
+int failed_already=0;
+PRBool debug_mode = PR_FALSE;
+
+static char *dayOfWeek[] =
+	{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
+static char *month[] =
+	{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
+
+PRLogModuleInfo *lm;
+
+static void PrintExplodedTime(const PRExplodedTime *et) {
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    printf("%s %s %2ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
+	    et->tm_hour, et->tm_min, et->tm_sec);
+
+    /* Print year */
+    printf("%hd ", et->tm_year);
+
+    /* Print time zone */
+    totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	printf("UTC ");
+    } else {
+        sign = "+";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
+    }
+#ifdef PRINT_DETAILS
+	printf("{%d, %d, %d, %d, %d, %d, %d, %d, %d, { %d, %d}}\n",et->tm_usec,
+											et->tm_sec,
+											et->tm_min,
+											et->tm_hour,
+											et->tm_mday,
+											et->tm_month,
+											et->tm_year,
+											et->tm_wday,
+											et->tm_yday,
+											et->tm_params.tp_gmt_offset,
+											et->tm_params.tp_dst_offset);
+#endif
+}
+
+static int ExplodedTimeIsEqual(const PRExplodedTime *et1,
+	const PRExplodedTime *et2)
+{
+    if (et1->tm_usec == et2->tm_usec &&
+	    et1->tm_sec == et2->tm_sec &&
+	    et1->tm_min == et2->tm_min &&
+	    et1->tm_hour == et2->tm_hour &&
+	    et1->tm_mday == et2->tm_mday &&
+	    et1->tm_month == et2->tm_month &&
+	    et1->tm_year == et2->tm_year &&
+	    et1->tm_wday == et2->tm_wday &&
+	    et1->tm_yday == et2->tm_yday &&
+	    et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset &&
+	    et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) {
+        return 1;
+    } else {
+	return 0;
+    }
+}
+
+/*
+ * TEST 1: TestExplodeImplodeTime
+ * Description:
+ * For each given timestamp T (a PRTime value), call PR_ExplodeTime
+ * with GMT, US Pacific, and local time parameters.  Compare the
+ * resulting calendar (exploded) time values with the expected
+ * values.
+ *
+ * Note: the expected local time values depend on the local time
+ * zone.  The local time values stored in this test are for the US
+ * Pacific Time Zone.  If you are running this test in a different
+ * time zone, you need to modify the values in the localt array.
+ * An example is provided below.
+ *
+ * Call PR_ImplodeTime for each of the exploded values and compare
+ * the resulting PRTime values with the original input.
+ * 
+ * This test is run for the values of time T corresponding to the
+ * following dates:
+ * - 12/31/99 - before 2000 
+ * - 01/01/00 - after 2000 
+ * - Leap year - Feb 29, 2000 
+ * - March 1st, 2001 (after 1 year) 
+ * - March 1st, 2005 (after second leap year) 
+ * - 09/09/99 (used by some programs as an end of file marker)
+ *
+ * Call PR_Now, convert to calendar time using PR_ExplodeTime and
+ * manually check the result for correctness. The time should match
+ * the system clock.
+ *
+ * Tested functions: PR_Now, PR_ExplodeTime, PR_ImplodeTime,
+ * PR_LocalTimeParameters, PR_GMTParameters. 
+ */
+
+static PRTime prt[] = {
+    LL_INIT(220405, 2133125120),  /* 946634400000000 */
+    LL_INIT(220425, 2633779200),  /* 946720800000000 */
+    LL_INIT(221612, 2107598848),  /* 951818400000000 */
+    LL_INIT(228975, 663398400),  /* 983440800000000 */
+    LL_INIT(258365, 1974568960),  /* 1109671200000000 */
+    LL_INIT(218132, 1393788928),  /* 936871200000000 */
+    /* Sun's dates follow */
+    LL_INIT( 213062, 4077979648 ), /* Dec 31 1998 10:00:00 */
+    LL_INIT( 218152, 1894443008 ), /* Sep 10 1999 10:00:00 */
+    LL_INIT( 221592, 1606944768 ), /* Feb 28 2000 10:00:00 */
+    LL_INIT( 227768, 688924672 ), /* Dec 31 2000 10:00:00 */
+    LL_INIT( 227788, 1189578752 ), /* Jan 1  2001 10:00:00 */
+};
+
+static PRExplodedTime gmt[] = {
+    { 0, 0, 0, 10, 31, 11, 1999, 5, 364, {0, 0}}, /* 1999/12/31 10:00:00 GMT */
+    { 0, 0, 0, 10, 1, 0, 2000, 6, 0, {0, 0}}, /* 2000/01/01 10:00:00 GMT */
+    { 0, 0, 0, 10, 29, 1, 2000, 2, 59, {0, 0}}, /* 2000/02/29 10:00:00 GMT */
+    { 0, 0, 0, 10, 1, 2, 2001, 4, 59, {0, 0}}, /* 2001/3/1 10:00:00 GMT */
+    { 0, 0, 0, 10, 1, 2, 2005, 2, 59, {0, 0}}, /* 2005/3/1 10:00:00 GMT */
+    { 0, 0, 0, 10, 9, 8, 1999, 4, 251, {0, 0}},  /* 1999/9/9 10:00:00 GMT */
+    /* Sun's dates follow */
+    { 0, 0, 0, 10, 31, 11, 1998, 4, 364, {0, 0}},  /* 12/31/1998 10:00:00 GMT */
+    { 0, 0, 0, 10, 10, 8, 1999, 5, 252, {0, 0}},  /* 9/10/1999 10:00:00 GMT */
+    { 0, 0, 0, 10, 28, 1, 2000, 1, 58, {0, 0}},  /* 2/28/2000 10:00:00 GMT */
+    { 0, 0, 0, 10, 31, 11, 2000, 0, 365, {0, 0}},  /* 12/31/2000 10:00:00 GMT */
+    { 0, 0, 0, 10, 1, 0, 2001, 1, 0, {0, 0}}  /* 1/1/2001 10:00:00 GMT */
+};
+
+static PRExplodedTime uspt[] = {
+{ 0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */
+{ 0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */
+{ 0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}},  /* 1999/9/9 3:00:00 PDT */
+    /* Sun's dates follow */
+    { 0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}},  /* 12/31/1998 00:00:00 GMT */
+    { 0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}},  /* 9/10/1999 00:00:00 GMT */
+    { 0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}},  /* 2/28/2000 00:00:00 GMT */
+    { 0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}},  /* 12/31/2000 00:00:00 GMT */
+    { 0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}}  /* 1/1/2001 00:00:00 GMT */
+};
+
+/*
+ * This test assumes that we are in US Pacific Time Zone.
+ * If you are running this test in a different time zone,
+ * you need to modify the localt array and fill in the
+ * expected results.  The localt array for US Eastern Time
+ * Zone is provided as an example.
+ */
+static PRExplodedTime localt[] = {
+{ 0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */
+{ 0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */
+{ 0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}},  /* 1999/9/9 3:00:00 PDT */
+    /* Sun's dates follow */
+    { 0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}},  /* 12/31/1998 00:00:00 GMT */
+    { 0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}},  /* 9/10/1999 00:00:00 GMT */
+    { 0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}},  /* 2/28/2000 00:00:00 GMT */
+    { 0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}},  /* 12/31/2000 00:00:00 GMT */
+    { 0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}}  /* 1/1/2001 00:00:00 GMT */
+};
+
+#ifdef US_EASTERN_TIME
+static PRExplodedTime localt[] = {
+{ 0, 0, 0, 5, 31, 11, 1999, 5, 364, {-18000, 0}}, /* 1999/12/31 2:00:00 EST */
+{ 0, 0, 0, 5, 1, 0, 2000, 6, 0, {-18000, 0}}, /* 2000/01/01 2:00:00 EST */
+{ 0, 0, 0, 5, 29, 1, 2000, 2, 59, {-18000, 0}}, /* 2000/02/29 2:00:00 EST */
+{ 0, 0, 0, 5, 1, 2, 2001, 4, 59, {-18000, 0}}, /* 2001/3/1 2:00:00 EST */
+{ 0, 0, 0, 5, 1, 2, 2005, 2, 59, {-18000, 0}}, /* 2005/3/1 2:00:00 EST */
+{ 0, 0, 0, 6, 9, 8, 1999, 4, 251, {-18000, 3600}},  /* 1999/9/9 3:00:00 EDT */
+    /* Sun's dates follow */
+    { 0, 0, 0, 5, 31, 11, 1998, 4, 364, {-18000 0}},  /* 12/31/1998 00:00:00 GMT */
+    { 0, 0, 0, 6, 10, 8, 1999, 5, 252, {-18000 3600}},  /* 9/10/1999 00:00:00 GMT */
+    { 0, 0, 0, 5, 28, 1, 2000, 1, 58, {-18000 0}},  /* 2/28/2000 00:00:00 GMT */
+    { 0, 0, 0, 5, 31, 11, 2000, 0, 365, {-18000 0}},  /* 12/31/2000 00:00:00 GMT */
+    { 0, 0, 0, 5, 1, 0, 2001, 1, 0, {-18000 0}}  /* 1/1/2001 00:00:00 GMT */
+};
+#endif
+
+static PRStatus TestExplodeImplodeTime(void)
+{
+    PRTime prt_tmp;
+    PRTime now;
+    int idx;
+    int array_size = sizeof(prt) / sizeof(PRTime);
+    PRExplodedTime et_tmp;
+    char buf[1024];
+
+    for (idx = 0; idx < array_size; idx++) {
+        PR_snprintf(buf, sizeof(buf), "%lld", prt[idx]);
+        if (debug_mode) printf("Time stamp %s\n", buf); 
+        PR_ExplodeTime(prt[idx], PR_GMTParameters, &et_tmp);
+        if (!ExplodedTimeIsEqual(&et_tmp, &gmt[idx])) {
+            fprintf(stderr, "GMT not equal\n");
+            PrintExplodedTime(&et_tmp);
+            PrintExplodedTime(&gmt[idx]);
+            exit(1);
+        }
+        prt_tmp = PR_ImplodeTime(&et_tmp);
+        if (LL_NE(prt_tmp, prt[idx])) {
+            fprintf(stderr, "PRTime not equal\n");
+            exit(1);
+        }
+        if (debug_mode) {
+            printf("GMT: ");
+            PrintExplodedTime(&et_tmp);
+            printf("\n");
+        }
+
+        PR_ExplodeTime(prt[idx], PR_USPacificTimeParameters, &et_tmp);
+        if (!ExplodedTimeIsEqual(&et_tmp, &uspt[idx])) {
+            fprintf(stderr, "US Pacific Time not equal\n");
+            PrintExplodedTime(&et_tmp);
+            PrintExplodedTime(&uspt[idx]);
+            exit(1);
+        }
+        prt_tmp = PR_ImplodeTime(&et_tmp);
+        if (LL_NE(prt_tmp, prt[idx])) {
+            fprintf(stderr, "PRTime not equal\n");
+            exit(1);
+        }
+        if (debug_mode) {
+            printf("US Pacific Time: ");
+            PrintExplodedTime(&et_tmp);
+            printf("\n");
+        }
+
+        PR_ExplodeTime(prt[idx], PR_LocalTimeParameters, &et_tmp);
+        if (!ExplodedTimeIsEqual(&et_tmp, &localt[idx])) {
+            fprintf(stderr, "not equal\n");
+            PrintExplodedTime(&et_tmp);
+            PrintExplodedTime(&localt[idx]);
+            exit(1);
+        }
+        prt_tmp = PR_ImplodeTime(&et_tmp);
+        if (LL_NE(prt_tmp, prt[idx])) {
+            fprintf(stderr, "not equal\n");
+            exit(1);
+        }
+        if (debug_mode) {
+            printf("Local time:");
+            PrintExplodedTime(&et_tmp);
+            printf("\n\n");
+        }
+    }
+
+    now = PR_Now();
+    PR_ExplodeTime(now, PR_GMTParameters, &et_tmp);
+    printf("Current GMT is ");
+    PrintExplodedTime(&et_tmp);
+    printf("\n");
+    prt_tmp = PR_ImplodeTime(&et_tmp);
+    if (LL_NE(prt_tmp, now)) {
+        fprintf(stderr, "not equal\n");
+        exit(1);
+    }
+    PR_ExplodeTime(now, PR_USPacificTimeParameters, &et_tmp);
+    printf("Current US Pacific Time is ");
+    PrintExplodedTime(&et_tmp);
+    printf("\n");
+    prt_tmp = PR_ImplodeTime(&et_tmp);
+    if (LL_NE(prt_tmp, now)) {
+        fprintf(stderr, "not equal\n");
+        exit(1);
+    }
+    PR_ExplodeTime(now, PR_LocalTimeParameters, &et_tmp);
+    printf("Current local time is ");
+    PrintExplodedTime(&et_tmp);
+    printf("\n");
+    prt_tmp = PR_ImplodeTime(&et_tmp);
+    if (LL_NE(prt_tmp, now)) {
+        fprintf(stderr, "not equal\n");
+        exit(1);
+    }
+    printf("Please verify the results\n\n");
+
+    if (debug_mode) printf("Test 1 passed\n");
+    return PR_SUCCESS;
+}
+/* End of Test 1: TestExplodeImplodeTime */
+
+/*
+ * Test 2: Normalize Time
+ */
+
+/*
+ * time increment for addition to PRExplodeTime
+ */
+typedef struct time_increment {
+	PRInt32 ti_usec;
+	PRInt32 ti_sec;
+	PRInt32 ti_min;
+	PRInt32 ti_hour;
+} time_increment_t;
+
+/*
+ * Data for testing PR_Normalize
+ *		Add the increment to base_time, normalize it to GMT and US Pacific
+ *		Time zone.
+ */
+typedef struct normalize_test_data {
+    PRExplodedTime		base_time; 
+    time_increment_t  	increment;
+    PRExplodedTime		expected_gmt_time;
+    PRExplodedTime		expected_uspt_time;
+} normalize_test_data_t;
+
+
+/*
+ * Test data -	the base time values cover dates of interest including y2k - 1,
+ *				y2k + 1, y2k leap year, y2k leap date + 1year,
+ *				y2k leap date + 4 years
+ */
+normalize_test_data_t normalize_test_array[] = {
+  /*usec sec min hour  mday  mo  year  wday yday {gmtoff, dstoff }*/
+
+	/* Fri 12/31/1999 19:32:48 PST */
+	{{0, 48, 32, 19, 31, 11, 1999, 5, 364, { -28800, 0}},
+    {0, 0, 30, 20},
+	{0, 48, 2, 0, 2, 0, 2000, 0, 1, { 0, 0}},	/*Sun Jan 2 00:02:48 UTC 2000*/
+	{0, 48, 2, 16, 1, 0, 2000, 6, 0, { -28800, 0}},/* Sat Jan 1 16:02:48
+														PST 2000*/
+	},
+	/* Fri 99-12-31 23:59:02 GMT */
+	{{0, 2, 59, 23, 31, 11, 1999, 5, 364, { 0, 0}},
+    {0, 0, 45, 0},
+	{0, 2, 44, 0, 1, 0, 2000, 6, 0, { 0, 0}},/* Sat Jan 1 00:44:02 UTC 2000*/
+	{0, 2, 44, 16, 31, 11, 1999, 5, 364, { -28800, 0}}/*Fri Dec 31 16:44:02
+														PST 1999*/
+	},
+	/* 99-12-25 12:00:00 GMT */
+	{{0, 0, 0, 12, 25, 11, 1999, 6, 358, { 0, 0}},
+    {0, 0, 0, 364 * 24},
+	{0, 0, 0, 12, 23, 11, 2000, 6, 357, { 0, 0}},/*Sat Dec 23 12:00:00
+													2000 UTC*/
+	{0, 0, 0, 4, 23, 11, 2000, 6, 357, { -28800, 0}}/*Sat Dec 23 04:00:00
+														2000 -0800*/
+	},
+	/* 00-01-1 00:00:00 PST */
+    {{0, 0, 0, 0, 1, 0, 2000, 6, 0, { -28800, 0}},
+    {0, 0, 0, 48},
+    {0, 0, 0, 8, 3, 0, 2000, 1, 2, { 0, 0}},/*Mon Jan  3 08:00:00 2000 UTC*/
+    {0, 0, 0, 0, 3, 0, 2000, 1, 2, { -28800, 0}}/*Mon Jan  3 00:00:00 2000
+																-0800*/
+	},
+	/* 00-01-10 12:00:00 PST */
+    {{0, 0, 0, 12, 10, 0, 2000, 1, 9, { -28800, 0}},
+    {0, 0, 0, 364 * 5 * 24},
+    {0, 0, 0, 20, 3, 0, 2005, 1, 2, { 0, 0}},/*Mon Jan  3 20:00:00 2005 UTC */
+    {0, 0, 0, 12, 3, 0, 2005, 1, 2, { -28800, 0}}/*Mon Jan  3 12:00:00
+														2005 -0800*/
+	},
+	/* 00-02-28 15:39 GMT */
+	{{0, 0, 39, 15, 28, 1, 2000, 1, 58, { 0, 0}},
+    {0,  0, 0, 24},
+	{0, 0, 39, 15, 29, 1, 2000, 2, 59, { 0, 0}}, /*Tue Feb 29 15:39:00 2000
+														UTC*/
+	{0, 0, 39, 7, 29, 1, 2000, 2, 59, { -28800, 0}}/*Tue Feb 29 07:39:00
+														2000 -0800*/
+	},
+	/* 01-03-01 12:00 PST */
+    {{0, 0, 0, 12, 3, 0, 2001, 3, 2, { -28800, 0}},/*Wed Jan 3 12:00:00
+													-0800 2001*/
+    {0, 30, 30,45},
+    {0, 30, 30, 17, 5, 0, 2001, 5, 4, { 0, 0}}, /*Fri Jan  5 17:30:30 2001
+													UTC*/
+    {0, 30, 30, 9, 5, 0, 2001, 5, 4, { -28800, 0}} /*Fri Jan  5 09:30:30
+														2001 -0800*/
+	},
+	/* 2004-04-26 12:00 GMT */
+	{{0, 0, 0, 20, 3, 0, 2001, 3, 2, { 0, 0}},
+    {0, 0, 30,0},
+	{0, 0, 30, 20, 3, 0, 2001, 3, 2, { 0, 0}},/*Wed Jan  3 20:30:00 2001 UTC*/ 
+    {0, 0, 30, 12, 3, 0, 2001, 3, 2, { -28800, 0}}/*Wed Jan  3 12:30:00
+														2001 -0800*/
+	},
+	/* 99-09-09 00:00 GMT */
+	{{0, 0, 0, 0, 9, 8, 1999, 4, 251, { 0, 0}},
+    {0, 0, 0, 12},
+    {0, 0, 0, 12, 9, 8, 1999, 4, 251, { 0, 0}},/*Thu Sep  9 12:00:00 1999 UTC*/
+    {0, 0, 0, 5, 9, 8, 1999, 4, 251, { -28800, 3600}}/*Thu Sep  9 05:00:00
+														1999 -0700*/
+	}
+};
+
+void add_time_increment(PRExplodedTime *et1, time_increment_t *it)
+{
+	et1->tm_usec += it->ti_usec;
+	et1->tm_sec	+= it->ti_sec;
+	et1->tm_min += it->ti_min;
+	et1->tm_hour += it->ti_hour;
+}
+
+/*
+** TestNormalizeTime() -- Test PR_NormalizeTime()
+**		For each data item, add the time increment to the base_time and then
+**		normalize it for GMT and local time zones. This test assumes that
+**		the local time zone is the Pacific Time Zone. The normalized values
+**		should match the expected values in the data item.
+**
+*/
+PRStatus TestNormalizeTime(void)
+{
+int idx, count;
+normalize_test_data_t *itemp;
+time_increment_t *itp;
+
+	count = sizeof(normalize_test_array)/sizeof(normalize_test_array[0]);
+	for (idx = 0; idx < count; idx++) {
+		itemp = &normalize_test_array[idx];
+		if (debug_mode) {
+			printf("%2d. %15s",idx +1,"Base time: ");
+			PrintExplodedTime(&itemp->base_time);
+			printf("\n");
+		}
+		itp = &itemp->increment;
+		if (debug_mode) {
+			printf("%20s %2d hrs %2d min %3d sec\n","Add",itp->ti_hour,
+												itp->ti_min, itp->ti_sec);
+		}
+		add_time_increment(&itemp->base_time, &itemp->increment);
+		PR_NormalizeTime(&itemp->base_time, PR_LocalTimeParameters);
+		if (debug_mode) {
+			printf("%19s","PST time: ");
+			PrintExplodedTime(&itemp->base_time);
+			printf("\n");
+		}
+		if (!ExplodedTimeIsEqual(&itemp->base_time,
+									&itemp->expected_uspt_time)) {
+			printf("PR_NormalizeTime failed\n");
+			if (debug_mode)
+				PrintExplodedTime(&itemp->expected_uspt_time);
+			return PR_FAILURE;
+		}
+		PR_NormalizeTime(&itemp->base_time, PR_GMTParameters);
+		if (debug_mode) {
+			printf("%19s","GMT time: ");
+			PrintExplodedTime(&itemp->base_time);
+			printf("\n");
+		}
+
+		if (!ExplodedTimeIsEqual(&itemp->base_time,
+									&itemp->expected_gmt_time)) {
+			printf("PR_NormalizeTime failed\n");
+			return PR_FAILURE;
+		}
+	}
+	return PR_SUCCESS;
+}
+
+
+/*
+** ParseTest. Structure defining a string time and a matching exploded time
+**
+*/
+typedef struct ParseTest
+{
+    char            *sDate;     /* string to be converted using PR_ParseTimeString() */
+    PRExplodedTime  et;         /* expected result of the conversion */
+} ParseTest;
+
+static ParseTest parseArray[] = 
+{
+    /*                                  |<----- expected result ------------------------------------------->| */
+    /* "string to test"                   usec     sec min hour   day  mo  year  wday julian {gmtoff, dstoff }*/
+    { "Thursday 1 Jan 1970 00:00:00",   { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "1 Jan 1970 00:00:00",            { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "1-Jan-1970 00:00:00",            { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01-Jan-1970 00:00:00",           { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 1, 1970",                { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 1, 1970 00:00",          { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 01, 1970 00:00",         { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 01 1970 00:00",          { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 01 1970 00:00:00",       { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01-01-1970",                     { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01/01/1970",                     { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01/01/70",                       { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01/01/70 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "70/01/01 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "70/1/1 00:00:",                  { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "00:00 Thursday, January 1, 1970",{ 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "1-Jan-70 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "70-01-01 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "70/01/01 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+
+    /* 31-Dec-1969 */
+    { "Wed 31 Dec 1969 00:00:00",       { 000000,  00, 00, 00,    31,  11, 1969, 3,   364,   {-28800, 0 }}},
+    { "31 Dec 1969 00:00:00",           { 000000,  00, 00, 00,    31,  11, 1969, 3,   364,   {-28800, 0 }}},
+    { "12/31/69    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2069, 2,   364,   {-28800, 0 }}},
+    { "12/31/1969  00:00:00",           { 000000,  00, 00, 00,    31,  11, 1969, 3,   364,   {-28800, 0 }}},
+    { "12-31-69    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2069, 2,   364,   {-28800, 0 }}},
+    { "12-31-1969  00:00:00",           { 000000,  00, 00, 00,    31,  11, 1969, 3,   364,   {-28800, 0 }}},
+    { "69-12-31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2069, 2,   364,   {-28800, 0 }}},
+    { "69/12/31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2069, 2,   364,   {-28800, 0 }}},
+
+    /* "Sun". 31-Dec-1998 (?) */ 
+    { "Thu 31 Dec 1998 00:00:00",        { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "12/31/98    00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "12/31/1998  00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "12-31-98    00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "12-31-1998  00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "98-12-31    00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "98/12/31    00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+
+    /* 09-Sep-1999. Interesting because of its use as an eof marker? */
+    { "09 Sep 1999 00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "9/9/99      00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "9/9/1999    00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "9-9-99      00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "9-9-1999    00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "09-09-99    00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "09-09-1999  00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "99-09-09    00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    
+    /* "Sun". 10-Sep-1999. Because Sun said so. */
+    { "10 Sep 1999 00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "9/10/99     00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "9/10/1999   00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "9-10-99     00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "9-10-1999   00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "09-10-99    00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "09-10-1999  00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "99-09-10    00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+
+    /* 31-Dec-1999 */
+    { "31 Dec 1999 00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "12/31/99    00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "12/31/1999  00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "12-31-99    00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "12-31-1999  00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "99-12-31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "99/12/31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+
+    /* 01-Jan-2000 */
+    { "01 Jan 2000 00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "1/1/00      00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "1/1/2000    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "1-1-00      00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "1-1-2000    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "01-01-00    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "Saturday 01-01-2000  00:00:00",  { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+
+    /* "Sun". 28-Feb-2000 */
+    { "28 Feb 2000 00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "2/28/00     00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "2/28/2000   00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "2-28-00     00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "2-28-2000   00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "02-28-00    00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "02-28-2000  00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+
+    /* 29-Feb-2000 */
+    { "29 Feb 2000 00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "2/29/00     00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "2/29/2000   00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "2-29-00     00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "2-29-2000   00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "02-29-00    00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "02-29-2000  00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+
+    /* 01-Mar-2000 */
+    { "01 Mar 2000 00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "3/1/00      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "3/1/2000    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "3-1-00      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "03-01-00    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "03-01-2000  00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+
+    /* "Sun". 31-Dec-2000 */
+    { "31 Dec 2000 00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "12/31/00    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "12/31/2000  00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "12-31-00    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "12-31-2000  00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "00-12-31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "00/12/31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+
+    /* "Sun". 01-Jan-2001 */
+    { "01 Jan 2001 00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "1/1/01      00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "1/1/2001    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "1-1-01      00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "1-1-2001    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "01-01-01    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "Saturday 01-01-2001  00:00:00",  { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+
+    /* 01-Mar-2001 */
+    { "01 Mar 2001 00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "3/1/01      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "3/1/2001    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "3-1-01      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "3-1-2001    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "03-01-01    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "03-01-2001  00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+
+    /* 29-Feb-2004 */
+    { "29 Feb 2004 00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+    { "2/29/04     00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+    { "2/29/2004   00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+    { "2-29-04     00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+    { "2-29-2004   00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+
+    /* 01-Mar-2004 */
+    { "01 Mar 2004 00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "3/1/04      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "3/1/2004    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "3-1-04      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "3-1-2004    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "03-01-04    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "03-01-2004  00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+
+    /* 01-Mar-2005 */
+    { "01 Mar 2005 00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "3/1/05      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "3/1/2005    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "3-1-05      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "3-1-2005    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "03-01-05    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "03-01-2005  00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+
+    /* last element. string must be null */
+    { NULL }        
+}; /* end array of ParseTest */
+
+/*
+** TestParseTime() -- Test PR_ParseTimeString() for y2k compliance
+**
+** TestParseTime() loops thru the array parseArray. For each element in
+** the array, he calls PR_ParseTimeString() with sDate as the conversion
+** argument. The result (ct) is then converted to a PRExplodedTime structure
+** and compared with the exploded time value (parseArray[n].et) in the
+** array element; if equal, the element passes the test.
+**
+** The array parseArray[] contains entries that are interesting to the
+** y2k problem.
+**
+**
+*/
+static PRStatus TestParseTime( void )
+{
+    ParseTest       *ptp = parseArray;
+    PRTime          ct;
+    PRExplodedTime  cet;
+    char            *sp = ptp->sDate;
+    PRStatus        rc;
+    PRStatus        rv = PR_SUCCESS;
+
+    while ( sp != NULL)
+    {
+        rc = PR_ParseTimeString( sp, PR_FALSE, &ct );
+        if ( PR_FAILURE == rc )
+        {
+            printf("TestParseTime(): PR_ParseTimeString() failed to convert: %s\n", sp );
+            rv = PR_FAILURE;
+            failed_already = 1;
+        }
+        else
+        {
+            PR_ExplodeTime( ct, PR_LocalTimeParameters , &cet );
+
+            if ( !ExplodedTimeIsEqual( &cet, &ptp->et ))
+            {
+                printf("TestParseTime(): Exploded time compare failed: %s\n", sp );
+                if ( debug_mode )
+                {
+                    PrintExplodedTime( &cet );
+                    printf("\n");
+                    PrintExplodedTime( &ptp->et );
+                    printf("\n");
+                }
+                
+                rv = PR_FAILURE;
+                failed_already = 1;
+            }
+        }
+                
+        /* point to next element in array, keep going */
+        ptp++;
+        sp = ptp->sDate;
+    } /* end while() */
+
+    return( rv );
+} /* end TestParseTime() */
+
+int main(int argc, char** argv)
+{
+	/* The command line argument: -d is used to determine if the test is being run
+	in debug mode. The regress tool requires only one line output:PASS or FAIL.
+	All of the printfs associated with this test has been handled with a if (debug_mode)
+	test.
+	Usage: test_name -d
+	*/
+	PLOptStatus os;
+	PLOptState *opt;
+    
+    PR_STDIO_INIT();
+	opt = PL_CreateOptState(argc, argv, "d");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    lm = PR_NewLogModule("test");
+
+    if ( PR_FAILURE == TestExplodeImplodeTime())
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("TestExplodeImplodeTime() failed"));
+    }
+    else
+    	printf("Test 1: Calendar Time Test passed\n");
+
+    if ( PR_FAILURE == TestNormalizeTime())
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("TestNormalizeTime() failed"));
+    }
+    else
+    	printf("Test 2: Normalize Time Test passed\n");
+
+    if ( PR_FAILURE == TestParseTime())
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("TestParseTime() failed"));
+    }
+    else
+    	printf("Test 3: Parse Time Test passed\n");
+
+	if (failed_already) 
+	    return 1;
+	else 
+	    return 0;
+} /* end main() y2k.c */
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/y2ktmo.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/y2ktmo.c
new file mode 100644
index 0000000..40be6f0
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/y2ktmo.c
@@ -0,0 +1,582 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Test: y2ktmo
+ *
+ * Description:
+ *   This test tests the interval time facilities in NSPR for Y2K
+ *   compliance.  All the functions that take a timeout argument
+ *   are tested: PR_Sleep, socket I/O (PR_Accept is taken as a
+ *   representative), PR_Poll, PR_WaitCondVar, PR_Wait, and
+ *   PR_CWait.  A thread of each thread scope (local, global, and
+ *   global bound) is created to call each of these functions.
+ *   The test should be started at the specified number of seconds
+ *   (called the lead time) before a Y2K rollover test date.  The
+ *   timeout values for these threads will span over the rollover
+ *   date by at least the specified number of seconds.  For
+ *   example, if the lead time is 5 seconds, the test should
+ *   be started at time (D - 5), where D is a rollover date, and
+ *   the threads will time out at or after time (D + 5).  The
+ *   timeout values for the threads are spaced one second apart.
+ *
+ *   When a thread times out, it calls PR_IntervalNow() to verify
+ *   that it did wait for the specified time.  In addition, it
+ *   calls a platform-native function to verify the actual elapsed
+ *   time again, to rule out the possibility that PR_IntervalNow()
+ *   is broken.  We allow the actual elapsed time to deviate from
+ *   the specified timeout by a certain tolerance (in milliseconds).
+ */ 
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(XP_UNIX)
+#include <sys/time.h> /* for gettimeofday */
+#endif
+#if defined(WIN32)
+#if defined(WINCE)
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/timeb.h>  /* for _ftime */
+#endif
+#endif
+
+#define DEFAULT_LEAD_TIME_SECS 5
+#define DEFAULT_TOLERANCE_MSECS 500
+
+static PRBool debug_mode = PR_FALSE;
+static PRInt32 lead_time_secs = DEFAULT_LEAD_TIME_SECS;
+static PRInt32 tolerance_msecs = DEFAULT_TOLERANCE_MSECS;
+static PRIntervalTime start_time;
+static PRIntervalTime tolerance;
+
+#if defined(XP_UNIX)
+static struct timeval start_time_tv;
+#endif
+#if defined(WIN32)
+#if defined(WINCE)
+static DWORD start_time_tick;
+#else
+static struct _timeb start_time_tb;
+#endif
+#endif
+
+static void SleepThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32) && !defined(WINCE)
+    struct _timeb end_time_tb;
+#endif
+
+    if (PR_Sleep(timeout) == PR_FAILURE) {
+        fprintf(stderr, "PR_Sleep failed\n");
+        exit(1);
+    }
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+#if defined(WINCE)
+    elapsed_msecs = GetTickCount() - start_time_tick;
+#else
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    if (debug_mode) {
+        fprintf(stderr, "Sleep thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void AcceptThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32) && !defined(WINCE)
+    struct _timeb end_time_tb;
+#endif
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    PRFileDesc *accepted;
+
+    sock = PR_NewTCPSocket();
+    if (sock == NULL) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = 0;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    if (PR_Bind(sock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    if (PR_Listen(sock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+    accepted = PR_Accept(sock, NULL, timeout);
+    if (accepted != NULL || PR_GetError() != PR_IO_TIMEOUT_ERROR) {
+        fprintf(stderr, "PR_Accept did not time out\n");
+        exit(1);
+    }
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+#if defined(WINCE)
+    elapsed_msecs = GetTickCount() - start_time_tick;
+#else
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (debug_mode) {
+        fprintf(stderr, "Accept thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void PollThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32) && !defined(WINCE)
+    struct _timeb end_time_tb;
+#endif
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    PRPollDesc pd;
+    PRIntn rv;
+
+    sock = PR_NewTCPSocket();
+    if (sock == NULL) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = 0;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    if (PR_Bind(sock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    if (PR_Listen(sock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+    pd.fd = sock;
+    pd.in_flags = PR_POLL_READ;
+    rv = PR_Poll(&pd, 1, timeout);
+    if (rv != 0) {
+        fprintf(stderr, "PR_Poll did not time out\n");
+        exit(1);
+    }
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+#if defined(WINCE)
+    elapsed_msecs = GetTickCount() - start_time_tick;
+#else
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (debug_mode) {
+        fprintf(stderr, "Poll thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void WaitCondVarThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32) && !defined(WINCE)
+    struct _timeb end_time_tb;
+#endif
+    PRLock *ml;
+    PRCondVar *cv;
+
+    ml = PR_NewLock();
+    if (ml == NULL) {
+        fprintf(stderr, "PR_NewLock failed\n");
+        exit(1);
+    }
+    cv = PR_NewCondVar(ml);
+    if (cv == NULL) {
+        fprintf(stderr, "PR_NewCondVar failed\n");
+        exit(1);
+    }
+    PR_Lock(ml);
+    PR_WaitCondVar(cv, timeout);
+    PR_Unlock(ml);
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+#if defined(WINCE)
+    elapsed_msecs = GetTickCount() - start_time_tick;
+#else
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    if (debug_mode) {
+        fprintf(stderr, "wait cond var thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void WaitMonitorThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32) && !defined(WINCE)
+    struct _timeb end_time_tb;
+#endif
+    PRMonitor *mon;
+
+    mon = PR_NewMonitor();
+    if (mon == NULL) {
+        fprintf(stderr, "PR_NewMonitor failed\n");
+        exit(1);
+    }
+    PR_EnterMonitor(mon);
+    PR_Wait(mon, timeout);
+    PR_ExitMonitor(mon);
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+#if defined(WINCE)
+    elapsed_msecs = GetTickCount() - start_time_tick;
+#else
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    PR_DestroyMonitor(mon);
+    if (debug_mode) {
+        fprintf(stderr, "wait monitor thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void WaitCMonitorThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32) && !defined(WINCE)
+    struct _timeb end_time_tb;
+#endif
+    int dummy;
+
+    PR_CEnterMonitor(&dummy);
+    PR_CWait(&dummy, timeout);
+    PR_CExitMonitor(&dummy);
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+#if defined(WINCE)
+    elapsed_msecs = GetTickCount() - start_time_tick;
+#else
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    if (debug_mode) {
+        fprintf(stderr, "wait cached monitor thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+typedef void (*NSPRThreadFunc)(void*);
+
+static NSPRThreadFunc threadFuncs[] = {
+    SleepThread, AcceptThread, PollThread,
+    WaitCondVarThread, WaitMonitorThread, WaitCMonitorThread};
+
+static PRThreadScope threadScopes[] = {
+    PR_LOCAL_THREAD, PR_GLOBAL_THREAD, PR_GLOBAL_BOUND_THREAD};
+
+static void Help(void)
+{
+    fprintf(stderr, "y2ktmo test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-l <secs>    lead time          (%d)\n",
+            DEFAULT_LEAD_TIME_SECS);
+    fprintf(stderr, "\t-t <msecs>   tolerance          (%d)\n",
+            DEFAULT_TOLERANCE_MSECS);
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRThread **threads;
+    int num_thread_funcs = sizeof(threadFuncs)/sizeof(NSPRThreadFunc);
+    int num_thread_scopes = sizeof(threadScopes)/sizeof(PRThreadScope);
+    int i, j;
+    int idx;
+    PRInt32 secs;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dl:t:h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'l':  /* lead time */
+                lead_time_secs = atoi(opt->value);
+                break;
+            case 't':  /* tolerance */
+                tolerance_msecs = atoi(opt->value);
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (debug_mode) {
+        fprintf(stderr, "lead time: %d secs\n", lead_time_secs);
+        fprintf(stderr, "tolerance: %d msecs\n", tolerance_msecs);
+    }
+
+    start_time = PR_IntervalNow();
+#if defined(XP_UNIX)
+    gettimeofday(&start_time_tv, NULL);
+#endif
+#if defined(WIN32)
+#ifdef WINCE
+    start_time_tick = GetTickCount();
+#else
+    _ftime(&start_time_tb);
+#endif
+#endif
+    tolerance = PR_MillisecondsToInterval(tolerance_msecs);
+
+    threads = PR_Malloc(
+            num_thread_scopes * num_thread_funcs * sizeof(PRThread*));
+    if (threads == NULL) {
+        fprintf(stderr, "PR_Malloc failed\n");
+        exit(1);
+    }
+
+    /* start to time out 5 seconds after a rollover date */
+    secs = lead_time_secs + 5;
+    idx = 0;
+    for (i = 0; i < num_thread_scopes; i++) { 
+        for (j = 0; j < num_thread_funcs; j++) {
+            threads[idx] = PR_CreateThread(PR_USER_THREAD, threadFuncs[j],
+                (void*)PR_SecondsToInterval(secs), PR_PRIORITY_NORMAL,
+                threadScopes[i], PR_JOINABLE_THREAD, 0);
+            if (threads[idx] == NULL) {
+                fprintf(stderr, "PR_CreateThread failed\n");
+                exit(1);
+            }
+            secs++;
+            idx++;
+        }
+    }
+    for (idx = 0; idx < num_thread_scopes*num_thread_funcs; idx++) {
+        if (PR_JoinThread(threads[idx]) == PR_FAILURE) {
+            fprintf(stderr, "PR_JoinThread failed\n");
+            exit(1);
+        }
+    }
+    PR_Free(threads);
+    printf("PASS\n");
+    return 0;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/yield.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/yield.c
new file mode 100644
index 0000000..b798a09
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/yield.c
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include "prthread.h"
+#include "prinit.h"
+#ifndef XP_OS2
+#include "private/pprmisc.h"
+#include <windows.h>
+#else
+#include "primpl.h"
+#include <os2.h>
+#endif
+
+#define THREADS 10
+
+
+void 
+threadmain(void *_id)
+{
+    int id = (int)_id;
+    int index;
+
+    printf("thread %d alive\n", id);
+    for (index=0; index<10; index++) {
+        printf("thread %d yielding\n", id);
+        PR_Sleep(0);
+        printf("thread %d awake\n", id);
+    }
+    printf("thread %d dead\n", id);
+
+}
+
+int main(int argc, char **argv)
+{
+    int index;
+    PRThread *a[THREADS];
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 5);
+    PR_STDIO_INIT();
+
+    for (index=0; index<THREADS; index++) {
+        a[index] = PR_CreateThread(PR_USER_THREAD,
+                              threadmain,
+                              (void *)index,
+                              PR_PRIORITY_NORMAL,
+                              index%2?PR_LOCAL_THREAD:PR_GLOBAL_THREAD,
+                              PR_JOINABLE_THREAD,
+                              0);
+    }
+    for(index=0; index<THREADS; index++)
+        PR_JoinThread(a[index]);
+    printf("main dying\n");
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/pr/tests/zerolen.c b/nspr-4.8.6/mozilla/nsprpub/pr/tests/zerolen.c
new file mode 100644
index 0000000..5d30b5b
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/pr/tests/zerolen.c
@@ -0,0 +1,300 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Test: zerolen.c 
+ *
+ * Description: a test for Bugzilla bug #17699.  We perform
+ * the same test for PR_Writev, PR_Write, and PR_Send.  In
+ * each test the server thread first fills up the connection
+ * to the client so that the next write operation will fail
+ * with EAGAIN.  Then it calls PR_Writev, PR_Write, or PR_Send
+ * with a zero-length buffer.  The client thread initially
+ * does not read so that the connection can be filled up.
+ * Then it empties the connection so that the server thread's
+ * PR_Writev, PR_Write, or PR_Send call can succeed.
+ *
+ * Bug #17699 is specific to the pthreads version on Unix,
+ * so on other platforms this test does nothing.
+ */
+
+#ifndef XP_UNIX
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("PASS\n");
+    return 0;
+}
+
+#else /* XP_UNIX */
+
+#include "nspr.h"
+#include "private/pprio.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+static void ClientThread(void *arg)
+{
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    PRUint16 port = (PRUint16) arg;
+    char buf[1024];
+    PRInt32 nbytes;
+
+    sock = PR_NewTCPSocket();
+    if (NULL == sock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+        fprintf(stderr, "PR_Connect failed\n");
+        exit(1);
+    }
+    /*
+     * Sleep 5 seconds to force the server thread to get EAGAIN.
+     */
+    if (PR_Sleep(PR_SecondsToInterval(5)) == PR_FAILURE) {
+        fprintf(stderr, "PR_Sleep failed\n");
+        exit(1);
+    }
+    /*
+     * Then start reading.
+     */
+    while ((nbytes = PR_Read(sock, buf, sizeof(buf))) > 0) {
+        /* empty loop body */
+    }
+    if (-1 == nbytes) {
+        fprintf(stderr, "PR_Read failed\n");
+        exit(1);
+    }
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+int main()
+{
+    PRFileDesc *listenSock;
+    PRFileDesc *acceptSock;
+    int osfd;
+    PRThread *clientThread;
+    PRNetAddr addr;
+    char buf[1024];
+    PRInt32 nbytes;
+    PRIOVec iov;
+#ifdef SYMBIAN
+    int loopcount=0;
+#endif
+
+    memset(buf, 0, sizeof(buf)); /* Initialize the buffer. */
+    listenSock = PR_NewTCPSocket();
+    if (NULL == listenSock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    /* Find out what port number we are bound to. */
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetSockName failed\n");
+        exit(1);
+    }
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    /*
+     * First test PR_Writev.
+     */
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == clientThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == acceptSock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+    osfd = PR_FileDesc2NativeHandle(acceptSock);
+    while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) {
+        /* empty loop body */
+#ifdef SYMBIAN
+      if (loopcount++>64) break;
+#endif
+    }
+    if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) {
+        fprintf(stderr, "write failed\n");
+        exit(1);
+    }
+    iov.iov_base = buf;
+    iov.iov_len = 0;
+    printf("calling PR_Writev with a zero-length buffer\n");
+    fflush(stdout);
+    nbytes = PR_Writev(acceptSock, &iov, 1, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes != 0) {
+        fprintf(stderr, "PR_Writev should return 0 but returns %d\n", nbytes);
+        exit(1);
+    }
+    if (PR_Close(acceptSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(clientThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+    /*
+     * Then test PR_Write.
+     */
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == clientThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+#ifdef SYMBIAN
+    loopcount = 0;
+#endif
+    acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == acceptSock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+    osfd = PR_FileDesc2NativeHandle(acceptSock);
+    while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) {
+        /* empty loop body */
+#ifdef SYMBIAN
+      if (loopcount++>64) break;
+#endif
+    }
+    if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) {
+        fprintf(stderr, "write failed\n");
+        exit(1);
+    }
+    printf("calling PR_Write with a zero-length buffer\n");
+    fflush(stdout);
+    nbytes = PR_Write(acceptSock, buf, 0);
+    if (nbytes != 0) {
+        fprintf(stderr, "PR_Write should return 0 but returns %d\n", nbytes);
+        exit(1);
+    }
+    if (PR_Close(acceptSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(clientThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+    /*
+     * Finally test PR_Send.
+     */
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == clientThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+#ifdef SYMBIAN
+    loopcount = 0;
+#endif
+    acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == acceptSock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+    osfd = PR_FileDesc2NativeHandle(acceptSock);
+    while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) {
+        /* empty loop body */
+#ifdef SYMBIAN
+      if (loopcount++>64) break;
+#endif
+    }
+    if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) {
+        fprintf(stderr, "write failed\n");
+        exit(1);
+    }
+    printf("calling PR_Send with a zero-length buffer\n");
+    fflush(stdout);
+    nbytes = PR_Send(acceptSock, buf, 0, 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes != 0) {
+        fprintf(stderr, "PR_Send should return 0 but returns %d\n", nbytes);
+        exit(1);
+    }
+    if (PR_Close(acceptSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(clientThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+    if (PR_Close(listenSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    printf("PASS\n");
+    return 0;
+}
+
+#endif /* XP_UNIX */
diff --git a/nspr-4.8.6/mozilla/nsprpub/tools/Makefile.in b/nspr-4.8.6/mozilla/nsprpub/tools/Makefile.in
new file mode 100644
index 0000000..068aa34
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/tools/Makefile.in
@@ -0,0 +1,236 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH	= ..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifeq ($(OS_TARGET), WIN16)
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+endif
+
+
+DIRS =
+
+CSRCS =             \
+	httpget.c	    \
+	tail.c		    \
+	$(NULL)
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS)
+
+INCLUDES = -I$(dist_includedir) 
+
+NSPR_VERSION = 3
+
+# Setting the variables LDOPTS and LIBPR.  We first initialize
+# them to the default values, then adjust them for some platforms.
+LDOPTS = -L$(dist_libdir)
+LIBPR = -lnspr$(NSPR_VERSION)
+LIBPLC = -lplc$(NSPR_VERSION)
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+  LIBPR = $(dist_libdir)/nspr$(NSPR_VERSION).lib
+  LIBPLC= $(dist_libdir)/plc$(NSPR_VERSION).lib
+else
+LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO
+LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).$(LIB_SUFFIX)
+LIBPLC= $(dist_libdir)/libplc$(NSPR_VERSION).$(LIB_SUFFIX)
+endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+LDOPTS += -Zomf -Zlinker /PM:VIO
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+LDOPTS += -rpath $(PWD)/$(dist_libdir) -lpthread
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir)
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib
+LIBPR = -lnspr$(NSPR_VERSION)_shr
+LIBPLC = -lplc$(NSPR_VERSION)_shr
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+ifneq ($(OS_RELEASE), 4.1.3_U1)
+ifdef NS_USE_GCC
+LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir)
+else
+LDOPTS += -R $(PWD)/$(dist_libdir)
+endif
+endif
+
+# SunOS 5.5 needs to link with -lpthread, even though we already
+# linked with this system library when we built libnspr.so.
+ifeq ($(OS_RELEASE), 5.5)
+ifdef USE_PTHREADS
+EXTRA_LIBS = -lpthread
+endif
+endif
+endif # SunOS
+
+ifeq ($(OS_ARCH), NCR)
+# XXX: We see some strange problems when we link with libnspr.so.
+# So for now we use static libraries on NCR.  The shared library
+# stuff below is commented out.
+LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).a
+LIBPLC = $(dist_libdir)/libplc$(NSPR_VERSION).a
+EXTRA_LIBS = -lsocket -lnsl -ldl
+
+# NCR needs to link against -lsocket -lnsl (and -lc, which is linked
+# implicitly by $(CC)) again even though we already linked with these
+# system libraries when we built libnspr.so.
+#EXTRA_LIBS = -lsocket -lnsl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+#export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), SCOOS)
+# SCO Unix needs to link against -lsocket again even though we
+# already linked with these system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup.  Equivalent to the -R or -rpath 
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifneq ($(OS_RELEASE),4.2)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to 
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+	rm -f $@ $(AIX_TMP)
+	$(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(NSPR_VERSION).a
+	$(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+	rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET),WIN16)
+	echo system windows >w16link
+	echo option map >>w16link
+	echo option stack=10K >>w16link
+	echo option heapsize=32K >>w16link
+	echo debug $(DEBUGTYPE) all >>w16link
+	echo name $@  >>w16link
+	echo file >>w16link
+	echo $<  >>w16link
+	echo library  >>w16link
+	echo $(LIBPR),	     >>w16link
+	echo $(LIBPLC),		 >>w16link
+	echo winsock.lib     >>w16link
+	wlink @w16link.
+else
+	link $(LDOPTS) $< $(LIBPR) $(LIBPLC) wsock32.lib -out:$@
+endif
+else
+ifeq ($(OS_ARCH),OS2)
+	$(LINK) $(LDOPTS) $< $(LIBPR) $(LIBPLC) $(OS_LIBS) $(EXTRA_LIBS) -o $@
+else
+	$(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPLC) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
+
diff --git a/nspr-4.8.6/mozilla/nsprpub/tools/httpget.c b/nspr-4.8.6/mozilla/nsprpub/tools/httpget.c
new file mode 100644
index 0000000..774a4c7
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/tools/httpget.c
@@ -0,0 +1,466 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/*
+ * Author: Wan-Teh Chang
+ *
+ * Given an HTTP URL, httpget uses the GET method to fetch the file.
+ * The fetched file is written to stdout by default, or can be
+ * saved in an output file.
+ *
+ * This is a single-threaded program.
+ */
+
+#include "prio.h"
+#include "prnetdb.h"
+#include "prlog.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "prinit.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>  /* for atoi */
+
+#define FCOPY_BUFFER_SIZE (16 * 1024)
+#define INPUT_BUFFER_SIZE 1024
+#define LINE_SIZE 512
+#define HOST_SIZE 256
+#define PORT_SIZE 32
+#define PATH_SIZE 512
+
+/*
+ * A buffer for storing the excess input data for ReadLine.
+ * The data in the buffer starts from (including) the element pointed to
+ * by inputHead, and ends just before (not including) the element pointed
+ * to by inputTail.  The buffer is empty if inputHead == inputTail.
+ */
+
+static char inputBuf[INPUT_BUFFER_SIZE];
+/*
+ * inputBufEnd points just past the end of inputBuf
+ */
+static char *inputBufEnd = inputBuf + sizeof(inputBuf);
+static char *inputHead = inputBuf;
+static char *inputTail = inputBuf;
+
+static PRBool endOfStream = PR_FALSE;
+
+/*
+ * ReadLine --
+ *
+ * Read in a line of text, terminated by CRLF or LF, from fd into buf.
+ * The terminating CRLF or LF is included (always as '\n').  The text
+ * in buf is terminated by a null byte.  The excess bytes are stored in
+ * inputBuf for use in the next ReadLine call or FetchFile call.
+ * Returns the number of bytes in buf.  0 means end of stream.  Returns
+ * -1 if read fails.
+ */
+
+PRInt32 ReadLine(PRFileDesc *fd, char *buf, PRUint32 bufSize)
+{
+    char *dst = buf;
+    char *bufEnd = buf + bufSize;  /* just past the end of buf */
+    PRBool lineFound = PR_FALSE;
+    char *crPtr = NULL;  /* points to the CR ('\r') character */
+    PRInt32 nRead;
+
+loop:
+    PR_ASSERT(inputBuf <= inputHead && inputHead <= inputTail
+	    && inputTail <= inputBufEnd);
+    while (lineFound == PR_FALSE && inputHead != inputTail
+	    && dst < bufEnd - 1) {
+	if (*inputHead == '\r') {
+	    crPtr = dst;
+	} else if (*inputHead == '\n') {
+	    lineFound = PR_TRUE;
+	    if (crPtr == dst - 1) {
+		dst--; 
+	    }
+	}
+	*(dst++) = *(inputHead++);
+    }
+    if (lineFound == PR_TRUE || dst == bufEnd - 1 || endOfStream == PR_TRUE) {
+	*dst = '\0';
+	return dst - buf;
+    }
+
+    /*
+     * The input buffer should be empty now
+     */
+    PR_ASSERT(inputHead == inputTail);
+
+    nRead = PR_Read(fd, inputBuf, sizeof(inputBuf));
+    if (nRead == -1) {
+	*dst = '\0';
+	return -1;
+    } else if (nRead == 0) {
+	endOfStream = PR_TRUE;
+	*dst = '\0';
+	return dst - buf;
+    }
+    inputHead = inputBuf;
+    inputTail = inputBuf + nRead;
+    goto loop;
+}
+
+PRInt32 DrainInputBuffer(char *buf, PRUint32 bufSize)
+{
+    PRInt32 nBytes = inputTail - inputHead;
+
+    if (nBytes == 0) {
+	if (endOfStream) {
+	    return -1;
+	} else {
+	    return 0;
+	}
+    }
+    if ((PRInt32) bufSize < nBytes) {
+	nBytes = bufSize;
+    }
+    memcpy(buf, inputHead, nBytes);
+    inputHead += nBytes;
+    return nBytes;
+}
+
+PRStatus FetchFile(PRFileDesc *in, PRFileDesc *out)
+{
+    char buf[FCOPY_BUFFER_SIZE];
+    PRInt32 nBytes;
+
+    while ((nBytes = DrainInputBuffer(buf, sizeof(buf))) > 0) {
+	if (PR_Write(out, buf, nBytes) != nBytes) {
+            fprintf(stderr, "httpget: cannot write to file\n");
+	    return PR_FAILURE;
+	}
+    }
+    if (nBytes < 0) {
+	/* Input buffer is empty and end of stream */
+	return PR_SUCCESS;
+    }
+    while ((nBytes = PR_Read(in, buf, sizeof(buf))) > 0) {
+	if (PR_Write(out, buf, nBytes) != nBytes) {
+	    fprintf(stderr, "httpget: cannot write to file\n");
+	    return PR_FAILURE;
+        }
+    }
+    if (nBytes < 0) {
+	fprintf(stderr, "httpget: cannot read from socket\n");
+	return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus FastFetchFile(PRFileDesc *in, PRFileDesc *out, PRUint32 size)
+{
+    PRInt32 nBytes;
+    PRFileMap *outfMap;
+    void *addr;
+    char *start;
+    PRUint32 rem;
+    PRUint32 bytesToRead;
+    PRStatus rv;
+    PRInt64 sz64;
+
+    LL_UI2L(sz64, size);
+    outfMap = PR_CreateFileMap(out, sz64, PR_PROT_READWRITE);
+    PR_ASSERT(outfMap);
+    addr = PR_MemMap(outfMap, LL_ZERO, size);
+    if (addr == (void *) -1) {
+	fprintf(stderr, "cannot memory-map file: (%d, %d)\n", PR_GetError(),
+		PR_GetOSError());
+
+	PR_CloseFileMap(outfMap);
+	return PR_FAILURE;
+    }
+    PR_ASSERT(addr != (void *) -1);
+    start = (char *) addr;
+    rem = size;
+    while ((nBytes = DrainInputBuffer(start, rem)) > 0) {
+	start += nBytes;
+	rem -= nBytes;
+    }
+    if (nBytes < 0) {
+	/* Input buffer is empty and end of stream */
+	return PR_SUCCESS;
+    }
+    bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE;
+    while (rem > 0 && (nBytes = PR_Read(in, start, bytesToRead)) > 0) {
+	start += nBytes;
+	rem -= nBytes;
+        bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE;
+    }
+    if (nBytes < 0) {
+	fprintf(stderr, "httpget: cannot read from socket\n");
+	return PR_FAILURE;
+    }
+    rv = PR_MemUnmap(addr, size);
+    PR_ASSERT(rv == PR_SUCCESS);
+    rv = PR_CloseFileMap(outfMap);
+    PR_ASSERT(rv == PR_SUCCESS);
+    return PR_SUCCESS;
+}
+
+PRStatus ParseURL(char *url, char *host, PRUint32 hostSize,
+    char *port, PRUint32 portSize, char *path, PRUint32 pathSize)
+{
+    char *start, *end;
+    char *dst;
+    char *hostEnd;
+    char *portEnd;
+    char *pathEnd;
+
+    if (strncmp(url, "http", 4)) {
+	fprintf(stderr, "httpget: the protocol must be http\n");
+	return PR_FAILURE;
+    }
+    if (strncmp(url + 4, "://", 3) || url[7] == '\0') {
+	fprintf(stderr, "httpget: malformed URL: %s\n", url);
+	return PR_FAILURE;
+    }
+
+    start = end = url + 7;
+    dst = host;
+    hostEnd = host + hostSize;
+    while (*end && *end != ':' && *end != '/') {
+	if (dst == hostEnd - 1) {
+	    fprintf(stderr, "httpget: host name too long\n");
+	    return PR_FAILURE;
+	}
+	*(dst++) = *(end++);
+    }
+    *dst = '\0';
+
+    if (*end == '\0') {
+	PR_snprintf(port, portSize, "%d", 80);
+	PR_snprintf(path, pathSize, "%s", "/");
+	return PR_SUCCESS;
+    }
+
+    if (*end == ':') {
+	end++;
+	dst = port;
+	portEnd = port + portSize;
+	while (*end && *end != '/') {
+	    if (dst == portEnd - 1) {
+		fprintf(stderr, "httpget: port number too long\n");
+		return PR_FAILURE;
+	    }
+	    *(dst++) = *(end++);
+        }
+	*dst = '\0';
+	if (*end == '\0') {
+	    PR_snprintf(path, pathSize, "%s", "/");
+	    return PR_SUCCESS;
+        }
+    } else {
+	PR_snprintf(port, portSize, "%d", 80);
+    }
+
+    dst = path;
+    pathEnd = path + pathSize;
+    while (*end) {
+	if (dst == pathEnd - 1) {
+	    fprintf(stderr, "httpget: file pathname too long\n");
+	    return PR_FAILURE;
+	}
+	*(dst++) = *(end++);
+    }
+    *dst = '\0';
+    return PR_SUCCESS;
+}
+
+void PrintUsage(void) {
+    fprintf(stderr, "usage: httpget url\n"
+		    "       httpget -o outputfile url\n"
+		    "       httpget url -o outputfile\n");
+}
+
+int main(int argc, char **argv)
+{
+    PRHostEnt hostentry;
+    char buf[PR_NETDB_BUF_SIZE];
+    PRNetAddr addr;
+    PRFileDesc *socket = NULL, *file = NULL;
+    PRIntn cmdSize;
+    char host[HOST_SIZE];
+    char port[PORT_SIZE];
+    char path[PATH_SIZE];
+    char line[LINE_SIZE];
+    int exitStatus = 0;
+    PRBool endOfHeader = PR_FALSE;
+    char *url;
+    char *fileName = NULL;
+    PRUint32 fileSize;
+
+    if (argc != 2 && argc != 4) {
+	PrintUsage();
+	exit(1);
+    }
+
+    if (argc == 2) {
+	/*
+	 * case 1: httpget url
+	 */
+	url = argv[1];
+    } else {
+	if (strcmp(argv[1], "-o") == 0) {
+	    /*
+	     * case 2: httpget -o outputfile url
+	     */
+	    fileName = argv[2];
+	    url = argv[3];
+        } else {
+	    /*
+	     * case 3: httpget url -o outputfile
+	     */
+	    url = argv[1];
+	    if (strcmp(argv[2], "-o") != 0) {
+		PrintUsage();
+		exit(1);
+            }
+	    fileName = argv[3];
+	}
+    }
+
+    if (ParseURL(url, host, sizeof(host), port, sizeof(port),
+	    path, sizeof(path)) == PR_FAILURE) {
+	exit(1);
+    }
+
+    if (PR_GetHostByName(host, buf, sizeof(buf), &hostentry)
+	    == PR_FAILURE) {
+        fprintf(stderr, "httpget: unknown host name: %s\n", host);
+	exit(1);
+    }
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons((short) atoi(port));
+    addr.inet.ip = *((PRUint32 *) hostentry.h_addr_list[0]);
+
+    socket = PR_NewTCPSocket();
+    if (socket == NULL) {
+	fprintf(stderr, "httpget: cannot create new tcp socket\n");
+	exit(1);
+    }
+
+    if (PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+	fprintf(stderr, "httpget: cannot connect to http server\n");
+	exitStatus = 1;
+	goto done;
+    }
+
+    if (fileName == NULL) {
+	file = PR_STDOUT;
+    } else {
+        file = PR_Open(fileName, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
+		00777);
+        if (file == NULL) {
+	    fprintf(stderr, "httpget: cannot open file %s: (%d, %d)\n",
+		    fileName, PR_GetError(), PR_GetOSError());
+	    exitStatus = 1;
+	    goto done;
+	}
+    }
+
+    cmdSize = PR_snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n", path);
+    PR_ASSERT(cmdSize == (PRIntn) strlen("GET  HTTP/1.0\r\n\r\n")
+            + (PRIntn) strlen(path));
+    if (PR_Write(socket, buf, cmdSize) != cmdSize) {
+	fprintf(stderr, "httpget: cannot write to http server\n");
+	exitStatus = 1;
+	goto done;
+    }
+
+    if (ReadLine(socket, line, sizeof(line)) <= 0) {
+	fprintf(stderr, "httpget: cannot read line from http server\n");
+	exitStatus = 1;
+	goto done;
+    }
+
+    /* HTTP response: 200 == OK */
+    if (strstr(line, "200") == NULL) {
+	fprintf(stderr, "httpget: %s\n", line);
+	exitStatus = 1;
+	goto done;
+    }
+
+    while (ReadLine(socket, line, sizeof(line)) > 0) {
+	if (line[0] == '\n') {
+	    endOfHeader = PR_TRUE;
+	    break;
+	}
+	if (strncmp(line, "Content-Length", 14) == 0
+		|| strncmp(line, "Content-length", 14) == 0) {
+	    char *p = line + 14;
+
+	    while (*p == ' ' || *p == '\t') {
+		p++;
+	    }
+	    if (*p != ':') {
+		continue;
+            }
+	    p++;
+	    while (*p == ' ' || *p == '\t') {
+		p++;
+	    }
+	    fileSize = 0;
+	    while ('0' <= *p && *p <= '9') {
+		fileSize = 10 * fileSize + (*p - '0');
+		p++;
+            }
+	}
+    }
+    if (endOfHeader == PR_FALSE) {
+	fprintf(stderr, "httpget: cannot read line from http server\n");
+	exitStatus = 1;
+	goto done;
+    }
+
+    if (fileName == NULL || fileSize == 0) {
+        FetchFile(socket, file);
+    } else {
+	FastFetchFile(socket, file, fileSize);
+    }
+
+done:
+    if (socket) PR_Close(socket);
+    if (file) PR_Close(file);
+    PR_Cleanup();
+    return exitStatus;
+}
diff --git a/nspr-4.8.6/mozilla/nsprpub/tools/tail.c b/nspr-4.8.6/mozilla/nsprpub/tools/tail.c
new file mode 100644
index 0000000..dc729c1
--- /dev/null
+++ b/nspr-4.8.6/mozilla/nsprpub/tools/tail.c
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prio.h"
+#include "prprf.h"
+#include "prinit.h"
+#include "prthread.h"
+#include "prinrval.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+#define BUFFER_SIZE 500
+
+static PRFileDesc *out = NULL, *err = NULL;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: tail [-n <n>] [-f] [-h] <filename>\n");
+    PR_fprintf(err, "\t-t <n>	Dally time in milliseconds\n");
+    PR_fprintf(err, "\t-n <n>	Number of bytes before <eof>\n");
+    PR_fprintf(err, "\t-f   	Follow the <eof>\n");
+    PR_fprintf(err, "\t-h   	This message and nothing else\n");
+}  /* Help */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+	PRIntn rv = 0;
+    PLOptStatus os;
+	PRStatus status;
+	PRFileDesc *file;
+	PRFileInfo fileInfo;
+	PRIntervalTime dally;
+	char buffer[BUFFER_SIZE];
+	PRBool follow = PR_FALSE;
+	const char *filename = NULL;
+	PRUint32 position = 0, seek = 0, time = 0;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hfn:");
+
+    out = PR_GetSpecialFD(PR_StandardOutput);
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+		case 0:  /* it's the filename */
+			filename = opt->value;
+			break;
+        case 'n':  /* bytes before end of file */
+            seek = atoi(opt->value);
+            break;
+        case 't':  /* dally time */
+            time = atoi(opt->value);
+            break;
+        case 'f':  /* follow the end of file */
+            follow = PR_TRUE;
+            break;
+        case 'h':  /* user wants some guidance */
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+	if (0 == time) time = 1000;
+	dally = PR_MillisecondsToInterval(time);
+
+    if (NULL == filename)
+    {
+        (void)PR_fprintf(out, "Input file not specified\n");
+        rv = 1; goto done;
+    }
+	file = PR_Open(filename, PR_RDONLY, 0);
+	if (NULL == file)
+	{
+		PL_FPrintError(err, "File cannot be opened for reading");
+		return 1;
+	}
+
+	status = PR_GetOpenFileInfo(file, &fileInfo);
+	if (PR_FAILURE == status)
+	{
+		PL_FPrintError(err, "Cannot acquire status of file");
+		rv = 1; goto done;
+	}
+	if (seek > 0)
+	{
+	    if (seek > fileInfo.size) seek = 0;
+		position = PR_Seek(file, (fileInfo.size - seek), PR_SEEK_SET);
+		if (-1 == (PRInt32)position)
+			PL_FPrintError(err, "Cannot seek to starting position");
+	}
+
+	do
+	{
+		while (position < fileInfo.size)
+		{
+			PRInt32 read, bytes = fileInfo.size - position;
+			if (bytes > sizeof(buffer)) bytes = sizeof(buffer);
+			read = PR_Read(file, buffer, bytes);
+			if (read != bytes)
+				PL_FPrintError(err, "Cannot read to eof");
+			position += read;
+			PR_Write(out, buffer, read);
+		}
+
+		if (follow)
+		{
+			PR_Sleep(dally);
+			status = PR_GetOpenFileInfo(file, &fileInfo);
+			if (PR_FAILURE == status)
+			{
+				PL_FPrintError(err, "Cannot acquire status of file");
+				rv = 1; goto done;
+			}
+		}
+	} while (follow);
+
+done:
+	PR_Close(file);
+
+	return rv;
+}  /* main */
+
+/* tail.c */
diff --git a/nspr.patches/nspr-50.description b/nspr.patches/nspr-50.description
new file mode 100644
index 0000000..934ce44
--- /dev/null
+++ b/nspr.patches/nspr-50.description
@@ -0,0 +1,2 @@
+Use the CLOCK_MONOTONIC clock instead of GETTIMEOFDAY for the implementation of PR_IntervalNow().
+This fixes bug #468: "When NTP changes the time on the board, a RESET message is sent to the backplate"
diff --git a/nspr.patches/nspr-50.patch b/nspr.patches/nspr-50.patch
new file mode 100644
index 0000000..164cce3
--- /dev/null
+++ b/nspr.patches/nspr-50.patch
@@ -0,0 +1,25 @@
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix.c nspr-4.8.6.N/mozilla/nsprpub/pr/src/md/unix/unix.c
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix.c	2010-02-09 19:03:35.000000000 -0800
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/md/unix/unix.c	2011-04-15 11:10:27.000000000 -0700
+@@ -3026,12 +3026,21 @@
+ 
+ PRIntervalTime _PR_UNIX_GetInterval()
+ {
++#if defined(XP_MACOSX)
+     struct timeval time;
+     PRIntervalTime ticks;
+ 
+     (void)GETTIMEOFDAY(&time);  /* fallicy of course */
+     ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
+     ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
++#else
++    struct timespec time;
++    PRIntervalTime ticks;
++
++    (void)clock_gettime(CLOCK_MONOTONIC, &time);
++    ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
++    ticks += (PRUint32)((PRUint64)time.tv_nsec / PR_NSEC_PER_MSEC);  /* so's that */
++#endif
+     return ticks;
+ }  /* _PR_SUNOS_GetInterval */
+ 
diff --git a/nspr.patches/nspr-51.description b/nspr.patches/nspr-51.description
new file mode 100644
index 0000000..6e7357c
--- /dev/null
+++ b/nspr.patches/nspr-51.description
@@ -0,0 +1 @@
+Fix for SAPPHIRE-6143:  relies on PR_LocalTimeParameters() to get all time information but tweaks the gmt/dst parameters based on the diff from GMT and using tm_isdst from struct tm. This fix assumes DST is always 1 hour.
diff --git a/nspr.patches/nspr-51.patch b/nspr.patches/nspr-51.patch
new file mode 100644
index 0000000..14b5503
--- /dev/null
+++ b/nspr.patches/nspr-51.patch
@@ -0,0 +1,233 @@
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c	2010-03-30 12:15:26.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/misc/prtime.c	2013-10-21 13:55:53.000000000 -0700
+@@ -102,6 +102,7 @@
+ static void        ComputeGMT(PRTime time, PRExplodedTime *gmt);
+ static int         IsLeapYear(PRInt16 year);
+ static void        ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset);
++static void        AdjustDSTGMTOffsets(PRTime time, PRExplodedTime *exploded);
+ 
+ /*
+  *------------------------------------------------------------------------
+@@ -244,6 +245,7 @@
+     exploded->tm_params = params(exploded);
+     ApplySecOffset(exploded, exploded->tm_params.tp_gmt_offset
+             + exploded->tm_params.tp_dst_offset);
++    AdjustDSTGMTOffsets(usecs, exploded);
+ }
+ 
+ 
+@@ -581,11 +583,68 @@
+ 
+ #endif  /* definition of MT_safe_localtime() */
+ 
++static PRBool ComputeLocalTime(time_t local, struct tm *ptm)
++{
++#ifdef HAVE_LOCALTIME_R
++    return localtime_r(&local, ptm);
++
++#elif HAVE_LOCALTIME_MONITOR
++
++    if (MT_safe_localtime(&local, ptm) != NULL)
++        return PR_TRUE;
++    else
++        return PR_FALSE;
++#else
++
++    #error no ComputeLocalTime()
++
++#endif /* definition of ComputeLocalTime() */
++}
++
++#ifndef HAVE_GMTIME_R
++
++#define HAVE_GMT_MONITOR 1  /* We use 'monitorgmt' to serialize our calls
++                             * to gmtime(). */
++
++static PRLock *monitorgmt = NULL;
++#endif
++
++static PRBool ComputeUTCTime(time_t t, struct tm *ptm)
++{
++#ifdef HAVE_GMTIME_R
++    return gmtime_r(&t, ptm);
++#else
++    PRBool retval = PR_TRUE;
++    struct tm *otm = NULL;
++    int needLock = PR_Initialized();  /* We need to use a lock to protect
++                                       * against NSPR threads only when the
++                                       * NSPR thread system is activated. */
++    if (needLock) PR_Lock(monitorgmt);
++
++    otm = gmtime(&t);
++
++    if (!otm)
++        retval = PR_FALSE;
++    else
++    {
++        *ptm = *otm;
++        retval = PR_TRUE;
++    }
++
++    if (needLock) PR_Unlock(monitorgmt);
++
++    return retval;
++#endif /* definition of ComputeUTCTime() */
++}
++
+ void _PR_InitTime(void)
+ {
+ #ifdef HAVE_LOCALTIME_MONITOR
+     monitor = PR_NewLock();
+ #endif
++#ifdef HAVE_GMT_MONITOR
++    monitorgmt = PR_NewLock();
++#endif
+ #ifdef WINCE
+     _MD_InitTime();
+ #endif
+@@ -599,11 +658,118 @@
+         monitor = NULL;
+     }
+ #endif
++#ifdef HAVE_GMT_MONITOR
++    if (monitorgmt) {
++        PR_DestroyLock(monitorgmt);
++        monitorgmt = NULL;
++    }
++#endif
+ #ifdef WINCE
+     _MD_CleanupTime();
+ #endif
+ }
+ 
++/*
++ * from https://mxr.mozilla.org/mozilla-central/source/js/src/vm/DateTime.cpp?rev=699228670afb
++ * but slightly adjusted as the modzilla has an issue during the hours close to the dst-std change
++ * Compute the offset in seconds from the current UTC time to the current local
++ * time
++ *
++ * Examples:
++ *
++ * Suppose we are in California, USA on January 1, 2013 at 04:00 PST (UTC-8, no
++ * DST in effect), corresponding to 12:00 UTC.  This function would then return
++ * -8 * SecondsPerHour, or -28800.
++ *
++ * Or suppose we are in Berlin, Germany on July 1, 2013 at 17:00 CEST (UTC+2,
++ * DST in effect), corresponding to 15:00 UTC.  This function would then return
++ * +2 * SecondsPerHour, or +7200.
++ */
++static PRInt32
++UTCToLocalTimeOffsetSeconds(time_t time)
++{
++    PRInt32 SecondsPerDay = 86400;
++    PRInt32 SecondsPerHour = 3600;
++    PRInt32 SecondsPerMinute = 60;
++    struct tm local;
++    struct tm utc;
++
++    memset(&local, 0, sizeof(local));
++    memset(&utc, 0, sizeof(utc));
++
++
++#if defined(XP_WIN)
++    // Windows doesn't follow POSIX: updates to the TZ environment variable are
++    // not reflected immediately on that platform as they are on other systems
++    // without this call.
++    _tzset();
++#endif
++
++    // Break down the current time into its components.
++    if (!ComputeLocalTime(time, &local))
++        return 0;
++
++    // Break down the local time into UTC-based components.
++    memset(&utc, 0, sizeof(utc));
++    if (!ComputeUTCTime(time, &utc))
++        return 0;
++
++    // Finally, compare the seconds-based components of the local
++    // representation and the UTC representation to determine the actual
++    // difference.
++    PRInt32 utc_secs = utc.tm_hour * SecondsPerHour + utc.tm_min * SecondsPerMinute;
++    PRInt32 local_secs = local.tm_hour * SecondsPerHour + local.tm_min * SecondsPerMinute;
++
++    // Same-day?  Just subtract the seconds counts.
++    if (utc.tm_mday == local.tm_mday)
++        return local_secs - utc_secs;
++
++    // If we have more UTC seconds, move local seconds into the UTC seconds'
++    // frame of reference and then subtract.
++    if (utc_secs > local_secs)
++        return (SecondsPerDay + local_secs) - utc_secs;
++
++    // Otherwise we have more local seconds, so move the UTC seconds into the
++    // local seconds' frame of reference and then subtract.
++    return local_secs - (utc_secs + SecondsPerDay);
++}
++
++static void
++AdjustDSTGMTOffsets(PRTime time, PRExplodedTime *exploded)
++{
++    PRInt64 sec64;
++    PRInt64 usecPerSec;
++    PRInt32 overallOffsetFromUTC;
++    PRInt32 dstoffset = 3600;
++    struct tm localTime;
++    time_t timetsecs;
++
++    LL_I2L(usecPerSec, 1000000L);
++    LL_DIV(sec64, time, usecPerSec);
++
++    timetsecs = sec64;
++
++    /*
++     *  overall_offset = gmt_offset + dst_offset
++     */
++    overallOffsetFromUTC = UTCToLocalTimeOffsetSeconds(timetsecs);
++
++    /*
++     *  used the passed time to calculate the right offsets based on
++     *  linux call to localtime
++     */
++    (void) MT_safe_localtime(&timetsecs, &localTime);
++
++    if (localTime.tm_isdst <= 0) {
++        /* DST is not in effect */
++        exploded->tm_params.tp_gmt_offset = overallOffsetFromUTC;
++        exploded->tm_params.tp_dst_offset = 0;
++    } else {
++        exploded->tm_params.tp_gmt_offset = overallOffsetFromUTC - dstoffset;
++        exploded->tm_params.tp_dst_offset = dstoffset;
++    }
++}
++
+ #if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS)
+ 
+ PR_IMPLEMENT(PRTimeParameters)
+@@ -642,7 +808,7 @@
+ 
+     /* GMT is 00:00:00, 2nd of Jan. */
+ 
+-    offset2Jan1970 = (PRInt32)localTime.tm_sec 
++    offset2Jan1970 = (PRInt32)localTime.tm_sec
+             + 60L * (PRInt32)localTime.tm_min
+             + 3600L * (PRInt32)localTime.tm_hour
+             + 86400L * (PRInt32)((PRInt32)localTime.tm_mday - 2L);
+@@ -696,7 +862,7 @@
+     }
+ 
+     /*
+-     * dayOffset is the offset between local time and GMT in 
++     * dayOffset is the offset between local time and GMT in
+      * the day component, which can only be -1, 0, or 1.  We
+      * use the day of the week to compute dayOffset.
+      */
+@@ -745,7 +911,7 @@
+             retVal.tp_dst_offset = 3600;
+         }
+     }
+-    
++
+     return retVal;
+ }
+ 
diff --git a/nspr.patches/nspr-52.description b/nspr.patches/nspr-52.description
new file mode 100644
index 0000000..17254e8
--- /dev/null
+++ b/nspr.patches/nspr-52.description
@@ -0,0 +1,4 @@
+Fix for SAPPHIRE-10152: updates PR_NormalizeTime() to correctly resolve DST
+time values using the Olsen database to avoid the issue seen in SAPPHIRE-10133.
+The existing PR_NormalizeTime has been renamed to PR_NormalizeTime_NoDSTAdjust,
+and is now used only internally within prtime.c.
diff --git a/nspr.patches/nspr-52.patch b/nspr.patches/nspr-52.patch
new file mode 100644
index 0000000..294a929
--- /dev/null
+++ b/nspr.patches/nspr-52.patch
@@ -0,0 +1,67 @@
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h nspr-4.8.6.N/mozilla/nsprpub/pr/include/prtime.h
+--- nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h	2009-03-03 08:17:48.000000000 -0800
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/include/prtime.h	2015-04-29 16:32:24.000000000 -0700
+@@ -206,7 +206,10 @@
+  *     should treat them as "read-only".
+  */
+ 
+-NSPR_API(void) PR_NormalizeTime(
++NSPR_API(PRTime) PR_NormalizeTime(
++    PRExplodedTime *exploded, PRTimeParamFn params);
++
++NSPR_API(void) PR_NormalizeTime_NoDSTAdjust(
+     PRExplodedTime *exploded, PRTimeParamFn params);
+ 
+ /**********************************************************************/
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c nspr-4.8.6.N/mozilla/nsprpub/pr/src/misc/prtime.c
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c	2015-04-29 16:33:57.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/misc/prtime.c	2015-04-29 16:33:10.000000000 -0700
+@@ -272,7 +272,7 @@
+ 
+     /* Normalize first.  Do this on our copy */
+     copy = *exploded;
+-    PR_NormalizeTime(&copy, PR_GMTParameters);
++    PR_NormalizeTime_NoDSTAdjust(&copy, PR_GMTParameters);
+ 
+     numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year);
+     
+@@ -387,9 +387,29 @@
+     }
+ }
+ 
+-PR_IMPLEMENT(void)
++NSPR_API(PRTime)
+ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params)
+ {
++    PRTime resolvedtime;
++    PR_NormalizeTime_NoDSTAdjust(time, PR_LocalTimeParameters);
++
++    // Resolve DST shifts explicitly. Note that this will also update *time
++    // with the corrected time.
++    resolvedtime = PR_ImplodeTime(time);
++    PR_ExplodeTime(resolvedtime, params, time);
++
++    // Return the DST-resolved PRTime.
++    return resolvedtime;
++}
++
++// This function normalizes time, but does not always resolve Daylight Savings
++// Time correctly (see SAPPHIRE-10133 for an example). It is the original
++// built-in PR_NormalizeTime function in NSPR, but should not be used outside
++// of the functions in this file - users should continue to utilize the newer
++// PR_NormalizeTime function below (see SAPPHIRE-10152).
++PR_IMPLEMENT(void)
++PR_NormalizeTime_NoDSTAdjust(PRExplodedTime *time, PRTimeParamFn params)
++{
+     int daysInMonth;
+     PRInt32 numDays;
+ 
+@@ -1723,7 +1743,7 @@
+    * Mainly to compute wday and yday, but normalized time is also required
+    * by the check below that works around a Visual C++ 2005 mktime problem.
+    */
+-  PR_NormalizeTime(result, PR_GMTParameters);
++  PR_NormalizeTime_NoDSTAdjust(result, PR_GMTParameters);
+   /* The remaining work is to set the gmt and dst offsets in tm_params. */
+ 
+   if (zone == TT_UNKNOWN && default_to_gmt)
diff --git a/nspr.patches/nspr-53.description b/nspr.patches/nspr-53.description
new file mode 100644
index 0000000..c0073f2
--- /dev/null
+++ b/nspr.patches/nspr-53.description
@@ -0,0 +1 @@
+String formatter for z and t length option.  Represents size of size_t and size of ptrdiff_t respectively
diff --git a/nspr.patches/nspr-53.patch b/nspr.patches/nspr-53.patch
new file mode 100644
index 0000000..2eeee82
--- /dev/null
+++ b/nspr.patches/nspr-53.patch
@@ -0,0 +1,44 @@
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/include/prprf.h nspr-4.8.6.N/mozilla/nsprpub/pr/include/prprf.h
+--- nspr-4.8.6/mozilla/nsprpub/pr/include/prprf.h	2004-04-25 08:00:47.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/include/prprf.h	2015-05-08 11:15:40.200961412 -0700
+@@ -48,6 +48,8 @@
+ **	%hd, %hu, %hx, %hX, %ho - 16-bit versions of above
+ **	%ld, %lu, %lx, %lX, %lo - 32-bit versions of above
+ **	%lld, %llu, %llx, %llX, %llo - 64 bit versions of above
++**	%td, %tu, %tx, %tX, %to - PRPtrdiff versions of the above (deals with machine dependent PRPtrdiff size)
++**	%zd, %zu, %zx, %zX, %zo - PRSize versions of above (deals with machine dependent PRSize size)
+ **	%s - string
+ **	%c - character
+ **	%p - pointer (deals with machine dependent pointer size)
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/src/io/prprf.c nspr-4.8.6.N/mozilla/nsprpub/pr/src/io/prprf.c
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/io/prprf.c	2008-05-31 08:10:17.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/io/prprf.c	2015-05-08 11:12:46.305410769 -0700
+@@ -820,6 +820,28 @@
+ 		type = TYPE_INT64;
+ 		c = *fmt++;
+ 	    }
++	} else if (c == 't') {
++		if (sizeof(PRPtrdiff) == sizeof(PRInt32)) {
++		    type = TYPE_UINT32;
++		} else if (sizeof(PRPtrdiff) == sizeof(PRInt64)) {
++		    type = TYPE_UINT64;
++		} else if (sizeof(PRPtrdiff) == sizeof(PRIntn)) {
++		    type = TYPE_UINTN;
++		} else {
++		    PR_ASSERT(0);
++		}
++		c = *fmt++;
++	} else if (c == 'z') {
++		if (sizeof(PRSize) == sizeof(PRInt32)) {
++		    type = TYPE_UINT32;
++		} else if (sizeof(PRSize) == sizeof(PRInt64)) {
++		    type = TYPE_UINT64;
++		} else if (sizeof(PRSize) == sizeof(PRIntn)) {
++		    type = TYPE_UINTN;
++		} else {
++		    PR_ASSERT(0);
++		}
++		c = *fmt++;
+ 	}
+ 
+ 	/* format */
diff --git a/nspr.tar.gz b/nspr.tar.gz
new file mode 100644
index 0000000..dbd90bb
--- /dev/null
+++ b/nspr.tar.gz
Binary files differ
diff --git a/nspr.url b/nspr.url
new file mode 100644
index 0000000..d485106
--- /dev/null
+++ b/nspr.url
@@ -0,0 +1 @@
+ftp://ftp.mozilla.org/pub/nspr/releases/v4.8.6/src/nspr-4.8.6.tar.gz
diff --git a/nspr.version b/nspr.version
new file mode 100644
index 0000000..7ea5948
--- /dev/null
+++ b/nspr.version
@@ -0,0 +1 @@
+4.8.6